正如标题所说 - 添加占位符到
UITextView
很简单。
只需使用
.textDidChangeNotification
并添加 CATextLayer
甚至只是 UILabel
。
问题是:
绝对、准确、明确地找到相同的位置,以便占位符始终准确地位于正文所在的位置。
(因此,如果您的占位符文本是“添加您的评论”,您应该能够输入“添加您的评论”,并且它是完全相同的。)
当然,您可以简单地将文本字体/等设置为相同,但是如何绝对匹配定位,即使苹果不可避免地会在 UITextView 内部稍微移动一些东西,并且取决于它里面的内容,它自己的大小等。
如何做?
我知道的唯一方法:
import UIKit
class PlaceholderTextView: UIITextView {
var placeholderText: String = "" {
didSet { placeholderLabel.text = placeholderText }
}
override func common() {
super.common()
clipsToBounds = true
layer.cornerRadius = 5.0
NotificationCenter.default.addObserver(
self, selector: #selector(tickle),
name: UITextView.textDidChangeNotification,
object:nil)
}
@objc func tickle() {
placeholderLabel.isHidden = !text.isEmpty
}
然后令人惊讶的是......
lazy private var placeholderLabel: UITextView = {
// seems strange, but the ONLY way to truly match the position
// at all times and in all ways, is use another text view
let p = UITextView()
p.isEditable = false
p.isUserInteractionEnabled = false
p.backgroundColor = .clear
p.font = font
p.textColor = (textColor ?? .black).withAlphaComponent(0.50)
addSubview(p)
return p
}()
然后,设置幽灵文本视图的位置就很简单了:
(不要忘记复制 textContainerInset;textContainerInset 在应用程序中几乎总是会更改。)
override func layoutSubviews() {
super.layoutSubviews()
placeholderLabel.textContainerInset = textContainerInset
placeholderLabel.frame = bounds
// conceivably, the font may have been changed dynamically:
placeholderLabel.font = font
placeholderLabel.textColor =
(textColor ?? .black).withAlphaComponent(0.50)
tickle()
}
}
@objc func tickle() {
placeholderLabel.isHidden = !text.isEmpty
}
更改为
@objc func tickle() {
placeholderLabel.isHidden = false //!text.isEmpty
}
然后执行此测试:
因此,如果您的占位符文本是“添加您的评论”,您应该能够输入“添加您的评论”,并且它是完全相同的。
精确匹配示例:
示例类中的
common()
初始化器是什么?在项目中,我只是为各种 iOS 视图添加简单的初始化视图以节省打字。 (注意初始化时额外的“I”。)
所以:
import UIKit
class UIITextView: UITextView {
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
common()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
common()
}
func common() {}
}
例如,