自反闭包 传递闭包_在swiftui兄弟视图和uiviewrepresentables之间传递闭包

自反闭包 传递闭包

Let’s take the following scenario: You have a ParentView with two child views, ChildView1 and ChildView2. On ChildView1, you have a button that should trigger an action in ChildView2.

让我们采取以下情形:您有一个带两个子视图的ParentViewChildView1ChildView2 。 在ChildView1 ,您具有一个按钮,该按钮应触发ChildView2的操作。

Now on that button tap, we want to change the text on that text field to something more appropriate. Let’s start by defining a typealias for our closure. If you don’t know what a closure is, it’s basically a method. You can read more about closures in the documentation.

现在点击该按钮,我们想将该文本字段上的文本更改为更合适的文本。 让我们开始为闭包定义一个类型别名。 如果您不知道闭包是什么,那么它基本上就是一种方法。 您可以在文档中阅读有关闭包的更多信息。

Let’s add the following typealias above our ParentView declaration:

让我们在ParentView声明上方添加以下类型ParentView

typealias OnClickHandler = (() -> Void)

So it becomes:

这样就变成了:

typealias OnClickHandler = (() -> Void)
struct ParentView: View {
...
}

And initialise it as an @State property in our ParentView:

并将其初始化为我们的ParentView@State属性:

struct ParentView: View {
@State var onClick: OnClickHandler = { }
...}

The idea here is that this onClick defined in the ParentView is our single source of truth. We don’t want another closure initialized somewhere along the call stack. We want this one passed to both our ChildViews.

这里的想法是,这onClick中定义的ParentView是我们的单一数据源。 我们不希望在调用堆栈的某处初始化另一个闭包。 我们希望将此传递给两个ChildViews。

In ChildView2, where our button is, we add it as an @Binding, as it’s already initialized in our ParentView and ChildView2 at this point only manipulates it. Then we add it as the action to our button:

ChildView2 ,我们的按钮位于其中,我们将其添加为@Binding ,因为它已经在ParentViewChildView2进行了初始化,此时只能对其进行操作。 然后,将其作为操作添加到按钮中:

You’ll notice that we deleted the old closure in which we would print our message and just passed ours as a parameter. This is not mandatory, but it’s shorter and cleaner.

您会注意到,我们删除了旧的闭包,在该闭包中将打印消息,并将其作为参数传递给我们。 这不是强制性的,但更短,更干净。

At this point, your ParentView is notifying you that you’re missing your onClick parameter when you’re initializing ChildView2, so let’s just add that:

此时,您的ParentView会通知您在初始化ChildView2时缺少onClick参数,所以我们只需添加一下:

You’ll notice we passed $onClick to ChildView2, as we defined our property as an @Binding, so we use $to pass the binding and not a value.

您会注意到我们通过了$onClick ChildView2 ,因为我们将属性定义为@Binding ,所以我们使用$来传递绑定而不是值。

We’re now going to do the same thing to our ChildView1 — add a binding property — but this time we’re also going to write the function that gets called when the button is tapped, and we’re going to assign that function to our passed closure:

现在,我们将对ChildView1执行相同的ChildView1 -添加一个绑定属性-但这次我们还将编写在点击按钮时调用的函数,并将该函数分配给我们通过的关闭:

The magic here is calling onAppear on the Text element. This means that when that field appears (think of viewDidAppear in UIKit), we are going to run the following code block. In that code block, we assign a function to our onClick closure that modifies the value of our string.

这里的魔法呼唤onAppear 在Text元素上。 这意味着当该字段出现时(考虑UIKit中的viewDidAppear ),我们将运行以下代码块。 在该代码块中,我们为onClick闭包分配了一个函数,该函数可修改字符串的值。

If you want to be fancy or your method is larger, you can even extract the whole code block into a different method and assign that to onClick:

如果您想花哨或您的方法更大,您甚至可以将整个代码块提取到另一个方法中,并将其分配给onClick

Now, through the magic of SwiftUI and Combine, you managed to link two views that have no knowledge of each other. Congratulations!

现在,借助SwiftUI和Combine的魔力,您成功地链接了彼此不了解的两个视图。 恭喜你!

奖金 (Bonus)

“What if I want to do this with a view and UIViewRepresentable where I don’t have onAppear?”

“如果我想有一个观点和UIViewRepresentable在那里我没有做到这一点onAppear ?”

That’s a great question, Alex!

这是一个很好的问题,Alex!

In this case, we will use the function:

在这种情况下,我们将使用以下函数:

You can see that I’ve sent it to a background thread. This is because the compiler will notify us at runtime that “Modifying state during view update, this will cause undefined behavior.”

您可以看到我已将其发送到后台线程。 这是因为编译器将在运行时通知我们“在视图更新期间修改状态,这将导致未定义的行为。”

This is Apple’s way of saying that we’re updating a state while the view is being redrawn.

这是Apple的一种说法,即在重绘视图时我们正在更新状态。

And that’s it. The full code is available on GitHub. Happy coding!

就是这样。 完整代码可在GitHub上获得 。 编码愉快!

翻译自: https://medium.com/better-programming/passing-closures-between-swiftui-sibling-views-and-uiviewrepresentables-1f81a6cf5be6

自反闭包 传递闭包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值