
[英]UITextView setTextColor changes layout in UITableViewCell
[英]Layout problems after replacing UILabel with UITextView in a UITableViewCell
作为我正在构建的应用程序的一部分,我拥有基本的聊天功能。 它基本上是一个 UITable 视图,其中 UITableViewCell 仅包含一个 UILabel(聊天消息文本)和一个 UIView(用作围绕文本的语音气泡。这是代码:
class ChatMessageViewCellController: UITableViewCell {
var ChatMessageText = UILabel()
var ChatBubble = UIView()
var leadingConstraint: NSLayoutConstraint!
var trailingConstraint: NSLayoutConstraint!
var isIncoming: Bool! {
didSet {
if self.isIncoming {
self.ChatBubble.backgroundColor = UIColor(named: "customGrey")
self.leadingConstraint.isActive = true
self.trailingConstraint.isActive = false
} else {
self.ChatBubble.backgroundColor = UIColor(named: "customGreen")
self.leadingConstraint.isActive = false
self.trailingConstraint.isActive = true
}
}
}
override func awakeFromNib() {
super.awakeFromNib()
addSubview(ChatBubble)
addSubview(ChatMessageText)
self.ChatBubble.translatesAutoresizingMaskIntoConstraints = false
self.ChatMessageText.translatesAutoresizingMaskIntoConstraints = false
self.ChatBubble.backgroundColor = UIColor(named: "customGreen")
self.ChatBubble.layer.cornerRadius = 10
self.ChatMessageText.numberOfLines = 0
self.ChatMessageText.textColor = .white
self.ChatMessageText.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.light)
let constraints = [
self.ChatMessageText.topAnchor.constraint(equalTo: topAnchor, constant: 16),
self.ChatMessageText.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -32),
self.ChatMessageText.widthAnchor.constraint(lessThanOrEqualToConstant: 220),
self.ChatBubble.topAnchor.constraint(equalTo: ChatMessageText.topAnchor, constant: -16),
self.ChatBubble.trailingAnchor.constraint(equalTo: ChatMessageText.trailingAnchor, constant: 16),
self.ChatBubble.bottomAnchor.constraint(equalTo: ChatMessageText.bottomAnchor, constant: 16),
self.ChatBubble.leadingAnchor.constraint(equalTo: ChatMessageText.leadingAnchor, constant: -16),
]
NSLayoutConstraint.activate(constraints)
self.leadingConstraint = self.ChatMessageText.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 32)
self.trailingConstraint = self.ChatMessageText.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -32)
}
我的问题是这样的:我不是用标准字符串来提供 UILabel,而是用 NSAttributedStrings,因为我想在那里获得一些可点击的链接和用户可选择的部分文本。 所以我被告知使用 UITextView 而不是 UILabel。 因此,我进行了以下 2 处更改:
var ChatMessageText = UILabel()
更改为var ChatMessageText = UITextView()
self.ChatMessageText.numberOfLines = 0
因为 UITextView 没有numberOfLines
成员Xcode 没有抱怨,应用程序编译并运行,但它完全弄乱了我的布局,我就是不知道为什么。 UILabel 的所有约束也应该适用于 UITextView - 至少我是这么认为的。 但这是屏幕的样子。
我究竟做错了什么? 我需要添加/更改约束吗?
默认情况下, UITextView
已启用滚动。
虽然这看起来很明显,但它允许用户输入比框架更多的文本行,并且用户可以上下滚动文本。
为了实现这一点, UIKit
必须知道文本视图的框架。 如果框架没有设置, UIKit
就无法知道要显示多少行,或者视图应该有多宽。 所以除非我们给文本视图提供了完整的约束集,否则自动布局会给它一个.zero
的大小。 即使给定宽度(或最大宽度)约束,自动布局仍然不知道我们想要显示多少可滚动的文本行。
在文本视图上设置.isScrollEnabled = false
改变所有这些。
现在,如果我们只限制文本视图的位置和宽度, UIKit
将根据.text
属性的内容大小计算高度。
这很容易证明。 我们将创建两个文本视图,给它们每个顶部、前导和最大宽度(lessThanOrEqualTo)约束,以及相同的文本......但在其中一个上设置.isScrollEnabled = false
:
class TextViewTestViewController: UIViewController {
let nonScrollingTextView = UITextView()
let scrollingTextView = UITextView()
override func viewDidLoad() {
super.viewDidLoad()
let s = "This is a test string to demonstrate UITextView size behavior."
[nonScrollingTextView, scrollingTextView].forEach {
tv in
tv.translatesAutoresizingMaskIntoConstraints = false
tv.font = UIFont.systemFont(ofSize: 17.0)
tv.text = s
view.addSubview(tv)
}
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
nonScrollingTextView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
nonScrollingTextView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
nonScrollingTextView.widthAnchor.constraint(lessThanOrEqualToConstant: 300.0),
scrollingTextView.topAnchor.constraint(equalTo: nonScrollingTextView.bottomAnchor, constant: 40.0),
scrollingTextView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
scrollingTextView.widthAnchor.constraint(lessThanOrEqualToConstant: 300.0),
])
// disable scrolling on the "top" text view
nonScrollingTextView.isScrollEnabled = false
// top text view is cyan
nonScrollingTextView.backgroundColor = .cyan
// bottom text view is green (although we won't see it)
scrollingTextView.backgroundColor = .green
}
}
结果:
我们添加了两个文本视图,但只禁用了“顶部”一个(青色背景)的滚动。 我们甚至看不到第二个(绿色背景),因为自动布局给它的高度为零。
值得注意的是...如果文本视图禁用了滚动并启用了编辑,它会随着用户添加/删除文本而自动增长/缩小。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.