簡體   English   中英

深度鏈接 onChange 未在 SwiftUI 工作表中觸發

[英]Deep link onChange not triggered in SwiftUI sheet

我的 SwiftUI 應用程序中的深層鏈接存在問題。

在我的應用程序 class 中,我已將 deepLink 聲明為層次結構中 ContentView() 下每個視圖的環境變量:

...

@main
struct TestApp: App {

var userSettings: UserSettings
var dataFetcher: DataFetcher
var dataUpdater: DataUpdater

@State var deepLink = ""

init() {
    userSettings = UserSettings()
    dataFetcher = DataFetcher(userSettings: userSettings)
    dataUpdater = DataUpdater(userSettings: userSettings)
}

var body: some Scene {
    WindowGroup {
        ContentView()
                .environmentObject(userSettings)
                .environmentObject(dataFetcher)
                .environmentObject(dataUpdater)
                .onOpenURL { url in
                    deepLink = url.absoluteString
                }
                .environment(\.deepLink, deepLink)
    }
}

}

在我的 ContentView() 中,我已將 deepLink 聲明為環境變量

struct ContentView: View {

    ...

    @State var isTestSheetViewPresented = false

    @Environment(\.deepLink) var deepLink: String

    ...

    var body: some View {

        Button(action: {
            self.isTestSheetViewPresented = true
        }, label: {
            HStack {
                Spacer()
                Image(systemName: "plus")
                Text("Add")
                Spacer()
            }
        })
        .sheet(isPresented: $isTestSheetViewPresented, content: {
            TestSheetView(isPresented: self.$isTestSheetViewPresented)
        })
        .onChange(of: self.deepLink) { _ in
            self.isTestSheetViewPresented = true
        }
    }

}

而 TestSheetView 是這樣的

struct TestSheetView: View {

    @Environment(\.deepLink) var deepLink: String

    @State var url: String = ""

    var body: some View {
        Text(url)
            .onChange(of: deepLink) { _ in
                if deepLink != "" {
                    self.url = deepLink
                }
            }
    }

}

問題是,當我單擊一個鏈接並打開我的應用程序時,正確顯示了 TestSheetView 但不會觸發 onChange,除非我向下滾動一點。

相反,如果我將 TestSheetView 的相同代碼放在 ContentView 中,那么文本就會正確顯示

似乎是一個時間問題。 在初始化TestSheetView時,正文是在deepLink更改創建的,因此無法檢測到它。

解決方案是在TestSheetView onAppear從那里讀取,如下所示:

struct TestSheetView: View {

    @Environment(\.deepLink) var deepLink: String

    @State var url: String = ""

    var body: some View {
        Text(url)
            .onAppear {
                if deepLink != "" {
                    self.url = deepLink
                }
            }
    }
}

處理視圖尚未出現的情況以及在視圖中導航鏈接的情況都是不符合人體工程學的。 以下視圖修飾符處理這兩種情況。 它假定頂層導航視圖中有一個 .onOpenURL() 處理程序,該處理程序設置當前選項卡選擇以及 currentDeepLink 環境值。

struct DeepLinkViewModifier: ViewModifier {
    @Environment(\.currentDeepLink) private var currentDeepLink
    let action: ((URL) -> Bool)

    func body(content: Content) -> some View {
        content
            .onAppear {
                if let url = currentDeepLink.wrappedValue,
                    action(url) {
                    currentDeepLink.wrappedValue = nil
                }
            }
            .onOpenURL { url in
                _ = action(url)
            }
    }
}

extension View {
    func onDeepLink(perform action: @escaping ((URL) -> Bool)) -> some View {
        return self.modifier(DeepLinkViewModifier(action: action))
    }
}

采用:

struct SomeView: View {
    @State urlString: String = ""

    var body: some View {
        Text(urlString).onDeepLink { url
            self.string = url.absoluteString
            return true // return false if another handler should consume
        }
    }
}

struct ContentView: View {
    @State private var tabSelection: TabSelection = .something
    @State private var currentDeepLink: URL? = nil

    var body: some View {
        TabView(selection: self.$tabSelection) {
        ...
        }
        .onOpenURL { url in
             self.tabSelection = ... // determine selection from URL
             self.currentDeepLink = url
        }
        .environment(\.tabSelection, self.$tabSelection)
        .environment(\.currentDeepLink, self.$currentDeepLink)
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM