Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift VStack子对象以填充(而不是展开)其父对象_Swift_Swiftui_Vstack - Fatal编程技术网

Swift VStack子对象以填充(而不是展开)其父对象

Swift VStack子对象以填充(而不是展开)其父对象,swift,swiftui,vstack,Swift,Swiftui,Vstack,我试图使警报视图的按钮适合父VStack。但我只能看到两种选择: 按钮宽度不变,无帧修改器。这并不理想,因为按钮不够宽 将帧修改器设置为.frame(maxWidth:.infinity)。这并不理想,因为它不仅填充其父对象,而且使其延伸到屏幕的边缘。 我真正想要的是,VStack保持其宽度,按钮刚好填充到边缘。没有延伸的VStack。VStack的大小由标题和消息定义,而不是由按钮定义。这是否可以通过SwiftUI实现 代码: 如注释中所述,如果希望宽度与消息大小相关联,则必须使用Pr

我试图使警报视图的按钮适合父VStack。但我只能看到两种选择:

  • 按钮宽度不变,无帧修改器。这并不理想,因为按钮不够宽

  • 将帧修改器设置为
    .frame(maxWidth:.infinity)
    。这并不理想,因为它不仅填充其父对象,而且使其延伸到屏幕的边缘。

  • 我真正想要的是,VStack保持其宽度,按钮刚好填充到边缘。没有延伸的VStack。VStack的大小由标题和消息定义,而不是由按钮定义。这是否可以通过SwiftUI实现

    代码:


    如注释中所述,如果希望宽度与消息大小相关联,则必须使用
    PreferenceKey
    将值向上传递到视图层次结构:

    struct ContentView: View {
        
        @State private var messageWidth: CGFloat = 0
        
        var body: some View {
            Color.white
                .overlay(
                    ZStack {
                        Color.black.opacity(0.4)
                            .edgesIgnoringSafeArea(.all)
                        
                        VStack(spacing: 15) {
                            Text("Alert View")
                                .font(.headline)
                            Text("This is just a message in an alert")
                                .background(GeometryReader {
                                    Color.clear.preference(key: MessageWidthPreferenceKey.self,
                                                           value: $0.frame(in: .local).size.width)
                                })
                            Button("Okay", action: {})
                                .padding()
                                .frame(width: messageWidth)
                                .background(Color.yellow)
                        }
                        .padding()
                        .background(Color.white)
                    }
                    .onPreferenceChange(MessageWidthPreferenceKey.self) { pref in
                        self.messageWidth = pref
                    }
                )
        }
        
        struct MessageWidthPreferenceKey : PreferenceKey {
            static var defaultValue: CGFloat { 0 }
            static func reduce(value: inout Value, nextValue: () -> Value) {
                value = value + nextValue()
            }
        }
    }
    

    我敢打赌,在某些情况下,您还需要设置最小宽度(例如,如果警报消息只有一个单词长),因此实际应用程序可能会使用
    max(minValue,messageWidth)
    或类似的方法来解释短消息。

    基本上,您希望按钮的宽度与消息的宽度相同,对吗?如果您不想为VStack设置精确的宽度,我认为您必须使用
    PreferenceKey
    s.correct,@jnpdx.yep,疯狂的详细解决方案,但这似乎是目前唯一的方法。非常感谢。
    struct ContentView: View {
        
        @State private var messageWidth: CGFloat = 0
        
        var body: some View {
            Color.white
                .overlay(
                    ZStack {
                        Color.black.opacity(0.4)
                            .edgesIgnoringSafeArea(.all)
                        
                        VStack(spacing: 15) {
                            Text("Alert View")
                                .font(.headline)
                            Text("This is just a message in an alert")
                                .background(GeometryReader {
                                    Color.clear.preference(key: MessageWidthPreferenceKey.self,
                                                           value: $0.frame(in: .local).size.width)
                                })
                            Button("Okay", action: {})
                                .padding()
                                .frame(width: messageWidth)
                                .background(Color.yellow)
                        }
                        .padding()
                        .background(Color.white)
                    }
                    .onPreferenceChange(MessageWidthPreferenceKey.self) { pref in
                        self.messageWidth = pref
                    }
                )
        }
        
        struct MessageWidthPreferenceKey : PreferenceKey {
            static var defaultValue: CGFloat { 0 }
            static func reduce(value: inout Value, nextValue: () -> Value) {
                value = value + nextValue()
            }
        }
    }