如何在SwiftUI中实现Label文本的首行缩进?
SwiftUI 实现文本首行缩进
方法一:SwiftUI 原生实现(iOS 15+)
利用Text的paragraphStyle修饰符直接设置首行缩进,代码如下:
ZStack { Image.book .resizable() .aspectRatio(contentMode: .fit) .frame(width: 12, height: 10) Text(verbatim: entry.verse) .font(.openSansRegular(withSize: 11)) .multilineTextAlignment(.leading) .paragraphStyle { let style = NSMutableParagraphStyle() // 调整首行缩进值,这里设为16pt,按需修改 style.firstLineHeadIndent = 16 return style } }
兼容 iOS 14 及以下版本
如果需要适配更低系统版本,使用AttributedString构建富文本:
ZStack { Image.book .resizable() .aspectRatio(contentMode: .fit) .frame(width: 12, height: 10) if let attrText = try? AttributedString(markdown: entry.verse) { var mutableAttr = attrText let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.firstLineHeadIndent = 16 mutableAttr.paragraphStyle = paragraphStyle Text(mutableAttr) .font(.openSansRegular(withSize: 11)) } else { Text(verbatim: entry.verse) .font(.openSansRegular(withSize: 11)) } }
方法二:封装 UILabel 复用原有逻辑
如果需要和你之前了解的UILabel首行缩进逻辑完全对齐,通过UIViewRepresentable封装UILabel:
// 自定义带首行缩进的Label struct IndentedTextLabel: UIViewRepresentable { let text: String let font: UIFont let firstLineIndent: CGFloat func makeUIView(context: Context) -> UILabel { let label = UILabel() label.font = font label.numberOfLines = 0 label.lineBreakMode = .byWordWrapping return label } func updateUIView(_ uiView: UILabel, context: Context) { let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.firstLineHeadIndent = firstLineIndent let attrString = NSAttributedString( string: text, attributes: [ .paragraphStyle: paragraphStyle, .font: font ] ) uiView.attributedText = attrString } } // 在你的ZStack中使用 ZStack { Image.book .resizable() .aspectRatio(contentMode: .fit) .frame(width: 12, height: 10) IndentedTextLabel( text: entry.verse, font: UIFont(name: "OpenSans-Regular", size: 11)!, firstLineIndent: 16 ) }
内容的提问来源于stack exchange,提问作者kunass2
相关产品推荐
相关产品推荐

