我想要的是一个非常直观的事情,但令人惊讶的是,它未包含在xcode中:我想要的是具有
的文本视图或文本字段 1-占位符
2-几行(如UITEXTVIEW中的滚动视图(。
3-文本或占位符应始终垂直和水平为中心。
我研究了类似的问题:
中心文本在UITEXTVIEW中垂直
将文本置于垂直和水平的UITEXTVIEW中
在uitextview
对于占位符,我正在使用以下库:
https://github.com/devxoul/uitextview-placeholder哪个解决了第一个要求,但即使上面的链接中给出的答案,我也无法满足其他2个要求
我正在使用Swift 3.1,部署目标ios9,Xcode 8.3.2
不幸的是,UITextView
和UITextField
都如此有限。许多开发人员已经多次完成了这些事情。
我通常要做的就是创建一个新的UIView
子类,然后具有2个子视图。占位符和集中文本视图的标签。
您可以在XIB中进行操作并使用接口构建器,我建议您这样做。然后,您可以公开文本视图和占位符,实际上可以设置几乎所有您需要的东西。
,但是要在代码中进行,它看起来像以下内容:
@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()
}
}
仍然有一些弊端:
- 视图本身需要文本视图的代表。因此,如果您在某些视图控制器中调用
myView.textView.delegate = self
,则会打破内部的逻辑。如果您需要它,我建议您在此视图上创建一个自定义委托,并公开所需的方法,而不是标准UITextViewDelegate
。 - 尽管课程是可设计的,但您无法拥有许多可检查的字段。因此,很难在接口构建器内部设置任何属性。您可以揭露诸如"文本"之类的属性,并将setter和getter指向文本视图。对于文本颜色也可以做同样的事情...但是最大的问题是您无法将字体标记为可检查的字体(我猜是哭泣(。
- 在某些情况下,文本进入Newline时会跳一些。我想您需要玩一些才能完善它。可能的约束可能会解决此问题,因此,如果您在XIB中进行操作可以解决它。
是一件好事,尽管您可以从代码中做任何事情。多行或属性的字符串占位符,对准,颜色,字体...
实际上我感到有些愚蠢,因为答案一直是我的眼前...
对于占位符,我将只使用图书馆:https://github.com/devxoul/uitextview-placeholder在我的问题中提到
然后在uiviewController类中我做了以下操作:
class myClass: UIViewController {
@IBOutlet weak var myTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Set the textView to the Delegate
myTextView.delegate = self
// Initialize the textView text Position and accordingly the
// placeholder position
myTextView.contentInset.top = max(0, (tv_comment.bounds.size.height - tv_comment.contentSize.height * tv_comment.zoomScale) / 2)
}
extension myClass: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
// do the same adjustment again every time the textView changes
textView.contentInset.top = max(0, (textView.bounds.size.height - textView.contentSize.height * textView.zoomScale) / 2)
}
}