我正在尝试在 SwiftUI 中使用动态大小,但我遇到了选择器视图实际上并未应用更改的问题。 如果我将 .dynamicTypeSize 直接应用于选择器,选择器的标题将更改其大小,但它不适用于段及其名称。 (我使用分段选择器样式)
有什么办法可以让它发挥作用吗? 例如,如果用户在 iPhone 上使用 xxxLarge 字体大小,然后我的应用程序会将其应用于所有内容但不适用于选择器,那么动态 ui 的意义何在?看起来很奇怪。
我尝试过使用dynamicTypeSize。
这是我认为的代码示例
.sheet(isPresented: $presentingModal) {
Spacer()
PickerView(title: eggSizes.title, options: eggSizes.options, selection: $eggTimerSettings.userSelections.size)
.padding(.horizontal)
PickerView(title: temperatures.title, options: temperatures.options, selection: $eggTimerSettings.userSelections.temperature)
.padding(.horizontal)
PickerView(title: donenessLevels.title, options: donenessLevels.options, selection: $eggTimerSettings.userSelections.doneness)
.padding(.horizontal)
Spacer()
Button(action: {
presentingModal.toggle()
navigate.toggle()
}, label: {
Text("Next")
.font(.system(.body, design: .rounded))
.fontWeight(.bold)
.foregroundStyle(.white)
.padding(.horizontal, 30)
.padding(.vertical, 15)
.background(RoundedRectangle(cornerRadius: 30)
.foregroundStyle(.black))
})
.padding(.bottom, 10)
.presentationDetents([.fraction(0.5)])
.presentationDragIndicator(.visible)
.presentationCornerRadius(25)
.presentationBackground(.regularMaterial)
}
.navigationDestination(isPresented: $navigate) {
TimerView()
.environmentObject(eggTimerSettings)
}
}
.dynamicTypeSize(...DynamicTypeSize.xxxLarge)
在分段选择器上设置字体大小不起作用,也不是动态的。但是,您可以申请
.scaleEffect
。
ScaleMetric
,您可以测量字体缩放并将其应用到 Picker
。在下面的示例中,
Picker
的上方和下方都有一个 Divider
,以显示高度是如何缩放的:
struct ContentView: View {
enum Choice: CaseIterable, Identifiable {
case first
case second
case third
var id: Choice {
self
}
var name: String {
"\(self)".capitalized
}
}
@ScaledMetric(relativeTo: .body) private var fontRefSize: CGFloat = 100.0
@State private var selection = Choice.first
private var fontScalingFactor: CGFloat {
max(1, (fontRefSize / 100))
}
var body: some View {
VStack(spacing: 0) {
Text("Body font")
Divider()
Picker("Choice", selection: $selection) {
ForEach(Choice.allCases) { choice in
Text(choice.name)
}
}
.pickerStyle(.segmented)
.fixedSize()
.frame(maxWidth: .infinity)
.frame(minHeight: 30 * fontScalingFactor)
.scaleEffect(fontScalingFactor)
Divider()
}
.padding(.top, 50)
.frame(maxHeight: .infinity, alignment: .top)
}
}
这种方法的一个缺点是选择器的所有方面都会被缩放。例如,这包括边框的厚度。
另一种方法是构建您自己的自定义分段选择器,这并不是很困难。
.matchedGeometryEffect
。这在如何创建这样的效果(两个重叠的矩形,并根据点击的矩形,切换颜色)中进行了说明。