@@ -51,7 +51,7 @@ struct TTSControls: View {
5151 TTSSettings ( viewModel: viewModel)
5252 . frame (
5353 minWidth: 320 , idealWidth: 400 , maxWidth: nil ,
54- minHeight: 150 , idealHeight: 150 , maxHeight: nil ,
54+ minHeight: 300 , idealHeight: 300 , maxHeight: nil ,
5555 alignment: . top
5656 )
5757 }
@@ -69,48 +69,47 @@ struct TTSSettings: View {
6969 @ObservedObject var viewModel : TTSViewModel
7070
7171 var body : some View {
72- List {
73- Section ( header : Text ( " Speech settings " ) ) {
74- ConfigStepper (
72+ NavigationView {
73+ Form {
74+ stepper (
7575 caption: " Rate " ,
7676 for: \. rate,
7777 step: viewModel. defaultConfig. rate / 10
7878 )
7979
80- ConfigStepper (
80+ stepper (
8181 caption: " Pitch " ,
8282 for: \. pitch,
8383 step: viewModel. defaultConfig. pitch / 4
8484 )
8585
86- ConfigPicker (
86+ picker (
8787 caption: " Language " ,
8888 for: \. defaultLanguage,
8989 choices: viewModel. availableLanguages,
9090 choiceLabel: { $0. localizedDescription ( ) }
9191 )
9292
93- ConfigPicker (
93+ picker (
9494 caption: " Voice " ,
9595 for: \. voice,
9696 choices: viewModel. availableVoices,
9797 choiceLabel: { $0. localizedDescription ( ) }
9898 )
9999 }
100+ . navigationTitle ( " Speech settings " )
101+ . navigationBarTitleDisplayMode ( . inline)
100102 }
101- . listStyle ( . insetGrouped )
103+ . navigationViewStyle ( . stack )
102104 }
103105
104- @ViewBuilder func ConfigStepper (
106+ @ViewBuilder func stepper (
105107 caption: String ,
106108 for keyPath: WritableKeyPath < TTSConfiguration , Double > ,
107109 step: Double
108110 ) -> some View {
109111 Stepper (
110- value: Binding (
111- get: { viewModel. config [ keyPath: keyPath] } ,
112- set: { viewModel. config [ keyPath: keyPath] = $0 }
113- ) ,
112+ value: configBinding ( for: keyPath) ,
114113 in: 0.0 ... 1.0 ,
115114 step: step
116115 ) {
@@ -119,29 +118,25 @@ struct TTSSettings: View {
119118 }
120119 }
121120
122- @ViewBuilder func ConfigPicker < T: Hashable > (
121+ @ViewBuilder func picker < T: Hashable > (
123122 caption: String ,
124123 for keyPath: WritableKeyPath < TTSConfiguration , T > ,
125124 choices: [ T ] ,
126125 choiceLabel: @escaping ( T ) -> String
127126 ) -> some View {
128- HStack {
129- Text ( caption)
130- Spacer ( )
131-
132- Picker ( caption,
133- selection: Binding (
134- get: { viewModel. config [ keyPath: keyPath] } ,
135- set: { viewModel. config [ keyPath: keyPath] = $0 }
136- )
137- ) {
138- ForEach ( choices, id: \. self) {
139- Text ( choiceLabel ( $0) )
140- }
127+ Picker ( caption, selection: configBinding ( for: keyPath) ) {
128+ ForEach ( choices, id: \. self) {
129+ Text ( choiceLabel ( $0) )
141130 }
142- . pickerStyle ( . menu)
143131 }
144132 }
133+
134+ private func configBinding< T> ( for keyPath: WritableKeyPath < TTSConfiguration , T > ) -> Binding < T > {
135+ Binding (
136+ get: { viewModel. config [ keyPath: keyPath] } ,
137+ set: { viewModel. config [ keyPath: keyPath] = $0 }
138+ )
139+ }
145140}
146141
147142private extension Optional where Wrapped == TTSVoice {
0 commit comments