@@ -51,7 +51,7 @@ struct TTSControls: View {
51
51
TTSSettings ( viewModel: viewModel)
52
52
. frame (
53
53
minWidth: 320 , idealWidth: 400 , maxWidth: nil ,
54
- minHeight: 150 , idealHeight: 150 , maxHeight: nil ,
54
+ minHeight: 300 , idealHeight: 300 , maxHeight: nil ,
55
55
alignment: . top
56
56
)
57
57
}
@@ -69,48 +69,47 @@ struct TTSSettings: View {
69
69
@ObservedObject var viewModel : TTSViewModel
70
70
71
71
var body : some View {
72
- List {
73
- Section ( header : Text ( " Speech settings " ) ) {
74
- ConfigStepper (
72
+ NavigationView {
73
+ Form {
74
+ stepper (
75
75
caption: " Rate " ,
76
76
for: \. rate,
77
77
step: viewModel. defaultConfig. rate / 10
78
78
)
79
79
80
- ConfigStepper (
80
+ stepper (
81
81
caption: " Pitch " ,
82
82
for: \. pitch,
83
83
step: viewModel. defaultConfig. pitch / 4
84
84
)
85
85
86
- ConfigPicker (
86
+ picker (
87
87
caption: " Language " ,
88
88
for: \. defaultLanguage,
89
89
choices: viewModel. availableLanguages,
90
90
choiceLabel: { $0. localizedDescription ( ) }
91
91
)
92
92
93
- ConfigPicker (
93
+ picker (
94
94
caption: " Voice " ,
95
95
for: \. voice,
96
96
choices: viewModel. availableVoices,
97
97
choiceLabel: { $0. localizedDescription ( ) }
98
98
)
99
99
}
100
+ . navigationTitle ( " Speech settings " )
101
+ . navigationBarTitleDisplayMode ( . inline)
100
102
}
101
- . listStyle ( . insetGrouped )
103
+ . navigationViewStyle ( . stack )
102
104
}
103
105
104
- @ViewBuilder func ConfigStepper (
106
+ @ViewBuilder func stepper (
105
107
caption: String ,
106
108
for keyPath: WritableKeyPath < TTSConfiguration , Double > ,
107
109
step: Double
108
110
) -> some View {
109
111
Stepper (
110
- value: Binding (
111
- get: { viewModel. config [ keyPath: keyPath] } ,
112
- set: { viewModel. config [ keyPath: keyPath] = $0 }
113
- ) ,
112
+ value: configBinding ( for: keyPath) ,
114
113
in: 0.0 ... 1.0 ,
115
114
step: step
116
115
) {
@@ -119,29 +118,25 @@ struct TTSSettings: View {
119
118
}
120
119
}
121
120
122
- @ViewBuilder func ConfigPicker < T: Hashable > (
121
+ @ViewBuilder func picker < T: Hashable > (
123
122
caption: String ,
124
123
for keyPath: WritableKeyPath < TTSConfiguration , T > ,
125
124
choices: [ T ] ,
126
125
choiceLabel: @escaping ( T ) -> String
127
126
) -> 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) )
141
130
}
142
- . pickerStyle ( . menu)
143
131
}
144
132
}
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
+ }
145
140
}
146
141
147
142
private extension Optional where Wrapped == TTSVoice {
0 commit comments