Open1

SwiftUI: Dynamic Typeで大きさが変わるテキストと変わらないテキスト

kabeyakabeya

ツールバーを作っていて、.segmentedPickerButtonを並べるケースがあったのですが、iOSで文字のサイズを変えるとPickerはそのままでButtonだけ文字が大きくなりました。

要はiOS+SwiftUIのUIコンポーネントには、Dynamic Typeで大きさが変わるものと変わらないものがあるということなんだと思いますが、何が変わって何が変わらないのか、一覧というか画面に貼り付けてみました。


標準フォントサイズ(Large)での表示


さらに大きいフォント(ここではAX2)での表示


コードは以下です。

struct AllUIComponentsView: View {
    @State var multiDatePickerSelection: Set<DateComponents> = []
    @State var text: String = ""
    @State var doubleValue: Double = 3
    var body: some View {
        HStack {
            VStack {
                Button("Button") {
                    
                }
                Image(systemName: "person.fill.badge.plus")
                Button(action: {}, label: {
                    Image(systemName: "person.fill.badge.plus")
                })
                

                DatePicker(selection: .constant(Date()), label: { Text("DatePicker") })
                    .datePickerStyle(.compact)
                DatePicker(selection: .constant(Date()), label: { Text("DatePicker") })
                    .datePickerStyle(.graphical)
                DatePicker(selection: .constant(Date()), label: { Text("DatePicker") })
                    .datePickerStyle(.wheel)
                ColorPicker("ColorPicker", selection: .constant(.red))
                Text("Text")
                DisclosureGroup("DiclosureGroup") {
                    Text("DiclosureContent(Text)")
                }
                
               
                
            }
            VStack {
                LabeledContent("LabeledContent") {
                    Text("LabeledContent(Text)")
                }
                Link(destination: URL(fileURLWithPath: "")) {
                    Text("Link")
                }
                List {
                    Text("ListContent(Text)")
                    Text("ListContent(Text)")
                    Text("ListContent(Text)")
                }
                Menu("Menu") {
                    Text("Menu Item(Text)")
                    Text("Menu Item(Text)")
                    Text("Menu Item(Text)")
                }
                MultiDatePicker("MultiDatePicker", selection: $multiDatePickerSelection)
                NavigationLink(destination: Text("NavigationLinkDestination(Text)")) {
                    Text("NavigationLinkLabel(Text)")
                }
                NavigationSplitView {
                    Text("NavigationSplitViewSidebar")
                } detail: {
                    Text("NavigationSplitViewDetail(Text)")
                }
                NavigationStack {
                    Text("NavigationStackContent(Text)")
                }
                NavigationView {
                    NavigationLink(destination: Text("NavigationLinkDestination(Text)")) { Text("NavigationLinkContent(Text)")
                    }
                }
            }
            VStack {
                EditButton()
                Form {
                    Text("FormContent(Text)")
                    Text("FormContent(Text)")
                    Text("FormContent(Text)")
                }
                Gauge(value: 0.3, in: 0...1) {
                    Text("Gauge")
                }
                GroupBox(label: Text("GroupBox")) {
                    Text("GroupBoxContent(Text)")
                }
                Picker(selection: .constant(1), label: Text("Picker(.menu)")) {
                    Text("MenuContent1").tag(1)
                    Text("MenuContent2").tag(2)
                }
                .pickerStyle(.menu)
                Picker(selection: .constant(1), label: Text("Picker(.segmented)")) {
                    Text("SegmentedContent1").tag(1)
                    Text("SegmentedContent2").tag(2)
                }
                .pickerStyle(.segmented)
                Picker(selection: .constant(1), label: Text("Picker(.inline)")) {
                    Text("InlineContent1").tag(1)
                    Text("InlineContent2").tag(2)
                }
                .pickerStyle(.inline)
                Picker(selection: .constant(1), label: Text("Picker(.palette)")) {
                    Text("PaletteContent1").tag(1)
                    Text("PaletteContent2").tag(2)
                }
                .pickerStyle(.palette)
                Picker(selection: .constant(1), label: Text("Picker(.wheel)")) {
                    Text("WheelContent1").tag(1)
                    Text("WheelContent2").tag(2)
                }
                .pickerStyle(.wheel)
                ProgressView(value: 0.5)
                RenameButton()
            }
            VStack {
                ScrollView {
                    Text("ScrollViewContent(Text)")
                }
                Section {
                    Text("SectionContent(Text)")
                }
                ShareLink(item: URL(string: "https://developer.apple.com/xcode/swiftui")!)
                SecureField("SecureField", text: $text)
                Slider(value: $doubleValue)
                TabView(selection: .constant(1)) {
                    Text("Tab Content 1").tabItem { Text("Tab Label 1") }.tag(1)
                    Text("Tab Content 2").tabItem { Text("Tab Label 2") }.tag(2)
                }
                TextEditor(text: .constant("TextEditor(Placeholder)"))
                TextField("TextField(Placeholder)", text: $text)
                Toggle(isOn: .constant(true)) {
                    Text("ToggleLabel")
                }
            }
        }
    }
}

およそほとんどのコンポーネントがでかくなるのですが、大きくならないものもあるということが分かります。
着目点は以下のあたりでしょうか。

  • Imageもでかくなる。Buttonに使っている場合だけかと思ってたら、単体で使ってる場合もでかくなる。
  • スタイルによってでかくなったりならなかったりするものがある。気付いたのはPicker/DatePickerですが他もあるかも知れません。
  • DatePicker/MultiDatePicker.graphicalは、他のと比べて大きさの変わり方が小さい。曜日の文字列も変わっている。
  • TabViewのラベル、.segmented/.palettePicker(=UISegmentedControlを使っているもの?)、.inline/.wheelPicker/DatePicker/MultiDatePicker(=UIPickerViewを使っているもの?)は大きくならない。

で、冒頭のツールバーに.segmentedPickerButtonを並べるケースでは、Picker同様、Buttonも文字を大きくしたくないと思います。(そうでないと収まらない)

こうした大きくしたくないビューには、.dynamicTypeSize(.large)というモディファイアをつけると、標準サイズのままになります。(逆に小さくもならない)