SwiftUI - @State 与 @Binding

cx6n0qe3  于 2022-10-31  发布在  Swift
关注(0)|答案(8)|浏览(377)

我正在用Swift和SwiftUI学习iOS编程,我知道的很少,我对一个@State和一个@Binding的区别非常困惑。
如果我没理解错的话,@Binding只是技术上的@State,但它并不更新视图。如果是这样的话,那么如果我可以使用@State来做同样的事情,为什么还要使用@Binding呢?

ivqmmu1c

ivqmmu1c1#

@State@Binding都是属性 Package 函数。

@国家

  • 它用于每次更新变量的值。
  • 我们也可以说它是一个双向绑定。
  • 如果我们更改属性状态,SwiftUI将自动重新加载视图的主体。
  • 它用于字符串、整数和布尔值等简单属性。
    @Binding
  • 您可以使用这个属性来存取另一个检视的state属性。
  • 它将为您提供变量的读写访问权限。
puruo6ea

puruo6ea2#

SwiftUI是一个声明性的面向组件的框架。你必须忘记MVC,在MVC中,你有控制器在视图和模型之间进行中介。SwiftUI使用区分算法来理解变化,并只更新相应的视图。

@州

  • State属性连接到视图。State属性由视图永久读取。这意味着每次@State属性更改/更新时,视图都会重新呈现,并最终根据@State的数据显示内容。
  • 状态只能由特定视图访问。
  • 字符串、整数和布尔值等简单属性属于单个视图-标记为私有。
  • 所有标记为State的字段都存储在专门的独立存储器中,只有对应的视图才能访问和更新它们。
    @Binding
  • BindableObject协议,它需要一个didChange属性。它可以在环境中使用该属性,并在它更改时立即重新生成视图。
  • didChange属性应该是一个发布者,它是新的Apple Reactive框架合并的一部分。
  • 发布者的主要目标是在发生变化时通知所有订阅者。一旦新值出现,SwiftUI将重建视图。
    @环境对象
  • 它是称为环境的功能的一部分。您可以使用所有需要的服务类填充环境,然后从该环境中的任何视图访问它们。
  • @EnvironmentObject可供环境内的每个视图访问。
  • @在其他位置创建的EnvironmentObject属性,如共享数据。如果缺少该属性,应用程序将崩溃。
  • 环境是SwiftUI依赖注入的正确方式。
pu3pd22g

pu3pd22g3#

State视为视图的唯一真实来源,作为一种改变变量并使视图无效以反映该状态的方法。
另一方面,Bindinga two-way connection between a view and its underlying model。一种改变不受视图管理的State的方法(例如,Toggle反映和控制一个bool值,而控件本身不知道该值的存储或来源)
最后,您可以使用$前置运算子,从任何State取得Binding
在这两种方法中进行选择的简单指南如下:
我是否需要修改我的私有值?=〉状态
我需要修改其他视图的状态吗?=〉Binding

k2fxgqgv

k2fxgqgv4#

州/省

  • @State关键字允许我们要求SwiftUI监控属性的值。一旦值发生变化,View将失效,并以有效的方式再次呈现。
  • 给定类型的持久值,视图通过它读取和监视该值。
  • 它只是另一个@propertyWrapper,概述了真理的来源。
  • 当您使用状态时,框架会为变量分配持久性存储,并将其作为依赖项进行跟踪...您始终必须指定一个初始常量值
    绑定
  • @Binding$-前缀允许将State属性传递到嵌套子级中。
  • 值的管理员,可提供变更值的方式。
  • @Binding又一个显式依赖于状态的@propertyWrapper
  • 通过使用Binding属性 Package 器,您可以定义一个对事实源的显式依赖,而无需拥有它,此外,您不需要指定初始值,因为绑定可以从状态派生。

供您参考的链接:Medium

fnvucqvd

fnvucqvd5#

关于 @State 和 @Binding

假设您有两个SwiftUI视图。在第一个视图中,您声明了一个count变量,在第二个视图中,您创建了一个Tap Me按钮。当单击该按钮时,第一个视图中count的值将被更新。要实现此逻辑,在第一个视图中需要一个@State属性 Package 器,在第二个视图中需要一个@Binding属性 Package 器。
x1M5 N1 X允许本地操作x1M6 N1 X少量数据。x1M7 N1 X直接创建和管理值,所以它是Source of Truth@Binding也引用value type的数据,但是由不同的视图拥有。@Binding不是事实的来源。为了将@State属性提供给Binding<T>,您需要使用$操作符(即,它看起来像$count)。@Binding在属性和另一个视图之间创建双向连接。
下面是代码:

import SwiftUI

struct FirstView: View {

    @State private var count: Int = 0

    var body: some View {
        ZStack {
            Color.black.ignoresSafeArea()
            VStack {
                SecondView(counter: $count).frame(width: 300, height: 100)
                Text("Tapped \(count) times").foregroundColor(.white)
            }
        }
    }
}

struct SecondView: View {

    @Binding var counter: Int

    var body: some View {
        ZStack {
            Color.yellow
            Text("Tap Me").onTapGesture { counter += 1 }
        }
    }
}

除了前面提到的属性 Package 器之外,还可以借助所谓的“Trinity”工具包--@StateObject@Published@ObservedObject--来实现类似的结果。

属性 Package 函数

下面的透视表表示17个常用SwiftUI 4.0属性 Package 器的三个主要特征(事实来源、用途和语义)。
| 编号|属性 Package 函数|真理之源|这是干什么用的?|语义学|
| - -|- -|- -|- -|- -|
| 01年|@应用程序存储|是的|从用户默认值读取/写入|价值|
| 二| @Binding |不可以|创建双向连接|价值|
| 03年|@环境|不可以|从系统读取数据|价值|
| 04年|@环境对象|不可以|从多个视图中读取共享对象|参考文献|
| 05年|@获取请求|是的|将其用于CoreData提取请求|价值|
| 06年|@焦点绑定|不可以|监视键视图中的值|价值|
| 07年|@焦点值|不可以|@FocusedBinding的简单版本|价值|
| 08年|@手势状态|是的|存储活动手势的值|价值|
| 09年|@命名空间|是的|命名空间允许改进代码结构|价值|
| 10个|@观察对象|不可以|引用符合ObservableObject的外部类的示例|参考文献|
| 十一|@已发布|是的|附加到ObservableObject内的属性|价值|
| 十二个|@缩放度量|是的|读取用户的动态类型设置|价值|
| 十三个|@场景存储|是的|还原系统状态的轻量数据|价值|
| 十四| @State |是的|在本地操作视图的数据|价值|
| 十五个| @State 对象|是的|存储符合ObservableObject的新示例|参考文献|
| 十六岁|@ NS应用程序委派配接器|是的|创建AppKit应用程序委托|协议书|
| 十七岁|@ UI应用程序委派配接器|是的|创建UIKit应用程序委托|协议书|

如何...

下面的示例说明如何使用四个常用的属性 Package 。

  • @已发布+ @已观察对象
  • @应用程序存储
  • @ NS应用程序委派配接器
68de4m5k

68de4m5k6#

我想提供一个 * 非常简短 * 的“实际使用”解释,这有助于我澄清它。我不是在定义状态/绑定,我只是指出最大的区别。

@State拥有价值,即“真理之源”

@Binding传递值,用作管道。

关于**@State**,有一件重要的事情:更改将触发重绘。更改**@State**的值将导致整个视图“重新执行”。

px9o7tmv

px9o7tmv7#

这是我为自己准备的笔记,

@州:

  • 我们需要在视图结构体中使用它
  • 建议将设为 private
  • 我们应该 * 提供默认 * 值
  • 可用作装订
  • 这意味着存储简单类型,如 StringIntBool 等。
    @Binding :
  • 这用于在视图之间共享公共数据
  • 最好的例子是,从视图1显示一张图纸,并从视图2启动关闭操作
    • 不需要默认值 * 因为将从另一个视图设置它

谢谢你!

wribegjk

wribegjk8#

State字符串、整数和布尔值等简单属性属于单个视图-标记为私有
绑定类似自定义类型的复杂属性在多个视图中共享数据。引用类型必需
EnvironmentObject在其他地方创建的属性,如共享数据,如果缺少该属性,应用程序将崩溃。

相关问题