Swift中为UILabel添加展开/收起功能遇异常求助
解决UILabel展开/收起功能的崩溃问题
问题原因
你遇到的NSInvalidArgumentException崩溃,核心问题出在IBOutlet关联错误!你把声明为NSLayoutConstraint类型的lblHeight,错误关联到了UILabel实例上。setConstant:是布局约束独有的方法,UILabel根本没有这个方法,所以系统会抛出“无法识别的选择器”错误。
修复步骤
- 打开你的Storyboard/XIB文件,找到
ExpandedLabelViewController对应的界面 - 定位到
myLabel的高度约束(就是你用来控制展开/收起的那个约束) - 断开错误关联:
- 右键点击代码里的
@IBOutlet weak var lblHeight: NSLayoutConstraint!,在弹出菜单中删除现有连线 - 或者在Storyboard右侧的「Connections Inspector」面板里,找到
lblHeight的错误连线并删除
- 右键点击代码里的
- 重新正确关联:按住Ctrl键,把Storyboard里的高度约束拖到代码的
lblHeight变量上,确保这次关联的是NSLayoutConstraint而非UILabel
代码优化建议
修复关联后,还可以优化代码让功能更流畅:
- 高效计算标签高度:用
boundingRect替代创建临时UILabel的方式,更高效准确:
func getLabelHeight(text: String, width: CGFloat, font: UIFont) -> CGFloat { let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude) let attributes: [NSAttributedString.Key: Any] = [.font: font] let boundingBox = text.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: attributes, context: nil) return ceil(boundingBox.height) }
- 添加展开/收起动画:在按钮点击后加入动画,让状态切换更顺滑:
@IBAction func btnAction(_ sender: Any) { isLabelAtMaxHeight.toggle() btn.setTitle(isLabelAtMaxHeight ? "Read less" : "Read more", for: .normal) // 计算标签实际可用宽度(减去左右内边距) let availableWidth = view.bounds.width - myLabel.layoutMargins.left - myLabel.layoutMargins.right lblHeight.constant = isLabelAtMaxHeight ? getLabelHeight(text: myLabel.text ?? "", width: availableWidth, font: myLabel.font) : 70 // 执行动画更新布局 UIView.animate(withDuration: 0.3) { self.view.layoutIfNeeded() } }
- 初始化收起状态:在
viewDidLoad里设置初始状态,确保打开页面时就是收起效果:
override func viewDidLoad() { super.viewDidLoad() myLabel.text = "bla bla blabla bla blabla bla blabla bla blabla bla blabla bla bla" // 初始设置为收起状态 lblHeight.constant = 70 btn.setTitle("Read more", for: .normal) }
内容的提问来源于stack exchange,提问作者Ahtazaz
相关产品推荐
相关产品推荐

