SwiftUI比屏幕更宽,使用alignmentGuide可在另一个视图容器中查看
我正在学习SwiftUI,我读了这篇关于alignmentGuides以及如何对齐不同容器中的视图的非常好的文章: 在我的UI中,我希望有一个复选标记,然后在一行(橙色)上有一个Text()标签问题,然后在下面有一个TextField(),他们可以回答问题(绿色),我希望TextField()的前导与Text()问题的前导匹配。像这样: 上面的屏幕截图是在我使用SwiftUI比屏幕更宽,使用alignmentGuide可在另一个视图容器中查看,swiftui,Swiftui,我正在学习SwiftUI,我读了这篇关于alignmentGuides以及如何对齐不同容器中的视图的非常好的文章: 在我的UI中,我希望有一个复选标记,然后在一行(橙色)上有一个Text()标签问题,然后在下面有一个TextField(),他们可以回答问题(绿色),我希望TextField()的前导与Text()问题的前导匹配。像这样: 上面的屏幕截图是在我使用.frame(宽度:200)强制设置绿色文本字段()的宽度时生成的。我不想强制文本字段保持一定的大小,但是当我 不幸的是,每当我移除.
.frame(宽度:200)
强制设置绿色文本字段()的宽度时生成的。我不想强制文本字段保持一定的大小,但是当我
不幸的是,每当我移除.frame(宽度:200)
1) 绿色的TextField()然后延伸到比屏幕更宽的位置
2) 外部VStack也延伸到屏幕之外。
3) 橙色HStack中的复选标记图像()与屏幕的前端对齐
下面是没有TextField().frame(宽度:200)
时的情况,请注意,VStack的蓝色轮廓位于屏幕两侧:
代码如下:
extension HorizontalAlignment {
private enum QuestionAlignment : AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[.leading]
}
}
static let questionAlignment = HorizontalAlignment(QuestionAlignment.self)
}
struct EasyModeQuestion: View {
@Binding var field : String
var body: some View {
VStack(alignment: .questionAlignment) {
Rectangle()
.fill(Color.primary)
.frame(width: 1)
.alignmentGuide(.questionAlignment, computeValue: { d in d[HorizontalAlignment.leading] })
HStack() {
Image(systemName: "checkmark.square")
Text("What is the blah blah blah?")
.alignmentGuide(.questionAlignment, computeValue: { d in d[.leading] })
}.background(Color.orange)
TextFieldRoundedRect(placeholder: "", text: $field)
.alignmentGuide(.questionAlignment, computeValue: { d in d[.leading] })
.background(Color.green)
//.frame(width: 200)
Rectangle()
.fill(Color.primary)
.frame(width: 1)
.alignmentGuide(.questionAlignment, computeValue: { d in d[HorizontalAlignment.leading] })
}
}
}
上面和下面的两个Rectangle()对象是我问题顶部链接中的示例,它们有助于可视化对齐指南的位置
当我使用基本的前导对齐方式并删除所有对齐辅助线时,TextField()将返回到适当的宽度:
SwiftUI的布局方式与UIKit AutoLayout不同
TextField
计算其大小后应用的,但TextField
没有自己的大小,因此它会获取父视图建议的所有可能宽度,即屏幕宽度。然后,当应用对齐时,一切都变得一团糟
因此,您以某种方式将TextField
的大小限制为所需的值(顺便说一句,您没有指定哪个值?)
案例1:硬编码-就像您使用.frame(宽度:200)
案例2:占位符的固定大小
TextFieldRoundedRect(placeholder: "your answer is here", text: $field)
.alignmentGuide(.questionAlignment, computeValue: { d in d[.leading] })
.background(Color.green)
.fixedSize()
案例3:动态计算(GeometryReader、AnchorReference等)到您需要的点我是您在问题开头引用的文章的作者。对齐确实会带来挑战,不是吗?。在你的情况下,让我提出一种不同的方法。我知道对很多人来说,这件看起来很便宜。。。但它实现了一个非常重要的点:代码的简单性。我知道你的问题可能只是为了暴露你正在处理的问题而简化,如果是这样,那么提供的解决方案可能没有帮助。。。但这里是以防万一:只需使用一个垫片。我可以想出两种简单的方法。一个更快但更脏,另一个更优雅,但需要多行代码: #1快速且脏:使用不可见的复选标记图像作为间隔
struct ContentView:View{
@国家私有变量text=“”
var body:一些观点{
EasyModeQuestion(字段:self.$text)
.框架(宽度:400)
}
}
结构EasyModeQuestion:视图{
@绑定变量字段:字符串
var body:一些观点{
VStack(对齐:。前导){
HStack{
图像(系统名称:“复选标记.方形”)
文本(“什么是废话?”)
}
HStack{
图像(systemName:“checkmark.square”)。不透明度(0.0)
TextField(“,text:$field)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
}
}
#2个更好的间隔?:使用图像的宽度作为颜色。清晰视图
struct ContentView:View{
@国家私有变量text=“”
var body:一些观点{
EasyModeQuestion(字段:self.$text)
.框架(宽度:400)
}
}
结构EasyModeQuestion:视图{
@绑定变量字段:字符串
var body:一些观点{
让img=UIImage(系统名:“checkmark.square”)!
返回VStack(对齐:。前导){
HStack{
图像(uiImage:img)
文本(“什么是废话?”)
}
HStack{
颜色.清晰.边框(宽度:img.size.width,高度:0)
TextField(“,text:$field)
.textFieldStyle(RoundedBorderTextFieldStyle())
}
}
}
}
但是文本字段不仅仅占据了所有可用的大小,它还扩展到比屏幕更宽。如果我去掉所有的对齐,那么文本字段的大小是正确的。谢谢你的文章,谢谢你的回复!我可能会使用这些更脏的解决方案,但你知道为什么对齐位一开始就不起作用吗?我不喜欢假设这样的事情是错误的,尤其是当我知道SwiftUI有一个不同于我习惯的思维模式,这可能只是一些我不理解的东西。