我想在圆形视图内创建一个文本视图。字体大小应自动设置为适合圆圈的大小。如何在SwiftUI中完成?我尝试过scaledToFill和scaledToFit修饰符,但它们对Text视图没有影响:
struct ContentView : View {
var body: some View {
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text").scaledToFill()
}
}
}
Run Code Online (Sandbox Code Playgroud)
sim*_*bac 40
可以使用GeometryReader
以使其也可以在横向模式下工作。
它首先检查宽度或高度是否更小,然后根据这些中的较小者调整字体大小。
GeometryReader{g in
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.font(.system(size: g.size.height > g.size.width ? g.size.width * 0.4: g.size.height * 0.4))
}
}
Run Code Online (Sandbox Code Playgroud)
Gra*_*eph 27
您希望允许您的文本:
您可以选择此比例因子限制以满足您的需要。通常,您不会缩小超出可读性或超出限制,这将使您的设计看起来很糟糕
struct ContentView : View {
var body: some View {
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.scaledToFill()
.minimumScaleFactor(0.5)
.lineLimit(1)
}
}
Run Code Online (Sandbox Code Playgroud)
}
Ond*_*j H 22
我有固定大小的按钮,这对我来说可以自动缩小长文本。
Text("This is a long label that will be scaled to fit:")
.lineLimit(1)
.minimumScaleFactor(0.5)
Run Code Online (Sandbox Code Playgroud)
Ant*_*ton 11
这是一个将文本调整代码隐藏在自定义修饰符中的解决方案,该修饰符可以应用于任何视图,而不仅仅是圆形,并采用一个参数指定文本应占据的视图的分数。
(我必须同意,虽然@szemian 的解决方案仍然不理想,但由于其他方法固有的问题,她的方法似乎是我们对当前 SwiftUI 实现所能做的最好的方法。@simibac 的答案需要摆弄以找到一个新的幻数每当文本或其属性(字体、粗细等)发生更改时,请替换 0.4,并且@giuseppe-sapienza 不允许指定圆圈的大小,仅允许指定文本的字体大小。)
struct FitToWidth: ViewModifier {
var fraction: CGFloat = 1.0
func body(content: Content) -> some View {
GeometryReader { g in
content
.font(.system(size: 1000))
.minimumScaleFactor(0.005)
.lineLimit(1)
.frame(width: g.size.width*self.fraction)
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用修饰符,代码变成这样:
var body: some View {
Circle().strokeBorder(Color.red, lineWidth: 30)
.aspectRatio(contentMode: .fit)
.overlay(Text("Text")
.modifier(FitToWidth(fraction: fraction)))
}
Run Code Online (Sandbox Code Playgroud)
此外,当 Xcode 的未来版本提供 SwiftUI 改进以消除.minimumScaleFactor
黑客攻击时,您只需更新修改器代码即可使用它。:)
如果您想查看分数参数的工作原理,请使用以下代码,让您使用滑块以交互方式调整它:
struct ContentView: View {
@State var fraction: CGFloat = 0.5
var body: some View {
VStack {
Spacer()
Circle().strokeBorder(Color.red, lineWidth: 30)
.aspectRatio(contentMode: .fit)
.overlay(Text("Text")
.modifier(FitToWidth(fraction: fraction)))
Slider(value: $fraction, in:0.1...0.9, step: 0.1).padding()
Text("Fraction: \(fraction, specifier: "%.1f")")
Spacer()
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是它的样子:
我混合了 @Simibac 和 @Anton 的答案,但被 iOS 14.0 破坏了,所以这就是我修复它的方法。也应该适用于 SwiftUI 1.0。
struct FitSystemFont: ViewModifier {
var lineLimit: Int
var minimumScaleFactor: CGFloat
var percentage: CGFloat
func body(content: Content) -> some View {
GeometryReader { geometry in
content
.font(.system(size: min(geometry.size.width, geometry.size.height) * percentage))
.lineLimit(self.lineLimit)
.minimumScaleFactor(self.minimumScaleFactor)
.position(x: geometry.frame(in: .local).midX, y: geometry.frame(in: .local).midY)
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我使用几何代理的frame(in:)
方法来获取本地坐标空间,然后使用.midX
和.midY
使其正确居中,因为正确居中是我在 iOS 14 上遇到的问题。
然后我在以下位置设置了扩展View
:
extension View {
func fitSystemFont(lineLimit: Int = 1, minimumScaleFactor: CGFloat = 0.01, percentage: CGFloat = 1) -> ModifiedContent<Self, FitSystemFont> {
return modifier(FitSystemFont(lineLimit: lineLimit, minimumScaleFactor: minimumScaleFactor, percentage: percentage))
}
}
Run Code Online (Sandbox Code Playgroud)
所以用法是这样的:
Text("Your text")
.fitSystemFont()
Run Code Online (Sandbox Code Playgroud)
一种可能的“破解”是使用较大的字体大小和较小的缩放比例,以使其自身收缩:
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.padding(40)
.font(.system(size: 500))
.minimumScaleFactor(0.01)
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1260 次 |
最近记录: |