Протокол Swift и метод, возвращающий "some View" - PullRequest
2 голосов
/ 03 августа 2020

Итак, протокол не поддерживает some View в качестве возвращаемого типа ... Я пробую это:

public extension View {
    func popSheet(isPresented: Binding<Bool>, arrowEdge: Edge = .bottom, content: @escaping () -> PopSheet) -> some View {
        Group {
            if UIDevice.current.userInterfaceIdiom == .pad {
                popover(isPresented: isPresented, attachmentAnchor: .rect(.bounds), arrowEdge: arrowEdge, content: {
                    content().popover()
                })
            } else {
                actionSheet(isPresented: isPresented, content: {
                    content().actionSheet()
                })
            }
        }
    }
}

protocol PopSheet {
    func actionSheet() -> ActionSheet
    associatedtype View
    func popover() -> View
}

Но не удается полностью объявить функцию, а также ошибки content().popover().

Method must be declared internal because its parameter uses an internal type

Protocol 'PopSheet' can only be used as a generic constraint because it has Self or associated type requirements

Member 'popover' cannot be used on value of protocol type 'PopSheet'; use a generic constraint instead

Ответы [ 2 ]

1 голос
/ 03 августа 2020

Здесь нет ничего принципиально неправильного. Всего несколько мелких ошибок.

Во-первых, ваш View связанный тип не имеет ничего общего с SwiftUI.View. Просто у него такое же имя. Вероятно, вы имели в виду следующее:

public protocol PopSheet {
    associatedtype V: View   // Create a new type that conforms to View
    func actionSheet() -> ActionSheet
    func popover() -> V
}

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

func popSheet<Sheet: PopSheet>(isPresented: Binding<Bool>, 
                               arrowEdge: Edge = .bottom, 
                               content: @escaping () -> Sheet) -> some View {

С этим ваша реализация должна быть в порядке.

0 голосов
/ 03 августа 2020

Для проблемы use a generic constraint instead причина:

...

Это то, что происходит, когда мы пытаемся напрямую сослаться на общий протокол c - это то есть протокол, который либо имеет связанные типы, либо требует, чтобы был известен соответствующий тип (на который ссылается Self). Например, встроенный протокол Equatable использует Self в своем объявлении

...

Вы можете найти подробное объяснение в этом отличном сообщении в блоге .

Отличный день и удачного кодирования!

...