升级Xcode13/iOS15后非固定尺寸UIButton文本总是截断如何解决
问题根因
iOS 15 对 UIButton 的布局逻辑做了较大重构,默认启用了UIButtonConfiguration布局体系,废弃了原有的titleEdgeInsets等旧属性的布局计算逻辑,导致按钮的intrinsicContentSize计算不准确,无法根据绑定的富文本正确撑开宽度,放在横向 StackView 中时就会被压缩截断。
解决方案
方案1:适配 iOS 15+ 新的 UIButton 配置体系(推荐)
废弃旧的titleEdgeInsets设置,改用UIButtonConfiguration设置内边距,保证 intrinsicContentSize 计算正确,代码示例:// 优先用custom类型按钮,避免系统默认配置干扰 let tagButton = UIButton(type: .custom) addSubview(tagButton) tagButton.layer.cornerRadius = 16 tagButton.layer.masksToBounds = true if #available(iOS 15.0, *) { var config = UIButton.Configuration.plain() // 替换原titleEdgeInsets设置内边距 config.contentInsets = NSDirectionalEdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16) // 配置换行策略,不需要截断可改为.byWordWrapping,同时设置titleLabel.numberOfLines = 0 config.titleLineBreakMode = .byTruncatingTail tagButton.configuration = config } else { // iOS15以下沿用旧设置 tagButton.titleEdgeInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) } // 提升横向抗压缩优先级,避免被StackView压缩 tagButton.setContentCompressionResistancePriority(.required, for: .horizontal) tagButton.snp.makeConstraints({ $0.edges.equalToSuperview() })方案2:关闭UIButtonConfiguration默认布局逻辑
如果不想适配新的配置体系,可以直接关闭iOS15新增的配置布局逻辑,沿用旧版的计算规则:if #available(iOS 15.0, *) { // 清空configuration,触发旧布局逻辑 tagButton.configuration = nil }方案3:文本绑定后强制触发布局更新
RxSwift绑定富文本后部分场景下按钮不会自动重新计算内容尺寸,可在绑定链中增加手动布局触发逻辑:bag.insert( viewModel.outputs.titleAttrText .do(onNext: { [weak tagButton] _ in tagButton?.setNeedsLayout() tagButton?.layoutIfNeeded() }) .drive(tagButton.rx.attributedTitle(for: .normal)) )StackView配置检查
确认承载按钮的横向StackView配置符合非固定尺寸按钮的布局要求:distribution不要设置为.fillEqually或.fillProportionally,应使用.fillalignment不要设置为.fill避免强制拉伸按钮高度,可使用.center/.top/.bottom
内容的提问来源于stack exchange,提问作者StefanN
相关产品推荐
相关产品推荐

