Вернуть вид из замыкания в SwiftUI - PullRequest
0 голосов
/ 02 марта 2020

У меня есть общий компонент вида c, который нужно инициализировать, чтобы он возвращал некоторое представление для редактирования раздела и другое для добавления элементов в раздел.

import SwiftUI

enum ProfileSectionType {
    case editable
    case addable
}

struct ProfileSection<Content> : View where Content : View {

    var model:ProfileSectionModel? = nil
    var sectionType:ProfileSectionType = .editable
    var onClick:(() -> View)? = nil
    var content: Content

    @inlinable public init(_ model:ProfileSectionModel? = nil, sectionType:ProfileSectionType = .editable, @ViewBuilder content: () -> Content) {
        self.model = model
        self.content = content()
        self.sectionType = sectionType
    }

    var body : some View {
        switch sectionType {
        case .editable:
            return AnyView(editable())
        case .addable:
            return AnyView(addable())
        }
    }
}

Но использовать закрытие, как (() -> View), невозможно. Я мог бы передать его в качестве параметра для init, но тогда я бы не стал лениво загружать представление.

Я также пытался использовать generi c в перечислении. Моей первой попыткой было что-то вроде:

enum ProfileSectionType<T : View> {
    case editable
    case addable(viewForAdding:T)
}

Но это, казалось, усложняло ситуацию. Как заставить этот раздел создавать два разных представления для редактирования и добавления?

Я хочу использовать это так:

ProfileSection(m.identifications(), sectionType: .addable, onClick: ^{
    AddIdentificationView()
}){
    ForEach( 0 ..< m.identifiers().count ) {
        ProfileEditableItem(key: m.identifiers()[$0].title, value: m.identifiers()[$0].value)
    }
}

1 Ответ

0 голосов
/ 04 марта 2020

Я решил это, установив:

struct ProfileSection<Content, T> : View where Content : View, T : View {

    var model:ProfileSectionModel? = nil
    var sectionType:ProfileSectionType = .editable
    var onClickAdd:(() -> T)? = nil
    var content: Content

Затем я могу использовать его следующим образом:

ProfileSection<ForEach, AddIdentificationView>(m.identifications(), sectionType: .addable, editDialog: {
    AddIdentificationView()
}){
    ForEach( 0 ..< m.identifiers().count ) {
        ProfileEditableItem(key: m.identifiers()[$0].title, value: m.identifiers()[$0].value)
    }
}

Затем AddIdentificationView представляется в модальном представлении. Было бы чище, если бы я избавился от <ForEach, но пока подойдет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...