首页 > 解决方案 > SwiftUI 中的自定义事件修饰符

问题描述

我创建了一个自定义按钮,显示一个弹出框。这是我的代码:

弹出选择器

struct PopupPicker: View {

    @State var selectedRow: UUID?
    @State private var showPopover = false
    let elements: [PopupElement]

    var body: some View {
        Button((selectedRow != nil) ? (elements.first { $0.id == selectedRow! }!.text) : elements[0].text) {
            self.showPopover = true
        }
        .popover(isPresented: self.$showPopover) {
            PopupSelectionView(elements: self.elements, selectedRow: self.$selectedRow)
        }
    }
}

弹出选择视图

struct PopupSelectionView: View {

    var elements: [PopupElement]
    @Binding var selectedRow: UUID?

    var body: some View {
        List {
            ForEach(self.elements) { element in
                PopupText(element: element, selectedRow: self.$selectedRow)
            }
        }
    }

}

弹出文本

struct PopupText: View {

    var element: PopupElement
    @Binding var selectedRow: UUID?

    var body: some View {
        Button(element.text) {
            self.presentation.wrappedValue.dismiss()
            self.selectedRow = self.element.id
        }
    }
}

这很好,但我可以创建一个自定义事件修饰符,以便我可以编写:

PopupPicker(...)
    .onSelection { popupElement in
        ...
    }

标签: swiftui

解决方案


我无法为您提供完整的解决方案,因为我没有您的所有代码以及您获取所选项目的方法,但是我知道从哪里开始。

事实证明,使用以下语法声明一个函数:

func `onSelection`'(arg:type) {
...
}

创建.onSelection类似这样的功能:

struct PopupPicker: View {
    @Binding var selectedRow: PopupElement?
    var body: some View {
        ...
    }

func `onSelection`(task: (_ selectedRow: PopupElement) -> Void) -> some View {
        print("on")
        if self.selectedRow != nil {
            task(selectedRow.self as! PopupElement)
        return AnyView(self)
    }
        return AnyView(self)
    }

}

理论上,您可以在这样的视图中使用它:

struct ContentView: View {
    @State var popupEl:PopupElement?
    var body: some View {
        PopupPicker(selectedRow: $popupEl)
            .onSelection { element in
                print(element.name)
        }
        
    }
}

但是我无法正确测试它,请评论您的发现

希望这可以让您对它的工作原理有所了解,对不起,如果我不能给出完整的解决方案


推荐阅读