ฉันพบว่าไม่ใช่เรื่องผิดปกติอย่างสิ้นเชิงในสถานการณ์ที่คุณอาจต้องตั้งค่า isScrollEnabled เป็น true เพื่ออนุญาตการโต้ตอบ UI ที่เหมาะสม กรณีที่ง่ายสำหรับกรณีนี้คือเมื่อคุณต้องการอนุญาตให้มีการขยายมุมมองข้อความอัตโนมัติ แต่ยังคงจำกัดความสูงของสิ่งที่สมเหตุสมผลใน UITableView
นี่คือ subclass ของ UITextView ที่ฉันสร้างขึ้นมาซึ่งอนุญาตให้ขยายอัตโนมัติด้วยเลย์เอาต์อัตโนมัติ แต่คุณยังสามารถจำกัดความสูงได้สูงสุดและจะจัดการว่ามุมมองนั้นเลื่อนได้หรือไม่ขึ้นอยู่กับความสูง ตามค่าเริ่มต้นมุมมองจะขยายอย่างไม่มีกำหนดหากคุณมีข้อ จำกัด ในการตั้งค่าแบบนั้น
import UIKit
class FlexibleTextView: UITextView {
// limit the height of expansion per intrinsicContentSize
var maxHeight: CGFloat = 0.0
private let placeholderTextView: UITextView = {
let tv = UITextView()
tv.translatesAutoresizingMaskIntoConstraints = false
tv.backgroundColor = .clear
tv.isScrollEnabled = false
tv.textColor = .disabledTextColor
tv.isUserInteractionEnabled = false
return tv
}()
var placeholder: String? {
get {
return placeholderTextView.text
}
set {
placeholderTextView.text = newValue
}
}
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
isScrollEnabled = false
autoresizingMask = [.flexibleWidth, .flexibleHeight]
NotificationCenter.default.addObserver(self, selector: #selector(UITextInputDelegate.textDidChange(_:)), name: Notification.Name.UITextViewTextDidChange, object: self)
placeholderTextView.font = font
addSubview(placeholderTextView)
NSLayoutConstraint.activate([
placeholderTextView.leadingAnchor.constraint(equalTo: leadingAnchor),
placeholderTextView.trailingAnchor.constraint(equalTo: trailingAnchor),
placeholderTextView.topAnchor.constraint(equalTo: topAnchor),
placeholderTextView.bottomAnchor.constraint(equalTo: bottomAnchor),
])
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override var text: String! {
didSet {
invalidateIntrinsicContentSize()
placeholderTextView.isHidden = !text.isEmpty
}
}
override var font: UIFont? {
didSet {
placeholderTextView.font = font
invalidateIntrinsicContentSize()
}
}
override var contentInset: UIEdgeInsets {
didSet {
placeholderTextView.contentInset = contentInset
}
}
override var intrinsicContentSize: CGSize {
var size = super.intrinsicContentSize
if size.height == UIViewNoIntrinsicMetric {
// force layout
layoutManager.glyphRange(for: textContainer)
size.height = layoutManager.usedRect(for: textContainer).height + textContainerInset.top + textContainerInset.bottom
}
if maxHeight > 0.0 && size.height > maxHeight {
size.height = maxHeight
if !isScrollEnabled {
isScrollEnabled = true
}
} else if isScrollEnabled {
isScrollEnabled = false
}
return size
}
@objc private func textDidChange(_ note: Notification) {
// needed incase isScrollEnabled is set to true which stops automatically calling invalidateIntrinsicContentSize()
invalidateIntrinsicContentSize()
placeholderTextView.isHidden = !text.isEmpty
}
}
เป็นโบนัสมีการสนับสนุนสำหรับการรวมข้อความตัวแทนที่คล้ายกับ UILabel