SwiftUI: ошибка при использовании if #available при попытке сборки до iOS 13 и iOS 14 в Xcode 12 beta 2 - PullRequest
4 голосов
/ 10 июля 2020

Итак, я пытаюсь сделать так, чтобы мое приложение могло развертываться на iOS 13 (технически я хочу iOS 13.5), а также iOS 14, поэтому я написал эти строки кода на проверьте это:

struct ContentView: View {
    var body: some View {
        if #available(iOS 14.0, *) {
            List {
                Text("Cool!")
                Text("Cool!")
                Text("Cool!")
                Text("Cool!")
            }
            .listStyle(InsetGroupedListStyle())
            
        } else {
            List {
                Text("Cool!")
                Text("Cool!")
                Text("Cool!")
                Text("Cool!")
            }
            .listStyle(GroupedListStyle())
            .environment(\.horizontalSizeClass, .regular)
        }
    }
}

Сборка до iOS 14 отлично работает, однако всякий раз, когда я строю до iOS 13,5 на физическом телефоне и симуляторе, я получаю эту ошибку в AppDelegate:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

Я установил для своей iOS цель развертывания iOS 13.5, и я использую Xcode 12 beta 2. Я пробовал использовать beta 1 с тем же результатом (хотя я использовал тот же файл, так что потенциально вот почему?). Я не уверен, что я делаю что-то не так или это ошибка. При использовании только кода для iOS 13.5 (без if #available) он работает так, как ожидалось, но только когда я добавляю эту проверку, возникают мои проблемы. Любая помощь будет оценена!

Ответы [ 2 ]

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

Эта ошибка должна быть исправлена ​​в Xcode 12 beta 5 и новее. Если это не так, воспользуйтесь Помощником по обратной связи, чтобы сообщить о проблеме.

Для всех, кому интересно, проблема заключалась в том, что, хотя ветвь iOS 14 не использовалась на устройствах iOS 13, типы из представлений, которые могли бы быть созданы этой веткой, все еще обрабатывались SwiftUI, и некоторые из этих типов не существовали в iOS 13. Обходной путь AnyView, предложенный @ pacification работает, потому что он скрывает информацию о типе в ветке iOS 14, так что SwiftUI не обрабатывает ее, если эта ветка не занята. Фактически, Xcode 12 beta 5 в основном исправляет эту ошибку, автоматически помещая ветку if #available в AnyView.

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

К сожалению, я могу воспроизвести эту ошибку в Xcode 12 beta 4, так что здесь обходной путь. Вы можете обернуть код iOS 14 в AnyView, и все будет успешно скомпилировано. В этом конкретном случае вы можете использовать ViewModifier, чтобы код выглядел более быстрым.

struct ContentView: View {
    var body: some View {
        List {
            Text("Cool!")
            Text("Cool!")
        }
        .modifier(GroupedListModifier())
    }
}

struct GroupedListModifier: ViewModifier {
    func body(content: Content) -> some View {
        Group {
            if #available(iOS 14, *) {
                AnyView(
                    content
                        .listStyle(InsetGroupedListStyle())
                )
            } else {
                content
                    .listStyle(GroupedListStyle())
                    .environment(\.horizontalSizeClass, .regular)
            }
        }
    }
}
...