带有 WKWebView 的模态在文本字段焦点上关闭

问题描述

我有一个包含 UIViewRepresentable 的简单工作表。它打开一个网页,仅此而已。我的应用程序的两个部分都有这个模块。一个很好用,但另一个当我专注于文本字段时,会立即关闭模式并给我消息(在问题下方)。我发现这是自动布局的问题,但我使用的是 SwiftUI,那么单个 Web 视图会出现什么问题?

我做错了什么?

    .sheet(item: $addURL) { url in
       WebView(callback: { _ in viewmodel.fetchCards() },url: url)}

我知道阅读时间太长,但也许会有所帮助:

2021-02-21 02:11:34.423786+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x6000001c7c50 h=--& v=--& _UIToolbarContentView:0x7f86c0e58860.width == 0   (active)>","<NSLayoutConstraint:0x6000001cc7d0 H:|-(0)-[_UIbuttonbarStackView:0x7f86c0e51e20]   (active,names: '|':_UIToolbarContentView:0x7f86c0e58860 )>","<NSLayoutConstraint:0x6000001cc820 H:[_UIbuttonbarStackView:0x7f86c0e51e20]-(0)-|   (active,"<NSLayoutConstraint:0x6000001c55e0 'IB_Leading_Leading' H:|-(0)-[_UIModernBarButton:0x7f86c2034c10]   (active,names: '|':_UIbuttonbarButton:0x7f86c2034490 )>","<NSLayoutConstraint:0x6000001c5c70 'IB_Leading_Leading' H:|-(>=5)-[_UIModernBarButton:0x7f86c2035f20]   (active,names: '|':_UIbuttonbarButton:0x7f86c2035d50 )>","<NSLayoutConstraint:0x6000001c5630 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2034c10]-(>=8)-|   (active,"<NSLayoutConstraint:0x6000001c5cc0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2035f20]-(>=5)-|   (active,"<NSLayoutConstraint:0x6000001c6a30 'TB_Leading_Leading' H:|-(8)-[_UIModernBarButton:0x7f86c2037880'Done']   (active,names: '|':_UIbuttonbarButton:0x7f86c2036860 )>","<NSLayoutConstraint:0x6000001c6a80 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2037880'Done']-(0)-|   (active,"<NSLayoutConstraint:0x6000001c6f80 'UISV-canvas-connection' UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'.leading == _UIbuttonbarButton:0x7f86c2034490.leading   (active)>","<NSLayoutConstraint:0x6000001c72f0 'UISV-canvas-connection' UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'.trailing == _UIbuttonbarButton:0x7f86c2036860.trailing   (active)>","<NSLayoutConstraint:0x6000001c7340 'UISV-spacing' H:[_UIbuttonbarButton:0x7f86c2034490]-(0)-[UIView:0x7f86c2035be0]   (active)>","<NSLayoutConstraint:0x6000001c7390 'UISV-spacing' H:[UIView:0x7f86c2035be0]-(0)-[_UIbuttonbarButton:0x7f86c2035d50]   (active)>","<NSLayoutConstraint:0x6000001c73e0 'UISV-spacing' H:[_UIbuttonbarButton:0x7f86c2035d50]-(0)-[UIView:0x7f86c20366f0]   (active)>","<NSLayoutConstraint:0x6000001c7430 'UISV-spacing' H:[UIView:0x7f86c20366f0]-(0)-[_UIbuttonbarButton:0x7f86c2036860]   (active)>","<NSLayoutConstraint:0x6000001cc640 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'](LTR)   (active,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>","<NSLayoutConstraint:0x6000001cc6e0 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide']-(0)-|(LTR)   (active,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001c5630 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2034c10]-(>=8)-|   (active,names: '|':_UIbuttonbarButton:0x7f86c2034490 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.425675+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001c5cc0 'IB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2035f20]-(>=5)-|   (active,names: '|':_UIbuttonbarButton:0x7f86c2035d50 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.426712+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001c6a80 'TB_Trailing_Trailing' H:[_UIModernBarButton:0x7f86c2037880'Done']-(0)-|   (active,names: '|':_UIbuttonbarButton:0x7f86c2036860 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.428153+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x6000001c7cf0 h=--& v=--& _UIToolbarContentView:0x7f86c0e58860.height == 0   (active)>","<NSLayoutConstraint:0x6000001cc870 V:|-(0)-[_UIbuttonbarStackView:0x7f86c0e51e20]   (active,"<NSLayoutConstraint:0x6000001cc8c0 _UIbuttonbarStackView:0x7f86c0e51e20.bottom == _UIToolbarContentView:0x7f86c0e58860.bottom   (active)>","<NSLayoutConstraint:0x600000138500 UIImageView:0x7f86c2035a10.centerY == _UIModernBarButton:0x7f86c2034c10.centerY   (active)>","<NSLayoutConstraint:0x6000001c58b0 'IB_Baseline_Baseline' _UIModernBarButton:0x7f86c2034c10.lastBaseline == UILayoutGuide:0x600001bbd5e0'UIViewLayoutMarginsGuide'.bottom   (active)>","<NSLayoutConstraint:0x6000001c5900 'IB_Top_Top' V:|-(>=0)-[_UIModernBarButton:0x7f86c2034c10]   (active,"<NSLayoutConstraint:0x6000001c5b30 'UIbuttonbar.maximumAlignmentSize' _UIbuttonbarButton:0x7f86c2034490.height == UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'.height   (active)>","<NSLayoutConstraint:0x6000001cc690 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide']-(0)-|   (active,"<NSLayoutConstraint:0x6000001c5810 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001bbd5e0'UIViewLayoutMarginsGuide']-(11)-|   (active,"<NSLayoutConstraint:0x6000001cc5f0 'UIView-topMargin-guide-constraint' V:|-(0)-[UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide']   (active,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x600000138500 UIImageView:0x7f86c2035a10.centerY == _UIModernBarButton:0x7f86c2034c10.centerY   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.429076+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,"<NSLayoutConstraint:0x6000001ca8f0 UIImageView:0x7f86c2036520.centerY == _UIModernBarButton:0x7f86c2035f20.centerY   (active)>","<NSLayoutConstraint:0x6000001c5f40 'IB_Baseline_Baseline' _UIModernBarButton:0x7f86c2035f20.lastBaseline == UILayoutGuide:0x600001bbd500'UIViewLayoutMarginsGuide'.bottom   (active)>","<NSLayoutConstraint:0x6000001c5f90 'IB_Top_Top' V:|-(>=0)-[_UIModernBarButton:0x7f86c2035f20]   (active,"<NSLayoutConstraint:0x6000001c61c0 'UIbuttonbar.maximumAlignmentSize' _UIbuttonbarButton:0x7f86c2035d50.height == UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'.height   (active)>","<NSLayoutConstraint:0x6000001c5ea0 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001bbd500'UIViewLayoutMarginsGuide']-(11)-|   (active,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001ca8f0 UIImageView:0x7f86c2036520.centerY == _UIModernBarButton:0x7f86c2035f20.centerY   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.430070+0100 CafeApp[54097:3012811] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand,"<NSLayoutConstraint:0x6000001d58b0 UIButtonLabel:0x7f86c203a690.centerY == _UIModernBarButton:0x7f86c2037880'Done'.centerY + 1.5   (active)>","<NSLayoutConstraint:0x6000001c6c10 'TB_Baseline_Baseline' _UIModernBarButton:0x7f86c2037880'Done'.lastBaseline == UILayoutGuide:0x600001bbd960'UIViewLayoutMarginsGuide'.bottom   (active)>","<NSLayoutConstraint:0x6000001c6c60 'TB_Top_Top' V:|-(>=0)-[_UIModernBarButton:0x7f86c2037880'Done']   (active,"<NSLayoutConstraint:0x6000001c6ee0 'UIbuttonbar.maximumAlignmentSize' _UIbuttonbarButton:0x7f86c2036860.height == UILayoutGuide:0x600001bd1340'UIViewLayoutMarginsGuide'.height   (active)>","<NSLayoutConstraint:0x6000001c6b70 'UIView-bottomMargin-guide-constraint' V:[UILayoutGuide:0x600001bbd960'UIViewLayoutMarginsGuide']-(11)-|   (active,names: '|':_UIbuttonbarStackView:0x7f86c0e51e20 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000001d58b0 UIButtonLabel:0x7f86c203a690.centerY == _UIModernBarButton:0x7f86c2037880'Done'.centerY + 1.5   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
2021-02-21 02:11:34.497772+0100 CafeApp[54097:3012811] WF: _userSettingsForUser : (null)
2021-02-21 02:11:34.497881+0100 CafeApp[54097:3012811] WF: _WebFilterIsActive returning: NO
2021-02-21 02:11:35.041365+0100 CafeApp[54097:3012811] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=3 "Target is not running or required target entitlement is missing" UserInfo={RBSAssertionAttribute=<RBSDomainAttribute| domain:"com.apple.webkit" name:"Background" sourceEnvironment:"(null)">,NSLocalizedFailureReason=Target is not running or required target entitlement is missing}>
2021-02-21 02:11:35.041769+0100 CafeApp[54097:3012811] [ProcessSuspension] 0x11b1fef80 - ProcessAssertion: Failed to acquire RBS Background assertion 'WebProcess Background Assertion' for process with PID 54102,error: Error Domain=RBSAssertionErrorDomain Code=3 "Target is not running or required target entitlement is missing" UserInfo={RBSAssertionAttribute=<RBSDomainAttribute| domain:"com.apple.webkit" name:"Background" sourceEnvironment:"(null)">,NSLocalizedFailureReason=Target is not running or required target entitlement is missing}
2021-02-21 02:11:35.059422+0100 CafeApp[54097:3012811] [assertion] Error acquiring assertion: <Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}>
2021-02-21 02:11:35.059608+0100 CafeApp[54097:3012811] [ProcessSuspension] 0x11b1fe000 - ProcessAssertion: Failed to acquire RBS Background assertion 'WebProcess Background Assertion' for process with PID 54102,error: Error Domain=RBSAssertionErrorDomain Code=2 "Specified target process does not exist" UserInfo={NSLocalizedFailureReason=Specified target process does not exist}

WKWebView的代码


struct WebView: UIViewRepresentable{
    let callback: (URL)->()
    let url: URL

    func makeCoordinator() -> WebView.Coordinator {
        Coordinator(self)
    }
    
    var request: URLRequest {
        URLRequest(url: url)
    }

    private let webview = WKWebView()

    fileprivate func loadRequest(in webView: WKWebView) {
        webView.load(request)
    }

    func makeUIView(context: UIViewRepresentableContext<WebView>) -> WKWebView {
        webview.navigationDelegate = context.coordinator
        webview.setContentHuggingPriority(.defaultHigh,for: .vertical)
        webview.setContentCompressionResistancePriority(.defaultLow,for: .horizontal)

        dispatchQueue.main.async {
            webview.becomeFirstResponder()
        }
        
        loadRequest(in: webview)
        return webview
    }

    func updateUIView(_ uiView: WKWebView,context: UIViewRepresentableContext<WebView>) {
        loadRequest(in: uiView)
    }
    
    class Coordinator: NSObject,WKNavigationDelegate {
        let parent: WebView

        init(_ parent: WebView) {
            self.parent = parent
        }

        func webView(_ webView: WKWebView,decidePolicyFor navigationAction: WKNavigationAction,decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            if let url = navigationAction.request.url,url.valueOf("success") != nil {
                dispatchQueue.main.async { [weak self] in
                    self?.parent.callback(url)
                }
                
                decisionHandler(WKNavigationActionPolicy.allow)
            } else {
                decisionHandler(WKNavigationActionPolicy.allow)
            }
        }
     }
}

解决方法

我解决了!原因是在接收键盘高度以对文本字段进行偏移的发布者中。据我所知,视图在更改其任何属性时会完全重绘自身。它还会重绘它的工作表。所以我写了一个条件,只有当那里没有模态时才改变视图:

.onReceive(Publishers.keyboardHeight) {
    if typeOfModal == nil {
        self.keyboardHeight = $0
    }
}