使用 UIButton 扩展 UITextView 而不是根据内容自动扩展
Expanding UITextView with UIButton instead of automatically based on content
我有一个 UITextView,它嵌入在 UIView 中,还有许多其他 UIView,这些 UIView 都在 UIScrollView(本质上是一种表单)中。我没有让 textView 随内容自动扩展,而是在其下方有一个按钮,我希望用户能够单击该按钮并 expand/colapse textView。
这是我的资料:
var textViewIsExpanded: Bool = false {
didSet {
if self.textViewIsExpanded {
self.expandTextViewButton.isSelected = true
guard self.myTextView.contentSize.height > 70 else { return }
self.myTextView.isScrollEnabled = false
self.myTextView.translatesAutoresizingMaskIntoConstraints = true
self.myTextView.sizeThatFits(CGSize(width: self.scrollView.width - 24, height: CGFloat.greatestFiniteMagnitude))
} else {
self.expandTextViewButton.isSelected = false
self.myTextView.isScrollEnabled = true
self.myTextView.translatesAutoresizingMaskIntoConstraints = false
}
}
}
@IBAction func expandTextViewButtonTapped(_ sender: UIButton) {
textViewIsExpanded.toggle()
}
我尝试用 .sizeToFit()
代替 .sizeThatFits(...)
哪种方法有效,但它调整了宽度和高度,我只关注 expand/colapse 高度。我猜这是正确实施 CGSize and/or IB 约束的问题,但我无法找到符合我要求的解决方案。
首先,在 true 和 false 之间切换 .translatesAutoresizingMaskIntoConstraints
是个坏主意。
您可能想要的是为您的文本视图提供 70 的高度约束...将其连接到 @IBOutlet
...然后在该约束上切换 .isActive
。
其次,如果你只有一行文字,那么内容大小高度可能是30,然后你调用
textViewIsExpanded = true
您的代码按原样将 textViewIsExpanded
设置为 true,但会保留 .isScrollEnabled
true --- 因此它不会真正被“扩展”。
第三,您需要通过调用让自动布局知道您正在更改文本视图的大小调整行为:
self.myTextView.invalidateIntrinsicContentSize()
切换后 .isScrollEnabled
。
因此,为文本视图的高度限制添加并连接 属性:
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!
并尝试将您的代码更改为:
var textViewIsExpanded: Bool = false {
didSet {
if self.textViewIsExpanded {
// if contentSize.height is less-than 71
// reset to false
if self.myTextView.contentSize.height < 71 {
self.textViewIsExpanded = false
return
} else {
self.expandTextViewButton.isSelected = true
self.myTextView.isScrollEnabled = false
self.textViewHeightConstraint.isActive = false
}
} else {
self.expandTextViewButton.isSelected = false
self.myTextView.isScrollEnabled = true
self.textViewHeightConstraint.isActive = true
}
self.myTextView.invalidateIntrinsicContentSize()
}
}
我有一个 UITextView,它嵌入在 UIView 中,还有许多其他 UIView,这些 UIView 都在 UIScrollView(本质上是一种表单)中。我没有让 textView 随内容自动扩展,而是在其下方有一个按钮,我希望用户能够单击该按钮并 expand/colapse textView。
这是我的资料:
var textViewIsExpanded: Bool = false {
didSet {
if self.textViewIsExpanded {
self.expandTextViewButton.isSelected = true
guard self.myTextView.contentSize.height > 70 else { return }
self.myTextView.isScrollEnabled = false
self.myTextView.translatesAutoresizingMaskIntoConstraints = true
self.myTextView.sizeThatFits(CGSize(width: self.scrollView.width - 24, height: CGFloat.greatestFiniteMagnitude))
} else {
self.expandTextViewButton.isSelected = false
self.myTextView.isScrollEnabled = true
self.myTextView.translatesAutoresizingMaskIntoConstraints = false
}
}
}
@IBAction func expandTextViewButtonTapped(_ sender: UIButton) {
textViewIsExpanded.toggle()
}
我尝试用 .sizeToFit()
代替 .sizeThatFits(...)
哪种方法有效,但它调整了宽度和高度,我只关注 expand/colapse 高度。我猜这是正确实施 CGSize and/or IB 约束的问题,但我无法找到符合我要求的解决方案。
首先,在 true 和 false 之间切换 .translatesAutoresizingMaskIntoConstraints
是个坏主意。
您可能想要的是为您的文本视图提供 70 的高度约束...将其连接到 @IBOutlet
...然后在该约束上切换 .isActive
。
其次,如果你只有一行文字,那么内容大小高度可能是30,然后你调用
textViewIsExpanded = true
您的代码按原样将 textViewIsExpanded
设置为 true,但会保留 .isScrollEnabled
true --- 因此它不会真正被“扩展”。
第三,您需要通过调用让自动布局知道您正在更改文本视图的大小调整行为:
self.myTextView.invalidateIntrinsicContentSize()
切换后 .isScrollEnabled
。
因此,为文本视图的高度限制添加并连接 属性:
@IBOutlet var textViewHeightConstraint: NSLayoutConstraint!
并尝试将您的代码更改为:
var textViewIsExpanded: Bool = false {
didSet {
if self.textViewIsExpanded {
// if contentSize.height is less-than 71
// reset to false
if self.myTextView.contentSize.height < 71 {
self.textViewIsExpanded = false
return
} else {
self.expandTextViewButton.isSelected = true
self.myTextView.isScrollEnabled = false
self.textViewHeightConstraint.isActive = false
}
} else {
self.expandTextViewButton.isSelected = false
self.myTextView.isScrollEnabled = true
self.textViewHeightConstraint.isActive = true
}
self.myTextView.invalidateIntrinsicContentSize()
}
}