SwiftUI在Form/Sheet中有多个NavigationLinks-条目保持突出显示 [英] SwiftUI multiple NavigationLinks in Form/Sheet - entry stays highlighted

查看:67
本文介绍了SwiftUI在Form/Sheet中有多个NavigationLinks-条目保持突出显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Xcode 12/iOS 14时遇到问题.在具有NavigationView的工作表中使用多个NavigationLinks会导致NavigationLink条目在返回页面后仍保持突出显示状态.这不仅是模拟器的问题.请参阅随附的GIF:

I have an issue with Xcode 12 / iOS 14. Using multiple NavigationLinks in a sheet with NavigationView leads to NavigationLink entries staying highlighted after going back a page. This is not only a problem with the simulator. See the attached GIF:

有人知道如何解决此问题吗?

Does anybody know how to fix this?

类似的问题: SwiftUI-NavigationLink单元(但是这不是问题)在表单中保持突出显示状态.

Similar question: SwiftUI - NavigationLink cell in a Form stays highlighted after detail pop (but that's not the problem here).

struct ContentView: View {
    
    var body: some View {
        Text("")
            .sheet(isPresented: .constant(true), content: {
                NavigationView {
                    Form {
                        Section {
                            NavigationLink("Link to ViewB", destination: ViewB())
                        }
                    }
                    .navigationBarTitle("ViewA")
                }
            }) 
    }
}

struct ViewB: View {
    @State var selection = 0
    let screenOptions = ["a", "b", "c"]
    var body: some View{
        Form {
            Section {
                NavigationLink("Link to ViewC", destination: ViewC())
            }
        }
        .navigationBarTitle("ViewB")
    }
}

struct ViewC: View {
    var body: some View{
        Form {
            Section {
                Text("Test")
            }
        }
        .navigationBarTitle("ViewC")
    }
}

推荐答案

在工作表中使用 NavigationLink 时,我也遇到了这个问题.我在iOS 14上的解决方案太麻烦了 UITableView didSelectRowAt:.选择该行后,我将其取消选择.还有更多代码可以检测其是否在工作表中,等等,但这是基本的工作代码:

I've also run into this problem when using a NavigationLink inside a sheet. My solution on iOS 14 has been too Swizzle didSelectRowAt: of UITableView. When the row is selected, I deselect it. There is more code for detecting if its in a sheet, etc, but this is the basic, get it working code:

extension UITableView {
    
    @objc static func swizzleTableView() {
        
        guard self == UITableView.self else {
            return
        }
        
        let originalTableViewDelegateSelector = #selector(setter: self.delegate)
        let swizzledTableViewDelegateSelector = #selector(self.nsh_set(delegate:))
        
        let originalTableViewMethod = class_getInstanceMethod(self, originalTableViewDelegateSelector)
        let swizzledTableViewMethod = class_getInstanceMethod(self, swizzledTableViewDelegateSelector)
        
        method_exchangeImplementations(originalTableViewMethod!,
                                       swizzledTableViewMethod!)
    }
    
    @objc open func nsh_set(delegate: UITableViewDelegate?) {
        nsh_set(delegate: delegate)
        
        guard let delegate =  delegate else { return }
        
        let originalDidSelectSelector = #selector(delegate.tableView(_:didSelectRowAt:))
        let swizzleDidSelectSelector = #selector(self.tableView(_:didSelectRowAt:))
        
        let swizzleMethod = class_getInstanceMethod(UITableView.self, swizzleDidSelectSelector)
        let didAddMethod = class_addMethod(type(of: delegate), swizzleDidSelectSelector, method_getImplementation(swizzleMethod!), method_getTypeEncoding(swizzleMethod!))
        
        if didAddMethod {
            let didSelectOriginalMethod = class_getInstanceMethod(type(of: delegate), NSSelectorFromString("tableView:didSelectRowAt:"))
            let didSelectSwizzledMethod = class_getInstanceMethod(type(of: delegate), originalDidSelectSelector)
            if didSelectOriginalMethod != nil && didSelectSwizzledMethod != nil {
                method_exchangeImplementations(didSelectOriginalMethod!, didSelectSwizzledMethod!)
            }
        }
    }
    
    @objc open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.tableView(tableView, didSelectRowAt: indexPath)

        // This is specifically to fix a bug in SwiftUI, where a NavigationLink is
        // not de-selecting itself inside a sheet.
        tableView.deselectRow(at: indexPath,
                              animated: true)
        
    }
}

(原始的混乱代码来自 https://stackoverflow.com/a/59262109/127853 ),此代码该示例只是添加了 deselectRow 调用.)

(Original swizzle code is from https://stackoverflow.com/a/59262109/127853), this code sample just adds the deselectRow call.)

别忘了在 application:didFinishLaunchingWithOptions:

这篇关于SwiftUI在Form/Sheet中有多个NavigationLinks-条目保持突出显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆