了解SwiftUI中的@Binding

时间:2019-06-07 06:21:23

标签: swift swiftui

我观看了一些有关数据绑定的WWDC视频和Apple文档,根据我目前的理解,@ State作为属性委托,将在视图和带注释的属性之间提供绑定连接,例如:

@State var myText: String

var body: some View {
  VStack {
    TextField($myText, placeholder: Text("input"))
    Text(myText)
  }
}

这会将 myTest 与我添加的文本字段的内容绑定在一起(即一项更改,另一项将跟进更新)

但是,尽管我知道$ myText指的是Binding的绑定类型,但是我注意到Binding也是属性委托,并且我注意到它出现在Apple的一些代码示例中。我不知道这是什么用作属性委托。 @State已经可以进行绑定了,那么我们需要@Binding做什么呢? 苹果文档对此很烂。

5 个答案:

答案 0 :(得分:6)

根据此WWDC演讲(通过Swift UI的数据流):

https://developer.apple.com/wwdc19/226

(!preg_match("~^\p{L}+(?:[-\h']\p{L}+)*$~u", $name)) 应该用于import tkinter import tkinter.ttk import random def startButton(): global my_list, roundNum, tmp_list, startTime grid_size = combobox1.get()[0] roundNum = combobox2.get()[0] gridActorList(my_list) imageUpdate() startTime=time.time() def imageUpdate(): global grid_size t = [] if grid_size == 2: photo_1 = tkinter.PhotoImage(file="picture/"+grid2[0]+".png") photo_2 = tkinter.PhotoImage(file="picture/"+grid2[1]+".png") photo_3 = tkinter.PhotoImage(file="picture/"+grid2[2]+".png") photo_4 = tkinter.PhotoImage(file="picture/"+grid2[3]+".png") for k in range(1,5): t.append(tkinter.Button(window, image=photo_+str(k))) for i in range(0,4): t[i].pack() window = tkinter.Tk() window.title('Finding different picture!') window.geometry('500x400') #combobox values1=[str(i)+"x"+str(i) for i in range(2,6)] #grid size values2=[str(j)+"times" for j in range(1,10,2)] #play time size combobox1=tkinter.ttk.Combobox(window, height=5, width=15, values=values1, justify='center', takefocus=True ) combobox2=tkinter.ttk.Combobox(window, height=5, width=15, values=values2, justify='center', takefocus=True ) combobox1.set("select size") combobox2.set("select times") combobox1.place(x=15, y=15) combobox2.place(x=155, y=15) #startButton startBtn = tkinter.Button(window, text='start', command=startButton) startBtn.place(x=300, y=15) #variables my_list = [] roundNnum = 0 window.mainloop() 内部的本地/私有更改。理想情况下,它们将是私有的。

当值位于当前视图域的@State时,应在子视图/可重用组件中使用

View

您可以在@Binding API中看到它。

其中可能有许多状态,它们告诉outside如何显示它们-但是决定是否显示它取决于超级视图,因此presentation(:_)({{ 1}}),您需要提供。

答案 1 :(得分:3)

@State只是另一个@propertyWrapper,概述了真理之源

“ ......当您使用状态时,框架会为变量分配持久性存储并将其作为依赖项进行跟踪...您始终必须指定初始常量值”-WWDC19 Session 226(07:41)

@Binding绑定另一个明确依赖状态的@propertyWrapper。

“ ......通过使用Binding属性包装器,您可以定义对真相源的显式依赖关系,而无需拥有它,此外,您无需指定初始值,因为可以从状态派生绑定。 -WWDC19 Session 226(13:01)

enter image description here -WWDC19 Session 226

答案 2 :(得分:1)

  

@State已经完成了绑定工作,那么我们需要@Binding用于什么

@State并不是您自己创建的绑定。它具有{docs)的public var binding: Binding<Value>属性:

  

使用绑定在视图及其基础模型之间创建双向连接。

(在您的情况下,在StringTextField之间)

因此,binding表示来回绑定值,而@State则用于读取和修改值会在binding上提供{它存储的价值。

答案 3 :(得分:1)

Binding<T>@Binding的属性委托。

$ myText给您一个Binding<String>

您所描述的@State“进行绑定工作”的方式是为您提供一个Binding<String>的初始化,该初始化使用捕获State<T>实例的引用的getter / setter进行初始化。

现在TextField通过调用传递绑定的setter来改变myText的值,后者又调用了State<T>的setter,该setter实际设置了myText。

如您所见,绑定不需要具有实际的存储属性,它可以委托具有存储功能的其他实例,在这种情况下为@State。因此得名。

答案 4 :(得分:0)

  • 如果您需要一个属于单个视图的简单属性,则可以 应该使用 @State
  • 如果您需要具有可能会 属于几个视图(例如2-3个视图),则应使用 @ObjectBinding
  • 最后,如果您需要拥有需要全方位使用的属性 您应该使用 @EnvironmentObject的视图。