CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

[SwiftUI100天]Bookworm-part1用Binding创建自定义组件-免费源码丞旭猿

译自https://www.hackingwithswift.com/books/ios-swiftui/bookworm-introduction更多内容,欢迎关注公众号 「Swift花园」喜欢文章?不如来个 ➕三连?关注专栏,关注我

Bookworm:介绍

在这个项目中我们要构建一个应用,用于跟踪你读过的书和你对它们的看法,延续 Cupcake Corner 项目的做法:让我们用上你已经掌握的技能,并且增加一些额外奖励的新技能,让你的技能熟练度再上一个台阶。

这一回你将认识 Core Data,它是 Apple 的一个久经战阵的框架,用于处理数据框。这个项目将扮演 Core Data 介绍者的角色,稍后我们会介绍更多细节。

与此同时,我们还将构建我们的第一个自定义组件 —— 一个评价等级的星星 widget,用户可以点击它来为每本书评分。这也意味着,我们将引入一个新的属性包装器,它叫@Binding

如往常一样,我们先速览一遍你将在这个项目中用到的新技术。首先,请创建一个新的 iOS 应用,取名叫 Bookworm,使用 Single View App 项目模板。


译自https://www.hackingwithswift.com/books/ios-swiftui/creating-a-custom-component-with-binding

用 Binding 创建自定义组件

你已经了解 SwiftUI 的@State属性包装器如何同本地值类型协同工作,以及@ObservedObject如何同共享的引用类型协同工作。其实还有第三个选项,叫@Binding, 它能让我们将一个视图的@State属性连接到底层的模型数据。

想想看:当我们创建一个 toggle 开关时,我们像下面这样发送某个可以被改变的布尔属性:

@StateprivatevarrememberMe=falsevarbody:someView{Toggle(isOn:$rememberMe){Text("Remember Me")}}

因此,Toggle需要在用户和它交互时改变我们的布尔值,但它是如何记住自己应该改变成哪个值呢?

这正是@Binding发挥作用的地方:它让我们创建一个在视图中可修改的值,这个值实际指向其他地方的某个值。对于Togglet,开关改变自身对于一个布尔型的本地绑定,而幕后实际上维护一个视图中的@State属性。

这使得@Binding对于任何自定义 UI 组件都至关重要,其中的关键在于 UI 组件就像其他东西一样,只是 SwiftUI 视图,但@Binding使得它们被区分开:它们既可以有本地的@State属性,同时也暴露@Binding属性,以便自己可以和其他视图连接。

为了说明这一点,我们将创建一种新的按钮:这种按钮在按下时保持被按下的视觉效果。基本的实现方式和你之前见到过的一样:一个带填充的按钮,线性渐变的背景,Capsule的裁切形状,等等 —— 把下面的代码添加到 ContentView.swift :

structPushButton:View{lettitle:String@StatevarisOn:BoolvaronColors=[Color.red,Color.yellow]varoffColors=[Color(white:0.6),Color(white:0.4)]varbody:someView{Button(title){self.isOn.toggle()}.padding().background(LinearGradient(gradient:Gradient(colors:isOn?onColors:offColors),startPoint:.top,endPoint:.bottom)).foregroundColor(.white).clipShape(Capsule()).shadow(radius:isOn?0:5)}}

这里我用了属性来控制渐变色,以便我们可以定制按钮的背景。

我们现在可以在主界面中使用刚才创建的按钮,像这样:

structContentView:View{@StateprivatevarrememberMe=falsevarbody:someView{VStack{PushButton(title:"Remember Me",isOn:rememberMe)Text(rememberMe?"On":"Off")}}}

按钮下方有一个文本视图,以便我们追踪按钮状态 —— 尝试运行代码,观察按钮的工作方式。

你将发现,点击按钮确实会影响它的呈现效果,但我们的文本视图并不会反映这个变化 —— 它一直都是 Off。显然,在按钮点击时有改变发生了,因为按钮的外观发生了变化,但这个变化并没有在ContentView中体现。

这里的情况是我们实际上定义了一种单向的数据流:ContentView拥有rememberMe布尔属性,并且被用于创建PushButton—— 这个按钮有一个由ContentView. 提供的初始值。但是,一旦按钮创建,它就接管了那个值:它在按钮内部触发isOn属性在true或者false间变化,但并不会把变化传回ContentView

这是一个问题,因为这样一来我们就有两个 sources of truth:ContentView存储一个值,而PushButton存储另一个。幸运的是,借助@Binding:我们可以在PushButton和任何使用它的东西之间建立双向的连接,以便一边改变,另一边也同步。

为了切换到@Binding,我们只需要做两处改动。首先,在PushButton里,把它的isOn属性改成这样:

@BindingvarisOn:Bool

其次,在ContentView里,修改我们创建按钮的方式,变成下面这样:

PushButton(title:"Remember Me",isOn:$rememberMe)

我们在rememberMe之前加了一个$符号 —— 代表我们传入的是绑定,而不是布尔类型。


我的公众号这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容