SwiftUI导航标题在小屏过长如何自动换行或自适应且保留原生交互
可行实现方案
方案1:超出长度自动缩小字体(推荐,符合系统原生设计风格)
该方案不会破坏SwiftUI原生导航栏的上滑折叠交互,仅调整大标题的自适应缩放属性,文本未超出时保留默认大标题字号,超出时自动缩小到预设的最小比例,无需自定义toolbar。
实现代码:
init() { let navBarAppearance = UINavigationBarAppearance() navBarAppearance.largeTitleTextAttributes = [ .adjustsFontSizeToFitWidth: true, .minimumScaleFactor: 0.7 // 可根据业务需求调整最小缩放比例,此处为最多缩小到原字体的70% ] // 全局应用到所有状态的导航栏 UINavigationBar.appearance().standardAppearance = navBarAppearance UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance UINavigationBar.appearance().compactAppearance = navBarAppearance }
折叠后的小标题会保留系统默认的截断逻辑,不受该配置影响。
方案2:超出长度自动换行
之前设置lineBreakMode不生效是因为导航栏大标题对应的UILabel默认numberOfLines为1,需修改该属性才能实现换行效果,该方案同样保留原生导航栏的所有交互逻辑。
第一步全局配置段落样式:
init() { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineBreakMode = .byWordWrapping paragraphStyle.lineSpacing = 4 // 可自行调整行间距 let navBarAppearance = UINavigationBarAppearance() navBarAppearance.largeTitleTextAttributes = [ .paragraphStyle: paragraphStyle ] UINavigationBar.appearance().standardAppearance = navBarAppearance UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance }
第二步在需要显示长标题的SwiftUI页面添加修饰符,修改大标题Label的行数限制:
.onAppear { // 遍历匹配导航栏大标题对应的UILabel for subview in UINavigationBar.appearance().subviews { guard let titleLabel = subview.subviews.first(where: { $0 is UILabel && ($0 as! UILabel).font == .preferredFont(forTextStyle: .largeTitle) }) as? UILabel else { continue } titleLabel.numberOfLines = 0 } }
换行后的大标题高度会自动适配,上滑折叠后小标题会自动恢复为默认的单行截断逻辑,不会产生兼容问题。
内容的提问来源于stack exchange,提问作者Darren
相关产品推荐
相关产品推荐

