21

When an input in WKWebView gets focused a constraints error pops up.

Code:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad();
        let wv = WKWebView(frame: CGRect(x: 100, y: 100, width: 100, height: 100));
        wv.loadHTMLString("<input type='text'/>", baseURL: nil); // it also can be select, it makes no difference
        view.addSubview(wv);
    }
}

Error Log:

2017-11-05 00:26:28.861439+0700 achievator[20048:75393577] [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:0x60c0000955e0 h=-&- v=-&- UIToolbar:0x7f8540419570.width ==
_UIInputViewContent:0x7f8540411830.width   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x60c000095720 h=--& v=--& _UIInputViewContent:0x7f8540411830.width == 0   (active)>",
    "<NSLayoutConstraint:0x60800009a9a0 H:|-(0)-[_UIButtonBarStackView:0x7f854041b2d0]   (active, names: '|':_UIToolbarContentView:0x7f8540402de0 )>",
    "<NSLayoutConstraint:0x60800009a9f0 _UIButtonBarStackView:0x7f854041b2d0.trailing == _UIToolbarContentView:0x7f8540402de0.trailing + 8   (active)>",
    "<NSLayoutConstraint:0x608000099a00 _UIToolbarContentView:0x7f8540402de0.trailing == UIToolbar:0x7f8540419570.trailing   (active)>",
    "<NSLayoutConstraint:0x608000099aa0 H:|-(0)-[_UIToolbarContentView:0x7f8540402de0]   (active, names: '|':UIToolbar:0x7f8540419570 )>",
    "<NSLayoutConstraint:0x6040000981a0 H:|-(0)-[_UIModernBarButton:0x7f854050ef70]   (active, names: '|':_UIButtonBarButton:0x7f854050e7f0 )>",
    "<NSLayoutConstraint:0x6040000981f0 H:[_UIModernBarButton:0x7f854050ef70]-(>=8)-|   (active, names: '|':_UIButtonBarButton:0x7f854050e7f0 )>",
    "<NSLayoutConstraint:0x6040000999b0 H:|-(8)-[_UIModernBarButton:0x7f8540512450'Done']   (active, names: '|':_UIButtonBarButton:0x7f8540511660 )>",
    "<NSLayoutConstraint:0x604000099a00 H:[_UIModernBarButton:0x7f8540512450'Done']-(0)-|   (active, names: '|':_UIButtonBarButton:0x7f8540511660 )>",
    "<NSLayoutConstraint:0x60c000094690 'UISV-canvas-connection' UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'.leading ==
_UIButtonBarButton:0x7f854050e7f0.leading   (active)>",
    "<NSLayoutConstraint:0x60c0000946e0 'UISV-canvas-connection' UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'.trailing ==
_UIButtonBarButton:0x7f8540511660.trailing   (active)>",
    "<NSLayoutConstraint:0x60c000094780 'UISV-spacing' H:[_UIButtonBarButton:0x7f854050e7f0]-(0)-[UIView:0x7f854050f4c0]   (active)>",
    "<NSLayoutConstraint:0x60c000094960 'UISV-spacing' H:[UIView:0x7f854050f4c0]-(0)-[_UIButtonBarButton:0x7f854050ea30]   (active)>",
    "<NSLayoutConstraint:0x60c000094a00 'UISV-spacing' H:[_UIButtonBarButton:0x7f854050ea30]-(0)-[UIView:0x7f8540511480]   (active)>",
    "<NSLayoutConstraint:0x60c000094a50 'UISV-spacing' H:[UIView:0x7f8540511480]-(0)-[_UIButtonBarButton:0x7f8540511660]   (active)>",
    "<NSLayoutConstraint:0x60800009a6d0 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'](LTR)  (active, names: '|':_UIButtonBarStackView:0x7f854041b2d0 )>",
    "<NSLayoutConstraint:0x60800009a770 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide']-(0)-|(LTR)  (active, names: '|':_UIButtonBarStackView:0x7f854041b2d0 )>" )

Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x6040000981f0 H:[_UIModernBarButton:0x7f854050ef70]-(>=8)-|   (active, names: '|':_UIButtonBarButton:0x7f854050e7f0 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 2017-11-05 00:26:28.863156+0700 achievator[20048:75393577] [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:0x60c0000955e0 h=-&- v=-&- UIToolbar:0x7f8540419570.width ==
_UIInputViewContent:0x7f8540411830.width   (active)>",
    "<NSAutoresizingMaskLayoutConstraint:0x60c000095720 h=--& v=--& _UIInputViewContent:0x7f8540411830.width == 0   (active)>",
    "<NSLayoutConstraint:0x60800009a9a0 H:|-(0)-[_UIButtonBarStackView:0x7f854041b2d0]   (active, names: '|':_UIToolbarContentView:0x7f8540402de0 )>",
    "<NSLayoutConstraint:0x60800009a9f0 _UIButtonBarStackView:0x7f854041b2d0.trailing == _UIToolbarContentView:0x7f8540402de0.trailing + 8   (active)>",
    "<NSLayoutConstraint:0x608000099a00 _UIToolbarContentView:0x7f8540402de0.trailing == UIToolbar:0x7f8540419570.trailing   (active)>",
    "<NSLayoutConstraint:0x608000099aa0 H:|-(0)-[_UIToolbarContentView:0x7f8540402de0]   (active, names: '|':UIToolbar:0x7f8540419570 )>",
    "<NSLayoutConstraint:0x604000098560 H:|-(>=5)-[_UIModernBarButton:0x7f8540510b40]   (active, names: '|':_UIButtonBarButton:0x7f854050ea30 )>",
    "<NSLayoutConstraint:0x604000098650 H:[_UIModernBarButton:0x7f8540510b40]-(>=5)-|   (active, names: '|':_UIButtonBarButton:0x7f854050ea30 )>",
    "<NSLayoutConstraint:0x6040000999b0 H:|-(8)-[_UIModernBarButton:0x7f8540512450'Done']   (active, names: '|':_UIButtonBarButton:0x7f8540511660 )>",
    "<NSLayoutConstraint:0x604000099a00 H:[_UIModernBarButton:0x7f8540512450'Done']-(0)-|   (active, names: '|':_UIButtonBarButton:0x7f8540511660 )>",
    "<NSLayoutConstraint:0x60c000094690 'UISV-canvas-connection' UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'.leading ==
_UIButtonBarButton:0x7f854050e7f0.leading   (active)>",
    "<NSLayoutConstraint:0x60c0000946e0 'UISV-canvas-connection' UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'.trailing ==
_UIButtonBarButton:0x7f8540511660.trailing   (active)>",
    "<NSLayoutConstraint:0x60c000094780 'UISV-spacing' H:[_UIButtonBarButton:0x7f854050e7f0]-(0)-[UIView:0x7f854050f4c0]   (active)>",
    "<NSLayoutConstraint:0x60c000094960 'UISV-spacing' H:[UIView:0x7f854050f4c0]-(0)-[_UIButtonBarButton:0x7f854050ea30]   (active)>",
    "<NSLayoutConstraint:0x60c000094a00 'UISV-spacing' H:[_UIButtonBarButton:0x7f854050ea30]-(0)-[UIView:0x7f8540511480]   (active)>",
    "<NSLayoutConstraint:0x60c000094a50 'UISV-spacing' H:[UIView:0x7f8540511480]-(0)-[_UIButtonBarButton:0x7f8540511660]   (active)>",
    "<NSLayoutConstraint:0x60800009a6d0 'UIView-leftMargin-guide-constraint' H:|-(0)-[UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide'](LTR)  (active, names: '|':_UIButtonBarStackView:0x7f854041b2d0 )>",
    "<NSLayoutConstraint:0x60800009a770 'UIView-rightMargin-guide-constraint' H:[UILayoutGuide:0x6080001a9a00'UIViewLayoutMarginsGuide']-(0)-|(LTR)  (active, names: '|':_UIButtonBarStackView:0x7f854041b2d0 )>" )

Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x604000098650 H:[_UIModernBarButton:0x7f8540510b40]-(>=5)-|   (active, names: '|':_UIButtonBarButton:0x7f854050ea30 )>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
Lal Krishna
  • 15,485
  • 6
  • 64
  • 84
mnemon1ck
  • 420
  • 3
  • 12

4 Answers4

12

My assumption is this a bug in ios 11. The complaints are about the components in the button bar for the keyboard which are all using default values set by the os. I have run the same code on both ios 9 and ios 10 and get no error messages.

Jim T
  • 2,480
  • 22
  • 21
  • 3
    is there any solution in sight? Can this be fixed somehow? Getting the same on iOS 13 beta 5 – swalkner Jul 30 '19 at 10:32
  • If you just want to remove the white space at the bottom: `NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { (notification) in self.webView.scrollView.contentOffset.y = 0 }` @swalkner If the offset was different than 0 you could get the content offset value in `keyboardWillShowNotification` and set it accordingly in `keyboardWillHideNotification` – mc_plectrum Sep 17 '19 at 20:45
3

Having the same issue. I'm running a clean project, vanilla setup and this issue comes up as soon as the webview keyboard gets focus. It seems to be a common issue, might just be a bug in iOS 11.

Also see:

WKWebView LayoutConstraints issue

Yasper
  • 501
  • 5
  • 23
1

One or more constraints are not compatible at the same time when keyboard is open.

Instead of doing frame by hand, try setting constraints to ur WKWebView.

private func addWKWebView(){
    let wv = WKWebView()
    view.addSubview(wv);
    wv.translatesAutoresizingMaskIntoConstraints = false


    wv.widthAnchor.constraint(equalTo:   view.widthAnchor  ).isActive = true
    wv.heightAnchor.constraint(equalTo:  view.heightAnchor ).isActive = true
    wv.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    wv.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}

or Something like this:

private func addWKWebView(){
    let wv = WKWebView()
    view.addSubview(wv);
    wv.translatesAutoresizingMaskIntoConstraints = false


    wv.widthAnchor.constraint(equalToConstant:  100).isActive = true
    wv.heightAnchor.constraint(equalToConstant: 100).isActive = true
    wv.widthAnchor.constraint(equalToConstant:  100).isActive = true
    wv.heightAnchor.constraint(equalToConstant: 100).isActive = true
}

U need to play around with your constraints to set the WkWebView where u want.

alegelos
  • 2,308
  • 17
  • 26
-1

I also have this problem when I need my custom-keyboard pop up. Finally, all I need to do is change the html input-element's eventType: from "touchstart" to "click" .

Origin:

    function setUpEvent(elem, eventType, handler) {
        return (elem.attachEvent ? elem.attachEvent("on" + eventType, handler)
            : ((elem.addEventListener) ? elem.addEventListener(eventType, handler, false) : null));
    }

    window.onload = function () {

        var input_ele = document.getElementById('YOUR_ELE_NAME');
        setUpEvent(input_ele, "touchstart", function (e) {

            //showKeyboard();//my personal function to show keyboard
        });
    }

And it works:

    function setUpEvent(elem, eventType, handler) {
        return (elem.attachEvent ? elem.attachEvent("on" + eventType, handler)
            : ((elem.addEventListener) ? elem.addEventListener(eventType, handler, false) : null));
    }

    window.onload = function () {

        var input_ele = document.getElementById('YOUR_ELE_NAME');
        setUpEvent(input_ele, "click", function (e) {//change here

            //showKeyboard();//my personal function to show keyboard
        });
    }