问题
enum SectionType: String, CaseIterable {
case top = "Top"
case best = "Best"
}
struct ContentView : View {
@State private var selection: Int = 0
var body: some View {
SegmentedControl(selection: $selection) {
ForEach(SectionType.allCases.identified(by: \.self)) { type in
Text(type.rawValue).tag(type)
}
}
}
}
How do I run code (e.g print("Selection changed to \(selection)") when the $selection state changes? I looked through the docs and I couldn't find anything.
回答1:
You can't use didSet observer on @State but you can on an ObservableObject property.
import SwiftUI
import Combine
final class SelectionStore: ObservableObject {
var selection: SectionType = .top {
didSet {
print("Selection changed to \(selection)")
}
}
// @Published var items = ["Jane Doe", "John Doe", "Bob"]
}
Then use it like this:
import SwiftUI
enum SectionType: String, CaseIterable {
case top = "Top"
case best = "Best"
}
struct ContentView : View {
@ObservedObject var store = SelectionStore()
var body: some View {
List {
Picker("Selection", selection: $store.selection) {
ForEach(FeedType.allCases, id: \.self) { type in
Text(type.rawValue).tag(type)
}
}.pickerStyle(SegmentedPickerStyle())
// ForEach(store.items) { item in
// Text(item)
// }
}
}
}
回答2:
Not really answering your question, but here's the right way to set up SegmentedControl (didn't want to post that code as a comment, because it looks ugly). Replace your ForEach version with the following code:
ForEach(0..<SectionType.allCases.count) { index in
Text(SectionType.allCases[index].rawValue).tag(index)
}
Tagging views with enumeration cases or even strings makes it behave inadequately – selection doesn't work.
You might also want to add the following after the SegmentedControl declaration to ensure that selection works:
Text("Value: \(SectionType.allCases[self.selection].rawValue)")
Full version of body:
var body: some View {
VStack {
SegmentedControl(selection: self.selection) {
ForEach(0..<SectionType.allCases.count) { index in
Text(SectionType.allCases[index].rawValue).tag(index)
}
}
Text("Value: \(SectionType.allCases[self.selection].rawValue)")
}
}
Regarding your question – I tried adding didSet observer to selection, but it crashes Xcode editor and generates "Segmentation fault: 11" error when trying to build.
来源:https://stackoverflow.com/questions/56550713/how-can-i-run-an-action-when-a-state-changes