我想在圆形视图内创建一个文本视图。字体大小应自动设置为适合圆圈的大小。如何在SwiftUI中完成?我尝试了scaledToFill和scaledToFit修饰符,但它们对“文本”视图没有影响:
struct ContentView : View {
var body: some View {
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text").scaledToFill()
}
}
}
答案 0 :(得分:11)
您要允许您的文字:
您可以选择此比例因子限制来满足您的需求。通常,您不会缩小到可读性或限制之外,否则会使您的设计看起来很糟糕
struct ContentView : View {
var body: some View {
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.scaledToFill()
.minimumScaleFactor(0.5)
.lineLimit(1)
}
}
}
答案 1 :(得分:8)
我必须同意,尽管@szemian的解决方案仍然不理想,但由于其他固有的问题,她的方法似乎是我们可以使用当前SwiftUI实现执行的最佳方法。 (@simibac的答案要求在文本或其属性(字体,粗细等)发生更改时,必须努力寻找一个新的幻数来替换0.4,并且@ giuseppe-sapienza不允许圆的大小只能指定文字的字体大小。)
这是一种解决方案,它在自定义修饰符中隐藏了文本调整大小的代码,该修饰符可以应用于任何View,而不仅仅是一个Circle,并采用一个参数指定该文本应占据的View的比例。
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)
}
}
}
使用修饰符,代码就是这样:
var body: some View {
Circle().strokeBorder(Color.red, lineWidth: 30)
.aspectRatio(contentMode: .fit)
.overlay(Text("Text")
.modifier(FitToWidth(fraction: fraction)))
}
此外,当将来的Xcode版本提供SwiftUI改进以消除.minimumScaleFactor
hack时,您只需更新修饰符代码即可使用它。 :)
如果您想了解分数参数的工作原理,以下代码可让您使用滑块进行交互式调整:
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()
}
}
}
是这样的:
答案 2 :(得分:2)
一个人可以使用INFO: Closed connection [connectionId{localValue:2}] to 127.0.0.1:27017 because there was a socket exception raised by this connection.
Exception in thread "main" com.mongodb.MongoSecurityException: Exception authenticating MongoCredential{mechanism=SCRAM-SHA-1, userName='DM', source='Admin', password=<hidden>, mechanismProperties=<hidden>}
使其也可以在横向模式下工作。
它首先检查宽度或高度是否较小,然后根据较小的字体来调整字体大小。
GeometryReader
答案 3 :(得分:2)
我混合使用@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)
}
}
}
正如您所看到的,我使用了几何代理的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))
}
}
所以用法是这样的:
Text("Your text")
.fitSystemFont()
答案 4 :(得分:1)
一种可能的“破解方法”是使用大字体和小比例尺,以使其自身收缩:
ZStack {
Circle().strokeBorder(Color.red, lineWidth: 30)
Text("Text")
.padding(40)
.font(.system(size: 500))
.minimumScaleFactor(0.01)
}
}
答案 5 :(得分:1)
基于@JaimeeAz 的回答。添加了指定最小字体的选项。
import SwiftUI
public struct FitSystemFont: ViewModifier {
public var lineLimit: Int?
public var fontSize: CGFloat?
public var minimumScaleFactor: CGFloat
public var percentage: CGFloat
public func body(content: Content) -> some View {
GeometryReader { geometry in
content
.font(.system(size: min(min(geometry.size.width, geometry.size.height) * percentage, fontSize ?? CGFloat.greatestFiniteMagnitude)))
.lineLimit(self.lineLimit)
.minimumScaleFactor(self.minimumScaleFactor)
.position(x: geometry.frame(in: .local).midX, y: geometry.frame(in: .local).midY)
}
}
}
public extension View {
func fitSystemFont(lineLimit: Int? = nil, fontSize: CGFloat? = nil, minimumScaleFactor: CGFloat = 0.01, percentage: CGFloat = 1) -> ModifiedContent<Self, FitSystemFont> {
return modifier(FitSystemFont(lineLimit: lineLimit, fontSize: fontSize, minimumScaleFactor: minimumScaleFactor, percentage: percentage))
}
}
答案 6 :(得分:0)
要实现此目的,您不需要ZStack
。您可以为Text
添加背景:
Text("Text text text?")
.padding()
.background(
Circle()
.strokeBorder(Color.red, lineWidth: 10)
.scaledToFill()
.foregroundColor(Color.white)
)
答案 7 :(得分:-1)
对我来说效果出奇的便宜的厚皮
struct ContentView: View {
var scale = UIScreen.main.bounds.width*0.08
var body: some View {
Text("something").font(.system(size: scale))
}}