在這段代碼中,我想在它們相同時更改兩個選擇器值以保持這兩個彼此不同。我嘗試使用交換,但這不能正常作業。
例如:當第一個選擇器的值為一個而第二個是兩個時,當我嘗試將第二個值更改為“一”時,值立即變為一個,第一個選擇器變為兩個!
struct ContentView: View {
@State private var list = ["one","two","three","four","five"]
@State private var from: String = "one"
@State private var from: String = "two"
var body: some View {
VStack {
Picker("",selection: $from) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
.onChange(of: from) { newValue in
if newValue == to {
(to,from) = (from, to)
}
}
Picker("",selection: $to) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
}
}
}
我將這個元組解決方案用于應用程式的另一部分,但在這部分不起作用:
(from, to) = (to, from)
例如,當與 from 相同時,如何立即交換這兩個值?
uj5u.com熱心網友回復:
我認為缺少一個聯系。你說
如果我對第一個選擇器的更改導致兩個選擇器相等,請立即交換它們!
如果你交換 2 個相等的值,你會得到 2 個相等的值。
假設:
您似乎想要的是交換 2 個值的標準面試問題的解決方案。
給定 x=1 和 y=2。交換值
這樣做的方法是
let temp = y //holds a value
y = x //starts swap
x = temp //finishes swap
現在你的結果是y=1 and x=2
在交換值時,您需要該temp變數來保存其中一個的值。
現在,如果我們回到您的陳述,謬誤在于等待值變得相等。
當您單擊新專案時,立即進行更改,無法檢索以前的值。
x = newValue or y = newValue
實作“交換”的唯一方法是在“事實來源”發生變化之前確定是否需要交換。
- 選擇新值
- 檢查是否需要交換
- 交換真值的來源
- 告訴 SwiftUI 有更新
您可以在 SwiftUI 中使用ObservableObject
class AutoPickerVM: ObservableObject{
///Variable that holds the value for From - Source of truth
private var storeFrom: String = "one"
///Processes the changes between the pickers and triggers view updates
var from: String {
get{
storeFrom
}
set{
if newValue == to{
//Take the value that is currently there
let curTo = to
//Start swapping
storeTo = storeFrom
//Place the previous value
storeFrom = curTo
}else{
storeFrom = newValue
}
objectWillChange.send()
}
}
///Variable that holds the value for to - Source of truth
private var storeTo: String = "two"
///Processes the changes between the pickers and triggers view updates
var to: String {
get{
storeTo
}
set{
if newValue == from{
//Take the value that is currently there
let curFrom = from
//Start swapping
storeFrom = storeTo
//Place the previous value
storeTo = curFrom
}else{
storeTo = newValue
}
objectWillChange.send()
}
}
init(){}
}
然后你View會看起來像這樣
struct AutoPicker: View {
@StateObject var vm: AutoPickerVM = .init()
@State private var list = ["one","two","three","four","five"]
var body: some View {
VStack {
Picker("",selection: $vm.from) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
Picker("",selection: $vm.to) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
}
}
}
uj5u.com熱心網友回復:
仍然不能 100% 確定您要做什么,但可能是這樣的,如使用輔助變數的示例代碼所示:
struct ContentView: View {
@State private var list = ["one","two","three","four","five"]
@State private var from: String = "one"
@State private var to: String = "two"
@State private var prevFrom: String = "one"
@State private var prevTo: String = "two"
var body: some View {
VStack {
Picker("",selection: $from) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
.onChange(of: to) { _ in
if to == from {
from = prevTo
}
prevTo = to
}
.onChange(of: from) { _ in
if to == from {
to = prevFrom
}
prevFrom = from
}
Picker("",selection: $to) {
ForEach(list, id: \.self) { item in
Text(item)
}
}
.pickerStyle(.menu)
.padding(.trailing)
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/497942.html
