SwiftUI: PreferenceKey is not called when parent view is embedded in NavigationView

江枫思渺然 提交于 2021-02-08 09:15:52

问题


DynamicScalingView is a child view with two buttons designed to have equal width & height using preferencekey

Issue: When DynamicScalingView is embedded in NavigationView it not longer adapts to intrinsic and increases its frame size. Current implementation without Navigation works fine but would like to understand how to fix this issue when embedded in NavigationView

  • Uncomment NavigationView in sample view to reproduce the issue
  • DynamicScalingView should adapt to Dynamic font size and increase its frame size maintaining equal width & height constraint between the buttons.

XCode 12.2 and iOS 14.2

struct SampleView: View {
    var body: some View {
        GeometryReader { gr in
            //NavigationView {
                ScrollView {
                    VStack {
                        // fills whatever space is left
                        Spacer()
                            .foregroundColor(.clear)

                        // view should fit with intrinsic content size
                        DynamicScalingView()
                            .padding(.horizontal, 20)
                            .border(Color.blue, width: 1)
                    }
                    .padding(.bottom, 20)
                    .border(Color.red, width: 1)
                    .frame(minHeight: gr.size.height)
                    .navigationBarHidden(true)
                }
        //  }
        }
    }

    struct DynamicScalingView: View {
        @State private var labelHeight = CGFloat.zero

        var body: some View {
            HStack {
                Button(action: {}, label: {
                    Text("Some Text Some Text Some Text")
                        .padding(.horizontal, 2)
                })
                    .foregroundColor(Color.white)
                    .padding(.vertical)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .frame(minHeight: labelHeight)
                    .background(Color.blue)
                    .cornerRadius(8)
                    .fixedSize(horizontal: false, vertical: true)
                    .background(GeometryReader {
                        Color.clear
                            .preference(
                                key: ViewHeightKey.self,
                                value: $0.frame(in: .local).size.height
                            )
                    })

                Button(action: {}, label: {
                    Text("Some Text")
                        .padding(.horizontal, 2)
                })
                    .foregroundColor(Color.white)
                    .padding(.vertical)
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .frame(minHeight: labelHeight)
                    .background(Color.blue)
                    .cornerRadius(8)
                    .fixedSize(horizontal: false, vertical: true)
                    .background(GeometryReader {
                        Color.clear
                            .preference(
                                key: ViewHeightKey.self,
                                value: $0.frame(in: .local).size.height
                            )
                    })
            }
            .onPreferenceChange(ViewHeightKey.self) {
                self.labelHeight = $0
            }
        }
    }

    struct ViewHeightKey: PreferenceKey {
        static var defaultValue: CGFloat { 0 }
        static func reduce(value: inout Value, nextValue: () -> Value) {
            value = max(value, nextValue())
        }
    }
}

来源:https://stackoverflow.com/questions/65674752/swiftui-preferencekey-is-not-called-when-parent-view-is-embedded-in-navigationv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!