我想要的是一个非常直观的东西,但令人惊讶的是它没有包含在 Xcode 中: 我想要的是一个 textView 或一个 textField 将有
1- 占位符
2- 几行(像 UITextView 中的 ScrollView )。
3- 文本或占位符应始终在 textBoxArea 中垂直和水平居中。
我看过类似的问题,例如:
Center text vertically in a UITextView
Center the text in a UITextView, vertically and horizontally
Aligning text vertically center in UITextView
对于 placeHolder,我使用以下库:
https://github.com/devxoul/UITextView-Placeholder
这解决了第一个要求,但即使上面的链接中给出了答案,我也无法满足其他 2 个要求
我正在使用 swift 3.1,部署目标 iOS9,Xcode 8.3.2
最佳答案
不幸的是 UITextView
和 UITextField
都非常有限。如此多的开发人员已多次完成同样的事情。
我通常做的只是创建一个新的 UIView
子类,然后有 2 个 subview ;内容的占位符和居中 TextView 的标签。
您可以在 xib 中执行此操作并使用界面构建器,我建议您这样做。然后您可以公开 TextView 和占位符,您实际上可以设置几乎任何您需要的东西。
但要在代码中执行它,它看起来像下面这样:
@IBDesignable class CustomTextView: UIView {
private(set) var textView: UITextView = UITextView(frame: CGRect.zero)
private(set) var placeholderLabel: UILabel = UILabel(frame: CGRect.zero)
@IBInspectable var placeholder: String? {
didSet {
placeholderLabel.text = placeholder
}
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
private func setup() {
textView.delegate = self
addSubview(textView)
textView.backgroundColor = UIColor.clear
textView.textAlignment = .center
addSubview(placeholderLabel)
placeholderLabel.textAlignment = .center
placeholderLabel.numberOfLines = 0
addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(onTap)))
}
override func layoutSubviews() {
super.layoutSubviews()
refreshViews()
}
fileprivate func refreshViews() {
UIView.performWithoutAnimation {
textView.frame = self.bounds
let optimalSize = textView.sizeThatFits(bounds.size)
textView.frame = CGRect(x: 0.0, y: max((bounds.size.height-optimalSize.height)*0.5, 0.0), width: bounds.width, height: min(optimalSize.height, bounds.size.height))
placeholderLabel.frame = bounds
placeholderLabel.backgroundColor = UIColor.clear
if textView.text.isEmpty && textView.isFirstResponder == false {
placeholderLabel.text = placeholder
placeholderLabel.isHidden = false
textView.isHidden = true
} else {
placeholderLabel.isHidden = true
textView.isHidden = false
}
}
}
@objc private func onTap() {
if !textView.isFirstResponder {
textView.becomeFirstResponder()
}
}
}
extension CustomTextView: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
refreshViews()
}
func textViewDidBeginEditing(_ textView: UITextView) {
refreshViews()
}
func textViewDidEndEditing(_ textView: UITextView) {
refreshViews()
}
}
不过还是有一些缺点:
- View 本身需要 TextView 的委托(delegate)。因此,如果您在某些 View Controller 中调用
myView.textView.delegate = self
,您将破坏内部逻辑。如果您需要它,我建议您在此 View 上创建一个自定义委托(delegate)并公开您需要的方法,而不是标准的UITextViewDelegate
。 - 尽管类是可设计的,但您不能有太多可检查的字段。所以在界面生成器中设置任何属性有点困难。您可以公开诸如“文本”之类的属性,并将 setter 和 getter 指向 TextView 。可以对文本颜色做同样的事情......但最大的问题是你不能将字体标记为可检查的(我想苹果哭了)。
- 在某些情况下,文本在进入换行符时会跳动一点。我想您需要稍微尝试一下才能完善它。约束可能会解决这个问题,所以如果你在 xib 中制作它,这就可以解决它。
虽然您可以从代码中执行几乎所有操作,但这是一件好事。多行或属性字符串占位符、对齐方式、颜色、字体...
关于ios - 如何创建具有 placeHolder、多行和垂直居中的 UITextView 或 UITextField?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44260747/