SwiftUIでカスタムなSegmentedControlを実装する
SwiftUIでSegmented Controlを使おうとすると、PickerにSegmentedPickerStyleを適用すれば一番楽だが、細かくデザイン調整しようとすると現状UISegmentedControl.appearance()を指定するしかなく、調整できる要素も少ないのが難点。そこで自前でカスタムなSegmented Controlを実装してみた。
Pickerで実装する場合
Pickerの場合、selectionに選択中の要素を渡して、pickerStyleにSegmentedPickerStyleを指定するだけでよい。
Picker("SegmentControl", selection: $selectedType) {
ForEach(SegmentType.allCases) { segment in
Text(segment.title)
}
}
.pickerStyle(.segmented)
しかし、フォントサイズやフォントカラー、選択中のセグメントのカラー、余白などは現状モディファイアで細かく指定することはできない。UISegmentedControl.appearance()で一部を指定することはできるが、他の利用箇所にも影響が出てしまう。
init() {
let appearance = UISegmentedControl.appearance()
let font = UIFont.boldSystemFont(ofSize: 12)
// 選択時の背景色
appearance.selectedSegmentTintColor = .black.withAlphaComponent(0.75)
// 通常時のフォントとフォント色
appearance.setTitleTextAttributes([.font: font, .foregroundColor: UIColor.black], for: .normal)
// 選択時のフォントとフォント色
appearance.setTitleTextAttributes([.font: font, .foregroundColor: UIColor.white], for: .selected)
}
カスタム実装の場合
Segmented Controlをカスタム実装する場合、基本的にHStackでButtonを並べて、それぞれのセグメントで通常時と選択時で重ねるUIを表示・非表示したり、ベースカラーやフォントカラーを切り替えればよい。また、Pickerでは指定できなかったpaddingやcornerRaduis、選択中のセグメントのカラーを別々にするなどのカスタマイズもできるようになる。
サンプルコードではselectedSegmentをwithAnimationでアニメーションさせているが、Pickerのようにスライドアニメーションを実装することもできる。
参考
この記事が気に入ったらサポートをしてみませんか?