如何在UITextView中添加占位符,类似于你可以为UITextField设置的占位符,在Swift中?


当前回答

无需添加任何第三方库。只需使用下面的代码…

class SubmitReviewVC : UIViewController, UITextViewDelegate {

@IBOutlet var txtMessage : UITextView!
var lblPlaceHolder : UILabel!

override func viewDidLoad() {
    super.viewDidLoad()

    txtMessage.delegate = self
    lblPlaceHolder = UILabel()
    lblPlaceHolder.text = "Enter message..."
    lblPlaceHolder.font = UIFont.systemFont(ofSize: txtMessage.font!.pointSize)
    lblPlaceHolder.sizeToFit()
    txtMessage.addSubview(lblPlaceHolder)
    lblPlaceHolder.frame.origin = CGPoint(x: 5, y: (txtMessage.font?.pointSize)! / 2)
    lblPlaceHolder.textColor = UIColor.lightGray
    lblPlaceHolder.isHidden = !txtMessage.text.isEmpty
}

func textViewDidChange(_ textView: UITextView) {
    lblPlaceHolder.isHidden = !textView.text.isEmpty
}

}

其他回答

我通过使用两个不同的文本视图来做到这一点:

一个在后台用作占位符。 一个在前台(具有透明背景),用户实际输入。

其思想是,一旦用户开始在前景视图中输入内容,后台的占位符就会消失(如果用户删除了所有内容,则会重新出现)。因此,它的行为完全类似于单行文本字段的占位符。

这是我用的代码。注意,descriptionField是用户键入的字段,descriptionPlaceholder是后台的字段。

func textViewDidChange(descriptionField: UITextView) {
    if descriptionField.text.isEmpty == false {
        descriptionPlaceholder.text = ""
    } else {
        descriptionPlaceholder.text = descriptionPlaceholderText
    }
}

文本视图委托方法

使用这两个委托方法,并在类中编写UITextViewDelegate

func textViewDidBeginEditing(_ textView: UITextView) {
    if (commentsTextView.text == "Type Your Comments")
    {
        commentsTextView.text = nil
        commentsTextView.textColor = UIColor.darkGray
    }
}

func textViewDidEndEditing(_ textView: UITextView) {
    if commentsTextView.text.isEmpty
    {
        commentsTextView.text = "Type Your Comments"
        commentsTextView.textColor = UIColor.darkGray
    }
    textView.resignFirstResponder()
}

我们可以很容易地实现textview占位符,如果我们正在使用pod IQKeyboardManagerSwift在我们的项目中,只需遵循4个步骤

我们必须将类IQTextView分配给我们的TextView类。 我们必须在Controller页面中导入IQKeyboardManagerSwift 最后但并非最不重要的是,在控制器页面的textView的出口//如果你想:) 通过storyboard inspectable给textView一些占位符文本

斯威夫特

这是一个Swiftui TextView使用UIVIewRepresentable,具有占位符功能和边界颜色

struct TextView: UIViewRepresentable {

@Binding var text: String
var placeholderText: String
var textStyle: UIFont.TextStyle

func makeUIView(context: Context) -> UITextView {
    let textView = UITextView()

    textView.font = UIFont.preferredFont(forTextStyle: textStyle)
    textView.autocapitalizationType = .sentences
    textView.isSelectable = true
    textView.isUserInteractionEnabled = true
    textView.delegate = context.coordinator
    textView.layer.borderWidth = 0.6
    textView.layer.borderColor = UIColor.lightGray.cgColor
    textView.layer.cornerRadius = 10
    textView.text = placeholderText
    textView.textColor = UIColor.lightGray
    return textView
}

func updateUIView(_ uiView: UITextView, context: Context) {
    uiView.text = text
    uiView.font = UIFont.preferredFont(forTextStyle: textStyle)
}

func makeCoordinator() -> Coordinator {
    Coordinator(self)
}
 
class Coordinator: NSObject, UITextViewDelegate {
    var parent: TextView
 
    init(_ parent: TextView) {
        self.parent = parent
    }
 
    func textViewDidChange(_ textView: UITextView) {
        self.parent.text = textView.text
    }
    
    func textViewDidBeginEditing(_ textView: UITextView) {
        if textView.textColor == UIColor.lightGray {
            textView.text = nil
            textView.textColor = UIColor.black
        }
    }
    
    func textViewDidEndEditing(_ textView: UITextView) {
        if textView.text.isEmpty {
            textView.text = self.parent.placeholderText
            textView.textColor = UIColor.lightGray
        }
    }
}

}

然后在你的视图中你可以这样使用它

TextView(text: self.$viewModel.addPostCommentText, placeholderText: "Share your story about this cash", textStyle: .body)
                .padding()
                .frame(height: 150)

迅速的回答

这是一个自定义类,用于动画占位符。

class CustomTextView: UITextView {
    
    //   MARK: - public
    
    public var placeHolderText: String? = "Enter Reason.."
    
    public lazy var placeHolderLabel: UILabel! = {
        let placeHolderLabel = UILabel(frame: .zero)
        placeHolderLabel.numberOfLines = 0
        placeHolderLabel.backgroundColor = .clear
        placeHolderLabel.alpha = 0.5
        return placeHolderLabel
    }()
    
    //   MARK: - Init
    
    override init(frame: CGRect, textContainer: NSTextContainer?) {
        super.init(frame: frame, textContainer: textContainer)
        enableNotifications()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        enableNotifications()
    }
    
    func setup() {
        placeHolderLabel.frame = CGRect(x: 8, y: 8, width: self.bounds.size.width - 16, height: 15)
        placeHolderLabel.sizeToFit()
    }
    
    //   MARK: - Cycle
    
    override func awakeFromNib() {
        super.awakeFromNib()
        
        textContainerInset = UIEdgeInsets(top: 8, left: 5, bottom: 8, right: 8)
        returnKeyType = .done
        addSubview(placeHolderLabel)
        placeHolderLabel.frame = CGRect(x: 8, y: 8, width: self.bounds.size.width - 16, height: 15)
        placeHolderLabel.textColor = textColor
        placeHolderLabel.font = font
        placeHolderLabel.text = placeHolderText
        bringSubviewToFront(placeHolderLabel)
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        setup()
    }
    
    //   MARK: - Notifications
    
    private func enableNotifications() {
        NotificationCenter.default.addObserver(self, selector: #selector(textDidChangeNotification(_:)), name: UITextView.textDidChangeNotification , object: nil)
    }
    
    @objc func textDidChangeNotification(_ notify: Notification) {
        guard self == notify.object as? UITextView else { return }
        guard placeHolderText != nil else { return }
        
        UIView.animate(withDuration: 0.25, animations: {
            self.placeHolderLabel.alpha = (self.text.count == 0) ? 0.5 : 0
        }, completion: nil)
    }
    
}