如何在SwiftUI中使用GeometryReader获取和读取文本大小?
我试图根据文本字体的大小来读取文本的宽度,因为我们知道GeometryReader占据了所有可能的位置,在这些代码中,它只接受给定的帧大小,我通过了它,但它不接受我文本的大小!我做错了什么?我什么GeometryReader开始只读取我的文本大小!不是他自己的框架宽度 这是我的密码:如何在SwiftUI中使用GeometryReader获取和读取文本大小?,swift,swiftui,Swift,Swiftui,我试图根据文本字体的大小来读取文本的宽度,因为我们知道GeometryReader占据了所有可能的位置,在这些代码中,它只接受给定的帧大小,我通过了它,但它不接受我文本的大小!我做错了什么?我什么GeometryReader开始只读取我的文本大小!不是他自己的框架宽度 这是我的密码: struct ContentView: View { @State var fontSize: CGFloat = 20.0 var body: some View { Spac
struct ContentView: View {
@State var fontSize: CGFloat = 20.0
var body: some View {
Spacer()
textWidthGeometryReader(fontSize: $fontSize)
Spacer()
Text("Font size:" + "\(fontSize)")
Slider(value: $fontSize, in: 20...40, step: 1)
.padding()
Spacer()
}
}
struct textWidthGeometryReader: View {
@Binding var fontSize: CGFloat
var body: some View {
GeometryReader { inSideGeometry in
Text("width of Text:" + String(format: "%.0f", inSideGeometry.size.width))
.font(.system(size: fontSize))
.background(Color.yellow)
.position(x: inSideGeometry.size.width / 2, y: inSideGeometry.size.height / 2)
}
.frame(width: 400, height: 300, alignment: .center)
.background(Color.gray)
.cornerRadius(20)
}
}
您可以使用视图首选项
首选项键
:ViewSizeKey
:查看首选项是一个相当高级的主题。您可以在此处找到更详细的说明:
struct ContentView: View {
@State var sizeOfText: CGSize = .zero
@State var fontSizeOfText: CGFloat = 20.0
var body: some View {
Text("Size of Text: " + String(format: "%.0f", sizeOfText.width) + "⭐︎" + String(format: "%.0f", sizeOfText.height))
.font(.system(size: fontSizeOfText))
.background(Color.yellow)
.background(sizeOfView(fontSizeOfText: $fontSizeOfText, sizeOfText: $sizeOfText))
Spacer()
Text("Font size:" + "\(fontSizeOfText)")
Slider(value: $fontSizeOfText, in: 20...40, step: 1)
.padding()
Spacer()
}
}
struct sizeOfView: View {
@Binding var fontSizeOfText: CGFloat
@Binding var sizeOfText: CGSize
var body: some View {
GeometryReader { proxy in
HStack {}
.onAppear { sizeOfText = proxy.size }
.onChange(of: fontSizeOfText) { _ in sizeOfText = proxy.size }
}
}
}
我找到了解决此问题的另一种方法,这次您可以使用。onReceive也可以,请查看我的代码并改进它,这种方法是3.0.0版!哈哈 代码:
你在这里玩得真开心!谢谢如何使GeometryReader进入文本内部,因为我知道该GeometryReader采用文本的大小?@Omid放置在
背景中的视图与它附加到的视图大小相同。这就是为什么放置在背景中的GeometryReader与文本大小相同。您的所有代码都正常工作,但这并不是将其视为最佳方式的最佳方式!因为文本的宽度是两件事的子项,1-文本字符串,2.文本的字体,所以创建文本的Xcode使用的是父母制作的子项(宽度),为什么苹果会使用它来重新进行已经在文本创建阶段完成的计算?GeometryReader的所有要点是什么?所有答案都在已经完成的文本中。我们只是读取文本的宽度值,我的意思是文本肯定知道它的宽度,为什么我们应该问GeometryReader?@Omid 1)GeometryReader的所有点是什么读取视图的大小。但是,GeometryReader会占用所有可用空间-这就是为什么需要将其放在背景中(与文本大小相同)。2) 我的意思是文本肯定知道它的宽度-不,它不知道。SwiftUI不是UIKit。我知道GeometryReader的一般用法,我说的是一个哲学问题:“GeometryReader的所有要点是什么?”我想告诉大家为什么它应该存在!你说文字不知道自己的长度!我相信文本是一个视图,每个视图都有自己的特殊大小,并且在内存中也有特殊的id来查找它,如果文本作为视图不知道自己的大小,谁知道呢?是的,这也行,首选项方法只是更通用而已。正如您所看到的,您必须使用GeometryReader:)顺便说一句,您可以将onAppear
和onChange
组合起来-请参阅,谢谢,我最初想使用.onReceive实现,但我没有成功!有什么想法吗?你可以做onReceive(Just(fontSizeOfText)){…},你需要导入Combine
你可以先import Combine
,然后在你的代码中。onReceive(Just(fontSizeOfText)){in sizeOfText=proxy.size}
但如果您仍然有问题,请为此创建一个新问题。@pawello2222:请查看我的新答案。
struct ViewGeometry: View {
var body: some View {
GeometryReader { geometry in
Color.clear
.preference(key: ViewSizeKey.self, value: geometry.size)
}
}
}
struct ContentView: View {
@State var fontSize: CGFloat = 20.0
@State var textSize: CGSize = .zero
var body: some View {
Spacer()
Text("width of Text:" + String(format: "%.0f", textSize.width))
.font(.system(size: fontSize))
.background(ViewGeometry())
.onPreferenceChange(ViewSizeKey.self) {
textSize = $0
}
Spacer()
Text("Font size:" + "\(fontSize)")
Slider(value: $fontSize, in: 20...40, step: 1)
.padding()
Spacer()
}
}
struct ContentView: View {
@State var sizeOfText: CGSize = .zero
@State var fontSizeOfText: CGFloat = 20.0
var body: some View {
Text("Size of Text: " + String(format: "%.0f", sizeOfText.width) + "⭐︎" + String(format: "%.0f", sizeOfText.height))
.font(.system(size: fontSizeOfText))
.background(Color.yellow)
.background(sizeOfView(fontSizeOfText: $fontSizeOfText, sizeOfText: $sizeOfText))
Spacer()
Text("Font size:" + "\(fontSizeOfText)")
Slider(value: $fontSizeOfText, in: 20...40, step: 1)
.padding()
Spacer()
}
}
struct sizeOfView: View {
@Binding var fontSizeOfText: CGFloat
@Binding var sizeOfText: CGSize
var body: some View {
GeometryReader { proxy in
HStack {}
.onAppear { sizeOfText = proxy.size }
.onChange(of: fontSizeOfText) { _ in sizeOfText = proxy.size }
}
}
}
class TextModel: ObservableObject
{
@Published var sizeOfFont: CGFloat = 20.0
@Published var sizeOfText: CGSize = .zero
}
struct ContentView: View
{
@StateObject var textModel = TextModel()
var body: some View
{
Spacer()
Text("Size of Text: " + String(format: "%.0f", textModel.sizeOfText.width) + "⭐︎" + String(format: "%.0f", textModel.sizeOfText.height))
.font(.system(size: textModel.sizeOfFont))
.background(Color.yellow)
.background( sizeOfViewOptionA(textModel: textModel) )
Spacer()
Text("Size of Text: " + String(format: "%.0f", textModel.sizeOfText.width) + "⭐︎" + String(format: "%.0f", textModel.sizeOfText.height))
.font(.system(size: textModel.sizeOfFont))
.background(Color.red)
.background( sizeOfViewOptionB(textModel: textModel) )
Spacer()
Text("Font size:" + "\(textModel.sizeOfFont)")
Slider(value: $textModel.sizeOfFont, in: 20...40, step: 1)
.padding()
Spacer()
}
}
struct sizeOfViewOptionA: View
{
@ObservedObject var textModel: TextModel
var body: some View {
GeometryReader { proxy in
HStack{}
.onAppear() {textModel.sizeOfText = proxy.size}
.onChange(of: textModel.sizeOfFont) { _ in textModel.sizeOfText = proxy.size}
}
}
}
struct sizeOfViewOptionB: View
{
@ObservedObject var textModel: TextModel
var body: some View {
GeometryReader { proxy in
HStack{ Color.clear }
.onReceive(textModel.$sizeOfFont) { _ in textModel.sizeOfText = proxy.size}
}
}
}