如何在 SwiftUI 中设置单行文本的行高?
How to set line height for a single line text in SwiftUI?
目前,我一直在使用.lineSpacing(...)
,但这只适用于多行文本。
/// Sets the amount of space between lines of text in this view.
///
/// - Parameter lineSpacing: The amount of space between the bottom of one
/// line and the top of the next line.
@inlinable public func lineSpacing(_ lineSpacing: CGFloat) -> some View
这意味着我很难准确翻译 sketch/figma 中的字体,我需要尝试调整填充以使其正确。这是一个显示此内容的示例:
VStack {
// Line spacing is ignored.
Text("Hello, World!")
.background(Color.green)
.lineSpacing(50)
Spacer()
// Line spacing is correct.
Text("Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups.")
.background(Color.green)
.lineSpacing(50)
}
您可以只使用 .frame 修饰符并设置高度。
Xcode 12
使用 .leading()
修饰符调整行距。
Text("Hello\nworld").font(Font.body.leading(.tight))
当前支持的值:.tight
、.standard
和 .loose
。
为了让您的文字与 figma 相匹配,这就是最终对我有用的方法。例如,如果您的 figma 设计具有 16 pt 的特定字体和 32 pt 的行高:
let font = UIFont(name: "SomeFont", size: 16)!
return Text("Some Text")
.font(.custom("SomeFont", size: 16))
.lineSpacing(32 - font.lineHeight)
.padding(.vertical, (32 - font.lineHeight) / 2)
为了获得准确的行距值,我们必须用字体固有的行高减去我们想要的行高,但正如您所指出的,这只会对多行文本和行间生效。我们仍然需要考虑文本的顶部和底部填充以匹配所需的行高,因此再次添加总行高减去字体的行高。
我已成功使用以下组合:
.frame(minHeight: lineHeight)
.lineSpacing(abs(designSystemFont.lineHeight - uiKitFont.lineHeight))
The abs
may not be needed (assuming the system's line height is taller than the default one, but you never know if that may change, so...)
这使我能够在尊重设计系统要求的同时处理 single-line 文本。
根据 Dan Hassan 的回答,我为自己制作了一个 ViewModifier 来执行此操作,看起来它按预期工作
import SwiftUI
struct FontWithLineHeight: ViewModifier {
let font: UIFont
let lineHeight: CGFloat
func body(content: Content) -> some View {
content
.font(Font(font))
.lineSpacing(lineHeight - font.lineHeight)
.padding(.vertical, (lineHeight - font.lineHeight) / 2)
}
}
extension View {
func fontWithLineHeight(font: UIFont, lineHeight: CGFloat) -> some View {
ModifiedContent(content: self, modifier: FontWithLineHeight(font: font, lineHeight: lineHeight))
}
}
实际上对我有用的是(基于 Ole-Kristian 的回答)
import SwiftUI
struct FontWithLineHeight: ViewModifier {
let font: UIFont
let lineHeight: CGFloat
func body(content: Content) -> some View {
content
.font(Font(font))
.lineSpacing((token.lineHeight - token.font.lineHeight)/2)
.padding(.vertical, (token.lineHeight - token.font.lineHeight))
}
}
extension View {
func fontWithLineHeight(font: UIFont, lineHeight: CGFloat) -> some View {
ModifiedContent(content: self, modifier: FontWithLineHeight(font: font, lineHeight: lineHeight))
}
}
...与填充值和 lineSpacing 值相反的其他答案非常相似。
这是我让底部 'padding' 与 Figma 相同的唯一方法。
目前,我一直在使用.lineSpacing(...)
,但这只适用于多行文本。
/// Sets the amount of space between lines of text in this view.
///
/// - Parameter lineSpacing: The amount of space between the bottom of one
/// line and the top of the next line.
@inlinable public func lineSpacing(_ lineSpacing: CGFloat) -> some View
这意味着我很难准确翻译 sketch/figma 中的字体,我需要尝试调整填充以使其正确。这是一个显示此内容的示例:
VStack {
// Line spacing is ignored.
Text("Hello, World!")
.background(Color.green)
.lineSpacing(50)
Spacer()
// Line spacing is correct.
Text("Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups.")
.background(Color.green)
.lineSpacing(50)
}
您可以只使用 .frame 修饰符并设置高度。
Xcode 12
使用 .leading()
修饰符调整行距。
Text("Hello\nworld").font(Font.body.leading(.tight))
当前支持的值:.tight
、.standard
和 .loose
。
为了让您的文字与 figma 相匹配,这就是最终对我有用的方法。例如,如果您的 figma 设计具有 16 pt 的特定字体和 32 pt 的行高:
let font = UIFont(name: "SomeFont", size: 16)!
return Text("Some Text")
.font(.custom("SomeFont", size: 16))
.lineSpacing(32 - font.lineHeight)
.padding(.vertical, (32 - font.lineHeight) / 2)
为了获得准确的行距值,我们必须用字体固有的行高减去我们想要的行高,但正如您所指出的,这只会对多行文本和行间生效。我们仍然需要考虑文本的顶部和底部填充以匹配所需的行高,因此再次添加总行高减去字体的行高。
我已成功使用以下组合:
.frame(minHeight: lineHeight)
.lineSpacing(abs(designSystemFont.lineHeight - uiKitFont.lineHeight))
The
abs
may not be needed (assuming the system's line height is taller than the default one, but you never know if that may change, so...)
这使我能够在尊重设计系统要求的同时处理 single-line 文本。
根据 Dan Hassan 的回答,我为自己制作了一个 ViewModifier 来执行此操作,看起来它按预期工作
import SwiftUI
struct FontWithLineHeight: ViewModifier {
let font: UIFont
let lineHeight: CGFloat
func body(content: Content) -> some View {
content
.font(Font(font))
.lineSpacing(lineHeight - font.lineHeight)
.padding(.vertical, (lineHeight - font.lineHeight) / 2)
}
}
extension View {
func fontWithLineHeight(font: UIFont, lineHeight: CGFloat) -> some View {
ModifiedContent(content: self, modifier: FontWithLineHeight(font: font, lineHeight: lineHeight))
}
}
实际上对我有用的是(基于 Ole-Kristian 的回答)
import SwiftUI
struct FontWithLineHeight: ViewModifier {
let font: UIFont
let lineHeight: CGFloat
func body(content: Content) -> some View {
content
.font(Font(font))
.lineSpacing((token.lineHeight - token.font.lineHeight)/2)
.padding(.vertical, (token.lineHeight - token.font.lineHeight))
}
}
extension View {
func fontWithLineHeight(font: UIFont, lineHeight: CGFloat) -> some View {
ModifiedContent(content: self, modifier: FontWithLineHeight(font: font, lineHeight: lineHeight))
}
}
...与填充值和 lineSpacing 值相反的其他答案非常相似。
这是我让底部 'padding' 与 Figma 相同的唯一方法。