如何在swiftUI中交换两个相同的选择器值



在这段代码中,我想改变两个选择器值,当它们是相同的,以保持这两个彼此不同。我尝试使用swap,但是不能正常工作。

例如:当第一个选择器值为1,第二个选择器值为2时,当我试图将第二个值更改为"1"时,值立即更改为1,第一个选择器变为2 !

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) 

我怎么能执行立即交换这两个值时,例如去相同的从?

我认为缺少了一种联系。你国家

如果我对第一个拾取器的更改导致两个拾取器相等,那么立即交换它们!

如果你交换两个相等的值,你会得到两个相等的值。

假设:

看来你想要的是解决方案的标准面试问题交换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

实现"切换"的唯一方法就是确定是否有需要调换之前的"真相来源";变化。

  1. 选择新值
  2. 检查是否需要交换
  3. 交换真值的来源
  4. 告诉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)
}
}
}

仍然不能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)
}
}
}

相关内容

  • 没有找到相关文章

最新更新