SwiftUI - 选择器.onChange 和 didSet
SwiftUI - Picker .onChange and didSet
我正在尝试实现所附 GIF 中的行为:
抱歉速度太快了,我不得不大幅压缩它才能上传到这里。该应用程序是来自 Readdle 的“文档”,如果您想自己看一下。
无论如何:我正在努力实现这种行为(排序和过滤,包括向上向下的动态箭头图标)。
我尝试了以下方法,但是我无法实现这种“ontap”体验。 On Change 仅在我更改值时触发,但当我想对现有值进行升序和降序排序时,它不起作用(这很明显,因为它没有变化)。我已经尝试过“didSet”,但这也没有用。
您知道如何实现吗?
下面是我的代码:
import SwiftUI
struct ContentView: View {
@State var selection = 0
@State var sortByAsc = true
@State var filterColumn = "A"
//Test to set case via picker but picter doesnt execute didSet
@State var myFilterTest: MyFilters = .alphabetical {
didSet {
switch myFilterTest {
case .creationDate:
sortByAsc.toggle()
print("c")
case .rating:
sortByAsc.toggle()
print("b")
case .alphabetical:
sortByAsc.toggle()
print("a")
}
}
}
var body: some View {
NavigationView {
Text("Hello, World!")
.padding()
.navigationTitle("SwiftUI")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu(content: {
Picker("My Picker", selection: $selection) {
Label("Title", systemImage: sortByAsc ? "arrow.down" : "arrow.up")
.tag(0)
Label("Rating", systemImage: sortByAsc ? "arrow.down" : "arrow.up")
.tag(1)
.onTapGesture {
print("tap")
}
}
.onChange(of: selection) { tag in
print("Selected Tag: \(tag)")
sortByAsc.toggle()
if(tag == 0) {
filterColumn = "Title"
}
if(tag == 1) {
filterColumn = "Rating"
}
}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
}
}
}
}
enum MyFilters: CaseIterable {
case alphabetical
case rating
case creationDate
}
解决了。这是代码:
struct PickerView: View {
@State private var pickerIndex = 0
@State private var previousPickerIndex = 0
@State var sortByAsc = true
var body: some View {
let pickerSelection = Binding<Int>(get: {
return self.pickerIndex
}, set: {
self.pickerIndex = [=10=]
if(pickerIndex == previousPickerIndex) {
sortByAsc.toggle()
}
previousPickerIndex = pickerIndex
})
NavigationView {
Text("Hello, World!")
.padding()
.navigationTitle("SwiftUI")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu(content: {
Picker("My Picker", selection: pickerSelection) {
ForEach(0..<4, id: \.self) { index in
Label("Title \(index)", systemImage: getSortingImage(menuItem: index))
.tag(index)
}
}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
}
}
}
func getSortingImage(menuItem: Int) -> String {
if(menuItem == pickerIndex) {
if(sortByAsc) {
return "arrow.down"}
else {
return "arrow.up"
}
}
else {
return ""
}
}
}
我正在尝试实现所附 GIF 中的行为:
抱歉速度太快了,我不得不大幅压缩它才能上传到这里。该应用程序是来自 Readdle 的“文档”,如果您想自己看一下。
无论如何:我正在努力实现这种行为(排序和过滤,包括向上向下的动态箭头图标)。
我尝试了以下方法,但是我无法实现这种“ontap”体验。 On Change 仅在我更改值时触发,但当我想对现有值进行升序和降序排序时,它不起作用(这很明显,因为它没有变化)。我已经尝试过“didSet”,但这也没有用。
您知道如何实现吗?
下面是我的代码:
import SwiftUI
struct ContentView: View {
@State var selection = 0
@State var sortByAsc = true
@State var filterColumn = "A"
//Test to set case via picker but picter doesnt execute didSet
@State var myFilterTest: MyFilters = .alphabetical {
didSet {
switch myFilterTest {
case .creationDate:
sortByAsc.toggle()
print("c")
case .rating:
sortByAsc.toggle()
print("b")
case .alphabetical:
sortByAsc.toggle()
print("a")
}
}
}
var body: some View {
NavigationView {
Text("Hello, World!")
.padding()
.navigationTitle("SwiftUI")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu(content: {
Picker("My Picker", selection: $selection) {
Label("Title", systemImage: sortByAsc ? "arrow.down" : "arrow.up")
.tag(0)
Label("Rating", systemImage: sortByAsc ? "arrow.down" : "arrow.up")
.tag(1)
.onTapGesture {
print("tap")
}
}
.onChange(of: selection) { tag in
print("Selected Tag: \(tag)")
sortByAsc.toggle()
if(tag == 0) {
filterColumn = "Title"
}
if(tag == 1) {
filterColumn = "Rating"
}
}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
}
}
}
}
enum MyFilters: CaseIterable {
case alphabetical
case rating
case creationDate
}
解决了。这是代码:
struct PickerView: View {
@State private var pickerIndex = 0
@State private var previousPickerIndex = 0
@State var sortByAsc = true
var body: some View {
let pickerSelection = Binding<Int>(get: {
return self.pickerIndex
}, set: {
self.pickerIndex = [=10=]
if(pickerIndex == previousPickerIndex) {
sortByAsc.toggle()
}
previousPickerIndex = pickerIndex
})
NavigationView {
Text("Hello, World!")
.padding()
.navigationTitle("SwiftUI")
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Menu(content: {
Picker("My Picker", selection: pickerSelection) {
ForEach(0..<4, id: \.self) { index in
Label("Title \(index)", systemImage: getSortingImage(menuItem: index))
.tag(index)
}
}
}, label: {
Image(systemName: "ellipsis.circle")
})
}
}
}
}
func getSortingImage(menuItem: Int) -> String {
if(menuItem == pickerIndex) {
if(sortByAsc) {
return "arrow.down"}
else {
return "arrow.up"
}
}
else {
return ""
}
}
}