Как открыть определенный вид с помощью быстрых действий домой

Я новичок в Swift и использую SwiftUI, а не Storyboard.

Я установил UIApplicationShortcutItems в Info.plist и имею два быстрых действия, которые могут выдавать предупреждение с помощью launchOptions.

Я могу отключить быстрые действия в SceneDelegate.swift

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    switch shortcutItem.type {
    case "QuickAction1":
        OneView() // What do I do to open this SwiftUI struct View?
        break
    case "QuickAction2":
        SecondView() // What do I do to open this SwiftUI struct View?
        break
    default:
        break
    }
}

Как правильно открыть конкретный вид из домашнего быстрого действия с помощью SwiftUI?


ContentView.swift

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: OneView())
                NavigationLink(destination: TwoView())
            }
        }
    }
}

person user1909186    schedule 10.01.2020    source источник


Ответы (1)


Вот возможный поэтапный подход (протестирован с Xcode 11.2 / iOS 13.2)

1) Добавьте класс AppSettings для хранения режима представлений, которые будут представлены ярлыком

class AppSettings: ObservableObject {
    enum Mode {
        case one
        case two
    }
    @Published var mode: Mode? = nil
}

2) сделать appSettings членом делегата сцены для доступа к нему и в ContentView и в делегате ярлыка и передать его в ContentView как объект среды

let appSettings = AppSettings()

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    let contentView = ContentView().environmentObject(appSettings)
    // ...

3) активируйте соответствующий режим в ярлыке делегата сцены

func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
    switch shortcutItem.type {
    case "QuickAction1":
        appSettings.mode = .one
        break
    case "QuickAction2":
        appSettings.mode = .two
        break
    default:
        break
    }
}

4) Сделать ContentView условно отображать ссылки в зависимости от выбранного режима быстрого доступа

struct ContentView: View {
    @EnvironmentObject var appSettings: AppSettings

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: OneView(),
                               tag: AppSettings.Mode.one,
                               selection: $appSettings.mode)
                    { Text("To One") }
                NavigationLink(destination: TwoView(),
                                tag: AppSettings.Mode.two,
                                selection: $appSettings.mode)
                    { Text("To Two") }
            }
        }
    }
}
person Asperi    schedule 11.01.2020
comment
Работает как часы! Я не был уверен, почему у вас есть appDelegate на шаге 2, поэтому я пока пропустил константу. Не могли бы вы объяснить причину обращения? В любом случае оцените обстоятельный ответ. - person user1909186; 16.01.2020
comment
Удаленный. appDelegate был для другого теста)) - person Asperi; 16.01.2020
comment
У меня похожий вопрос. У меня есть только один ярлык, который должен открывать представление, к которому в противном случае можно было бы перейти, нажав NavigationLink. Когда представление открывается с помощью элемента ярлыка, я хочу, чтобы у него была кнопка «Назад» с заголовком предыдущего представления в иерархии навигации. - person Dave F; 08.05.2020
comment
Вы всегда даете отличные объяснения. Вопрос: Почему на шаге 3 у вас нет completionHandler(true) для 2 случаев и false для значения по умолчанию? - person David; 02.05.2021