如何解决如何响应动态文本大小的更改来更改懒惰网格GridItem的固定大小?
下面的代码使用LazyVGrid
来实现控件的布局,以便所有内容都像这样排列:
尤其是,滑块的末端全部对齐,并且符号彼此居中对齐。我已经研究出如何调整符号和数字读数的GridItem的大小,以使其成为其内容的“正确大小”-灵活的或自适应的GridItems都无法做到这一点-考虑动态类型
在测试中,只要用户在应用程序激活后不更改其动态类型大小,此方法就非常有效。如果这样做,类型(和符号)将按照其应有的方式进行调整,但是GridItem的大小将保持固定为其初始值。这会导致数字在小数点后换行。
是否有一种方法可以调整GridItem的大小以响应动态类型的更改,或者有更好的方法来进行此布局?
import SwiftUI
struct ProtoGrid: View {
let gridItems = [
GridItem(.fixed(UIImage(systemName: "ruler",withConfiguration: UIImage.SymbolConfiguration(textStyle: .body,scale: .large))!.size.width)),GridItem(.flexible(minimum: 40,maximum: .infinity)),GridItem(.fixed(("00.00" as Nsstring).size(withAttributes: [NSAttributedString.Key.font: UIFont.preferredFont(forTextStyle: .body)]).width + 4),alignment: .trailing)
]
@State var index1 = 5.0
@State var index2 = 5.0
@State var index3 = 5.0
var body: some View {
vstack {
Rectangle()
.fill(Color.red)
LazyVGrid(columns: gridItems,spacing: 12) {
Image(systemName: "person").imageScale(.large)
Slider(value: $index1,in: 0...10)
Text("\(String(format: "%.2f",index1))").font(Font.system(.body).monospacedDigit())
Image(systemName: "megaphone").imageScale(.large)
Slider(value: $index2,index2))").font(Font.system(.body).monospacedDigit())
Image(systemName: "ruler").imageScale(.large)
Slider(value: $index3,index3))").font(Font.system(.body).monospacedDigit())
}
.padding()
}
}
}
struct ProtoGrid_Previews: PreviewProvider {
static var previews: some View {
ProtoGrid()
.previewDevice("iPhone 11 Pro")
}
}
111
解决方法
由于图像尺寸不同,尝试在此处使用网格的目的似乎很明确,即具有对齐的滑块,但是网格配置是恒定的,即您只做了一次。实际上,它是经过硬编码的,因此不适用于动态文本大小写。
我会提出另一种方法-只使用常规的HStack,它可以动态地适应内容,并且可以对内容进行一些自定义动态对齐。
通过Xcode 12 / iOS 14测试
struct ProtoGrid: View {
@State var index1 = 5.0
@State var index2 = 5.0
@State var index3 = 5.0
@State private var imageWidth = CGFloat.zero
var body: some View {
VStack {
Rectangle()
.fill(Color.red)
HStack(spacing: 12) {
Image(systemName: "person").imageScale(.large)
.alignedView(width: $imageWidth)
Slider(value: $index1,in: 0...10)
Text("\(String(format: "%.2f",index1))").font(Font.system(.body).monospacedDigit())
}
HStack(spacing: 12) {
Image(systemName: "megaphone").imageScale(.large)
.alignedView(width: $imageWidth)
Slider(value: $index2,index2))").font(Font.system(.body).monospacedDigit())
}
HStack(spacing: 12) {
Image(systemName: "ruler").imageScale(.large)
.alignedView(width: $imageWidth)
Slider(value: $index3,index3))").font(Font.system(.body).monospacedDigit())
}
}
.padding()
}
}
extension View {
func alignedView(width: Binding<CGFloat>) -> some View {
self.modifier(AlignedWidthView(width: width))
}
}
// creates a view which uses max width of calculated intrinsic
// content or shared from external width,updating external
// bound variable if own width is bigger.
struct AlignedWidthView: ViewModifier {
@Binding var width: CGFloat
func body(content: Content) -> some View {
content
.background(GeometryReader {
Color.clear
.preference(key: ViewWidthKey.self,value: $0.frame(in: .local).size.width)
})
.onPreferenceChange(ViewWidthKey.self) {
if $0 > self.width {
self.width = $0
}
}
.frame(width: width)
}
}
struct ViewWidthKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value,nextValue: () -> Value) {
value += nextValue()
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。