向 SwiftUI Picker 添加回调
Posted
技术标签:
【中文标题】向 SwiftUI Picker 添加回调【英文标题】:Adding a callback to a SwiftUI Picker 【发布时间】:2019-07-17 22:05:43 【问题描述】:我正在尝试向 SwiftUI 选择器添加回调,但无法执行。 The didSet apparently does not execute when picker value changes.到目前为止,这是我尝试过的:
struct ContentView : View
@State private var picked: Int = 0 didSetprint("here")
var someData = ["a", "b", "c"]
var body: some View
VStack
Picker(selection: $picked,
label: Text(""))
ForEach(0 ..< someData.count) Text(self.someData[$0]).tag($0)
.pickerStyle(.wheel)
Text("you picked: \(someData[picked])")
【问题讨论】:
【参考方案1】:代码更新至 beta 6
@State 变量永远不会执行 didSet,因为它不会改变。改变的是包装的价值。所以我能想到的唯一方法是在中间放置第二个绑定,作为中介,并传递值。这样,您就可以将回调放在那里。
struct ContentView : View
@State private var picked: Int = 0
var someData = ["a", "b", "c"]
var body: some View
let p = Binding<Int>(get:
return self.picked
, set:
self.picked = $0
// your callback goes here
print("setting value \($0)")
)
return VStack
Picker(selection: p,
label: Text(""))
ForEach(0 ..< someData.count)
Text(self.someData[$0]).tag($0)
.pickerStyle(WheelPickerStyle())
Text("you picked: \(someData[picked])")
【讨论】:
DOESNT COMPILE:函数声明了一个不透明的返回类型,但在其主体中没有返回语句来推断底层类型 这只是一半。我似乎可以让它回来工作。假设您要转换通过绑定传入的字母“b”并使其成为选定按钮。我不能让它工作 @jimijon 这是一个小问题,与 SwiftUI 无关:只需在数组中查找项目索引:self.picked = self.someData.firstIndex(of: "b") ?? 0
不是。设置好后尝试将绑定传递给视图。如何设置绑定:@Binding alphabetLetter:String。 ?然后您需要将 self.picked 设置为 self.someData.first ... 这会导致无限循环
Uau 不错的解决方案,效果很好!我需要这个来更新来自父视图的绑定变量。【参考方案2】:
你可以使用 ObservableObject 来解决它
import SwiftUI
class PickerModel:ObservableObject
@Published var picked: Int = 0 didSetprint("here")
struct Picker_Callback: View
@ObservedObject var pickerModal = PickerModel()
var someData = ["a", "b", "c"]
var body: some View
VStack
Picker(selection: self.$pickerModal.picked,
label: Text(""))
ForEach(0 ..< someData.count) Text(self.someData[$0]).tag($0)
//.pickerStyle(.wheel)
Text("you picked: \(someData[self.pickerModal.picked])")
【讨论】:
【参考方案3】:您不能在带有@State
属性包装器的变量上使用didSet
修饰符。
State
包装器告诉 SwiftUI,包装后的值必须由 SwiftUI 框架本身管理。这意味着视图实际上并不包含该值,它只包含一个 State
(它是不可变的),它提供对包装值的某种引用。
实际上,您应该忘记 SwiftUI View
中的 didSet
回调。
View
协议需要body
,它没有标记为mutating
(SwiftUI 视图为struct
)。所以View
基本上是不可变的。
【讨论】:
拉斐尔是 100% 正确的。 didSet 永远不会被调用。检查我的答案以获得解决方法。.onChange
修饰符(用于 Picker 等) 可用,这在某些情况下可能就足够了。以上是关于向 SwiftUI Picker 添加回调的主要内容,如果未能解决你的问题,请参考以下文章