【问题标题】:SwiftUI. How to change the placeholder color of the TextField?斯威夫特用户界面。如何更改 TextField 的占位符颜色?
【发布时间】:2020-01-01 10:27:22
【问题描述】:

我想更改 TextField 的占位符颜色,但找不到方法。

我尝试设置foregroundColoraccentColor,但它并没有改变占位符的颜色。

代码如下:

TextField("Placeholder", $text)
    .foregroundColor(Color.red)
    .accentColor(Color.green)

也许还没有这方面的 API?

【问题讨论】:

标签: swift swiftui


【解决方案1】:

(目前)还没有 api。 但你可以

使用自定义placeholder 修饰符将任何视图显示为任何其他视图的持有者!例如:

TextField("", text: $text)
    .placeholder(when: text.isEmpty) {
        Text("Placeholder recreated").foregroundColor(.gray)
}

? 这是一个简单的ZStack,您可以在View 扩展中使用:

extension View {
    func placeholder<Content: View>(
        when shouldShow: Bool,
        alignment: Alignment = .leading,
        @ViewBuilder placeholder: () -> Content) -> some View {

        ZStack(alignment: alignment) {
            placeholder().opacity(shouldShow ? 1 : 0)
            self
        }
    }
}

? 现在您可以将 任何 类型的样式应用于占位符,例如带有图像的渐变占位符:

✅如果你有兴趣,这里是how to apply resizable gradient on any view


? 简约的艺术

大多数情况下,您只需要传递一个字符串和一个灰色占位符,例如:

TextField("", text: $text)
    .placeholder("Placeholder", when: text.isEmpty)

您可以为上面的扩展编写一个简单的包装器:

extension View {
    func placeholder(
        _ text: String,
        when shouldShow: Bool,
        alignment: Alignment = .leading) -> some View {
            
        placeholder(when: shouldShow, alignment: alignment) { Text(text).foregroundColor(.gray) }
    }
}

就这样?

【讨论】:

  • 这似乎不适用于 iOS14。 TextField 为空白,即没有占位符
  • 谢谢你,你拯救了我的一天!没有你的诡计,默认颜色对我来说是不可读的
  • 好主意,我为自己简化了这个,所以它不会臃肿:func placeholder(when shouldShow: Bool, placeholder: String)
  • @Big_Chair 我为此添加了另一个扩展,一个简单的助手,它接受一个字符串并在里面设置文本。
【解决方案2】:

最终,在 ZStack 中嵌入内容的 ViewModifier 更优雅,代码更少:

public struct PlaceholderStyle: ViewModifier {
    var showPlaceHolder: Bool
    var placeholder: String

    public func body(content: Content) -> some View {
        ZStack(alignment: .leading) {
            if showPlaceHolder {
                Text(placeholder)
                .padding(.horizontal, 15)
            }
            content
            .foregroundColor(Color.white)
            .padding(5.0)            
        }
    }
}

用法:

TextField("", text: $data)
.modifier(PlaceholderStyle(showPlaceHolder: data.isEmpty,
                           placeholder: "My Placeholder"))

【讨论】:

  • 这应该是新接受的答案,直到 SwiftUI 有一种改变占位符颜色的本地方式
【解决方案3】:

这是对@jfk's answer的一点修改,我们可以为view创建一个扩展来简化主视图中的修改代码,也可以用于TextImage

struct PlaceHolder<T: View>: ViewModifier {
    var placeHolder: T
    var show: Bool
    func body(content: Content) -> some View {
        ZStack(alignment: .leading) {
            if show { placeHolder }
            content
        }
    }
}

extension View {
    func placeHolder<T:View>(_ holder: T, show: Bool) -> some View {
        self.modifier(PlaceHolder(placeHolder:holder, show: show))
    }
}

在 TextField 中的使用:

将这行代码.placeHolder(Text("Your placeholder"), show: text.isEmpty) 作为viewModifier 添加到TextField

TextField("", text: $text, onEditingChanged: { (changing) in
    print("Changing: \(changing)")
}, onCommit: {
    print("Committed!")
})
    .placeHolder(Text("Your placeholder"), show: text.isEmpty)

在图片中的使用:

此外,正如@EmilioPelaez 建议的那样,我修改了代码以支持任何视图的占位符。 Image 如下所示。

Image("your_image")
    .placeHolder(Image("placeholder_image"), show: true)

【讨论】:

  • 这是一个很好的答案,但我认为它可以进一步改进。允许任何类型的内容而不是要求Text 并将text: String 参数替换为show: Bool 会使其更加灵活,并且可以与不同类型的视图一起使用。
  • 啊.. @EmilioPelaez,让占位符可用于任何视图,无论是 Text 还是 Image,这真是个好主意,我'我更新了我的答案。我坚持这个问题,但你的建议简直是开箱即用。谢谢!!
【解决方案4】:

如果您想保留原始 TextField 并且不介意将 Introspect 添加到您的项目 (https://github.com/siteline/SwiftUI-Introspect),您可以通过访问 UIKit attributedPlaceholder 来实现:

TextField("Email", text: $email)
.introspectTextField { uiTextField in
    uiTextField.attributedPlaceholder = NSAttributedString(string: "placeholder text", 
    attributes: [NSAttributedString.Key.foregroundColor: UIColor.red])
}

【讨论】:

  • 根本不起作用。图书馆很差 - 如果你只有一个 View 和 TextField,它有 80% 的机会工作。一旦你添加了样式,或者在 VStack 中移动 TextField 并将样式添加到 VStack - 它会立即中断。
【解决方案5】:

您可以尝试根据TextField的内容更改颜色。也许是这样的:

@State var text : String
@State var textFieldColor : Color = .secondary

TextField("Placeholder", text: $text)
   .foregroundColor(textFieldColor)
   .onChange(of: text) { value in
      textFieldColor = value == "" ? .red : .green
   }

【讨论】:

    【解决方案6】:

    选项 1:TL;DR 简短回答:

    myUiTextField.attributedPlaceholder = NSAttributedString(string: placeHolderText, attributes: [NSAttributedString.Key.foregroundColor: placeHolderTextColor])
    

    上述答案的解释: 使用这里其他社区成员也建议的属性字符串。

    选项 2:长答案但简洁且可扩展: 我们在项目中创建了一个扩展类,使用以下方法为一些参数设置默认值,以保持代码干净、可扩展和可重用:

        import UIKit
    
        extension UITextField {
    
            /// Set the placeholder text properties of a UITextField
            /// - Parameters:
            ///   - placeHolder: text message for placeholder
            ///   - foregroundColor: text color (optional)
            ///   - fontSize: text font size (optional)
            func placeHolderSetup(placeHolder: String, foregroundColor: UIColor = UIColor.AppColors.zGreyColor, fontSize: CGFloat = 16)  {
                let str = NSAttributedString(string: placeHolder,
                                         attributes:[NSAttributedString.Key.foregroundColor:foregroundColor,NSAttributedString.Key.font: UIFont(name: AppFonts.zFontRegular, size: fontSize)!])
                
                 self.attributedPlaceholder = str;
             }
         }
    

    上述方法的示例用法:

    searchTextField?.placeHolderSetup(placeHolder: "Search", foregroundColor: UIColor.white, fontSize: 14)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-01
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 2023-02-06
      • 2023-03-14
      相关资源
      最近更新 更多