iOS11 Alert Dialog字符截断问题:求原因分析及修复方法
iOS 11中UIAlertController(ActionSheet样式)字符截断问题的原因与修复方案
我之前做本地化适配时刚好踩过iOS 11里ActionSheet的文本截断坑,结合你的代码和常见场景,给你拆解下问题根源和可行的解决办法:
问题原因
iOS 11的UIAlertController在ActionSheet样式下存在布局计算bug:
- 对于非英文(尤其是像波兰语这类带特殊字符、单词较长的本地化文本),系统没有正确计算文本的实际显示宽度,当文本长度超过它预设的窄宽度阈值时,就会直接截断,而非自动换行调整。
- 如果是在iPad上呈现ActionSheet(默认是popover形式),若popover尺寸适配逻辑没处理好,也可能挤压文本区域导致截断,但从你的波兰语文本来看,更大概率是系统本身的布局计算缺陷。
修复方案
1. 手动插入换行符(快速临时解决)
如果文本长度不算特别长,可以手动在合适位置插入\n换行符,强制文本换行避免截断:
let restorePurchases = UIAlertAction(title: "Przywróć\nzakupy", style: .default) { (action) in self.restorePurchases() }
这个方法简单直接,但缺点是需要根据不同语言手动调整换行位置,适配性较差。
2. 使用富文本标题(推荐方案)
通过KVC给UIAlertAction设置富文本标题,指定段落样式让文本自动按单词换行:
// 创建富文本段落样式,设置按单词换行、居中对齐 let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .byWordWrapping paragraphStyle.alignment = .center // 生成富文本标题 let attributedTitle = NSAttributedString( string: "Przywróć zakupy", attributes: [.paragraphStyle: paragraphStyle] ) // 创建UIAlertAction,先设置空标题,再通过KVC赋值富文本 let restorePurchases = UIAlertAction(title: "", style: .default) { (action) in self.restorePurchases() } restorePurchases.setValue(attributedTitle, forKey: "attributedTitle")
这个方法能让文本根据ActionSheet的宽度自动换行,不用手动调整,适配所有语言。虽然用到了KVC访问私有属性,但实际开发中苹果很少因为这个拒审,属于比较安全的“黑魔法”。
3. 升级最低系统版本(彻底解决)
苹果在iOS 12及后续版本中已经修复了这个布局bug,如果你的应用可以接受放弃iOS 11的用户支持,直接把Deployment Target升到iOS 12是最省心的办法,不用写额外的兼容代码。
4. 自定义ActionSheet组件(终极方案)
如果上面的方法都不符合你的需求,可以自己封装一个自定义ActionSheet,完全控制布局:
- 用UIView做容器,内部用UITableView或者UICollectionView展示选项;
- 自定义cell里的UILabel设置
numberOfLines = 0、lineBreakMode = .byWordWrapping,确保文本自动换行; - 添加动画效果模拟系统ActionSheet的弹出/收起逻辑。
这个方案完全不受系统bug限制,还能自定义样式,适合对UI要求较高的场景。
内容的提问来源于stack exchange,提问作者Bartłomiej Janczak
相关产品推荐
相关产品推荐

