如何在SwiftUI中实现自定义回调动作?类似于onAppear功能

piztneat  于 2023-09-30  发布在  Swift
关注(0)|答案(2)|浏览(142)

我自定义了ActionView,有两个按钮:汽车自行车。当点击这些按钮时,我需要在MainView修改器onCarTap/onBikeTap中触发。
在我目前的实现中,这里是错误的:

  • 传递给不带参数的调用的参数
  • 元组类型“Void”的值没有成员“onBikeTap”

原始程式码:

struct ActionView: View {
    // Callback for button taps
    var onCarTap: (() -> Void)?
    var onBikeTap: (() -> Void)?
    
    var body: some View {
        HStack {
            Button(action: {
                onCarTap?()
            }, label: {
                Text("Car")
            })
            Button(action: {
                onBikeTap?()
            }, label: {
                Text("Bike")
            })
        }
    }
}

我正在寻找这样的解决方案:

struct MainView: View {
    var body: some View {
        ActionView()
            .onCarTap({})
            .onBikeTap({ })
    }
}

可以以这种方式实现:

ActionView(onCarTap: {
        print("on car tap")
    }, onBikeTap: {
        print("on bike tap")
    })
tcbh2hod

tcbh2hod1#

您可以像下面这样为您的目的声明一个修饰符。

extension ActionView {
    func onCarTap(_ handler: @escaping () -> Void) -> ActionView {
        var new = self
        new.onCarTap = handler
        return new
    }
}

此外,如果您希望使用privatefileprivate隐藏处理程序属性以防止直接访问它,则必须声明一个指定的init,该init接受其属性的参数,但处理程序的参数除外。

wj8zmpe1

wj8zmpe12#

假设您有以下视图:

struct ActionView: View {
    var onCarTapAction: (() -> Void)?
    var onBikeTapAction: (() -> Void)?

    var body: some View {
        HStack {
            Button(action: {
                onCarTapAction?()
            }, label: {
                Text("Car")
            })
            Button(action: {
                onBikeTapAction?()
            }, label: {
                Text("Bike")
            })
        }
    }
}

您可以创建一个扩展:

extension ActionView {
    func onCarTap(action: @escaping (() -> Void)) -> ActionView {
        ActionView(onCarTapAction: action, onBikeTapAction: onBikeTapAction)
    }

    func onBikeTap(action: @escaping (() -> Void)) -> ActionView {
        ActionView(onCarTapAction: onCarTapAction, onBikeTapAction: action)
    }
}

这样使用:

struct ContentView: View {
    var body: some View {
        ActionView()
            .onCarTap {
                print("onCarTap")
            }
            .onBikeTap {
                print("onBikeTap")
            }
    }
}

相关问题