问题
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