Я хочу предоставить функции из моей структуры, которая соответствует протоколу просмотра, таким образом, чтобы пользователь структуры мог связать вызовы функций.

Ниже то, что я написал

struct MyResuableView: View {
    var event1Callback: () -> Void = {}
    var event2Callback: () -> Void = {}
    
    var body: some View {
        Text("Resuable View")
    }
    
    mutating func onEvent1(action: @escaping () -> Void) -> Self {
        self.event1Callback = action
        return self
    }

    mutating func onEvent2(action: @escaping () -> Void) -> Self {
        self.event2Callback = action
        return self
    }
}

Вот как я собираюсь его использовать

struct MyView: View {
    var body: some View {
        VStack {
            Text("My View")
            MyResuableView()
                .onEvent1(action: self.event1Handler)
                .onEvent2(action: self.event2Handler)
        }
    }
    
    private func event1Handler() {
        
    }
    
    private func event2Handler() {
        
    }
}

Я получаю ошибку компиляции ниже < sizesCannot use mutating member on immutable value: function call returns immutable value, что понятно.

enter image description here

Я просмотрел поток обратный вызов SwiftUI как параметр представления. Это один из способов добиться, но как предоставить такие функции, как onEvent1 (....), onEvent2 (....), чтобы принимать функции в качестве входных данных от вызывающего.

Так что мне просто любопытно узнать, что мне нужно (если мы можем), чтобы достичь того, что я ищу?

1
Ishwar Jindal 3 Сен 2020 в 14:33

2 ответа

Лучший ответ

Вот возможный подход (вспоминая, что View - это просто значение) ...

struct MyResuableView: View {
    var event1Callback: () -> Void = {}
    var event2Callback: () -> Void = {}
    
    var body: some View {
        Text("Resuable View")
    }
    
    func onEvent1(action: @escaping () -> Void) -> Self {
        var newOne = self
        newOne.event1Callback = action
        return newOne
    }

    func onEvent2(action: @escaping () -> Void) -> Self {
        var newOne = self
        newOne.event2Callback = action
        return newOne
    }
}
0
Asperi 3 Сен 2020 в 11:52

Вы можете структурировать его так, как работают модификаторы представления. Каждый раз возвращайте новое представление:

struct MyReusableView: View {
    let event1Callback: () -> Void
    let event2Callback: () -> Void
    
    init(event1Callback: @escaping () -> Void = {}, event2Callback: @escaping () -> Void = {})
    {
        self.event1Callback = event1Callback
        self.event2Callback = event2Callback
    }
    
    var body: some View {
        Text("Reusable View")
    }
    
    func onEvent1(action: @escaping () -> Void) -> Self {
        .init(event1Callback: action, event2Callback: self.event2Callback)
    }

    func onEvent2(action: @escaping () -> Void) -> Self {
        .init(event1Callback: self.event1Callback, event2Callback: action)
    }
}
0
vacawama 3 Сен 2020 в 12:00