尝试修复UIViewAlertForUnsatisfiableConstraints时遇到问题

时间:2019-09-02 14:26:00

标签: ios swift uiview autolayout ios-autolayout

我是iOS开发的100%的新手,并且是我从一些承包商那里继承来的项目的唯一开发人员,所以对于如何弄清这个问题的原因,我感到茫然。

我能够扩展输出日志以获取更多详细信息,并且能够跟踪视图,但是我似乎找不到其所指的确切组件。

UIWindow:0x7f98ce414290
|   UILayoutContainerView:0x7f98ce512ad0
|   |   UINavigationTransitionView:0x7f98ce428970
|   |   |   UIViewControllerWrapperView:0x7f98ce42b220
|   |   |   |   SWRevealView:0x7f98ce50b0e0
|   |   |   |   |   UIView:0x7f98ce50abd0
|   |   |   |   |   |   UILayoutContainerView:0x7f98ce50dfb0
|   |   |   |   |   |   |   UINavigationTransitionView:0x7f98ce614110
|   |   |   |   |   |   |   |   UIViewControllerWrapperView:0x7f98ce407440
|   |   |   |   |   |   |   |   |   •UIView:0x7f98ce622790, MISSING HOST CONSTRAINTS
|   |   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003aef720 - "UIViewSafeAreaLayoutGuide", layoutFrame = {{0, 20}, {414, 716}}, owningView = <UIView: 0x7f98ce622790; frame = (0 0; 414 736); autoresize = W+H; gestureRecognizers = <NSArray: 0x600000d08030>; layer = <CALayer: 0x6000003d19a0>>>- AMBIGUOUS LAYOUT for UILayoutGuide:0x600003aef720'UIViewSafeAreaLayoutGuide'.Width{id: 295}, UILayoutGuide:0x600003aef720'UIViewSafeAreaLayoutGuide'.Height{id: 290}
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce621cf0
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce61e450
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce622970
|   |   |   |   |   |   |   |   |   |   |   •UIView:0x7f98d1703b40
|   |   |   |   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a997a0 - "UIViewSafeAreaLayoutGuide", layoutFrame = {{0, 0}, {320, 89.666666666666671}}, owningView = <UIView: 0x7f98d1703b40; frame = (0 0; 320 50); autoresize = W+H; tag = 10; layer = <CALayer: 0x600000385d60>>>- AMBIGUOUS LAYOUT for UILayoutGuide:0x600003a997a0'UIViewSafeAreaLayoutGuide'.Height{id: 391}
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f98ce51a5d0- AMBIGUOUS LAYOUT for UIButton:0x7f98ce51a5d0.minY{id: 404}
|   |   |   |   |   |   |   |   |   |   |   |   |   UIImageView:0x7f98ce436990
|   |   |   |   |   |   |   |   |   |   |   |   *APP_NAME.CustomLabel:0x7f98ce6291f0'School Details'- AMBIGUOUS LAYOUT for APP_NAME.CustomLabel:0x7f98ce6291f0'School Details'.minY{id: 406}
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f98d1704b20- AMBIGUOUS LAYOUT for UIButton:0x7f98d1704b20.minY{id: 432}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f98d1700000- AMBIGUOUS LAYOUT for UIView:0x7f98d1700000.minY{id: 411}
|   |   |   |   |   |   |   |   |   |   |   |   *APP_NAME.CustomLabel:0x7f98ce628890
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f98ce628660
|   |   |   |   |   |   |   |   |   |   *UICollectionView:0x7f98cf81fa00
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce616e90
|   |   |   |   |   |   |   |   |   |   |   *UIStackView:0x7f98ce617070
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f98ce6101a0'NOT INTERESTED'
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f98ce60f7e0'APPLY NOW (0)'
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce6107e0
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce621b10
|   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f98ce621090
|   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f98ce6212c0'Thank you for signing up ...'
|   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f98ce620cb0
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce61cf60
|   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f98ce61c560
|   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f98ce620270'Hang Tight!

There are no...'
|   |   |   |   |   |   |   |   |   |   |   *APP_NAME.CustomButton:0x7f98ce6104c0'REFRESH'
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce60be10
|   |   |   |   |   |   |   |   |   |   *UIButton:0x7f98ce613340
|   |   |   |   |   |   |   |   |   |   |   UIImageView:0x7f98d11144a0
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce621ed0
|   |   |   |   |   |   |   |   |   |   *UIView:0x7f98ce6220b0
|   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f98ce622290
|   |   |   |   |   |   |   UINavigationBar:0x7f98d3804100
|   |   |   |   |   |   |   |   _UIBarBackground:0x7f98d3804520
|   |   |   |   |   |   |   |   |   UIImageView:0x7f98d38049b0
|   |   |   |   |   |   |   |   |   UIVisualEffectView:0x7f98d3804be0
|   |   |   |   |   |   |   |   |   |   _UIVisualEffectBackdropView:0x7f98ce61fdf0
|   |   |   |   |   |   |   |   |   |   _UIVisualEffectSubview:0x7f98ce612760
|   |   |   |   |   |   |   |   _UINavigationBarLargeTitleView:0x7f98d3805430
|   |   |   |   |   |   |   |   |   UILabel:0x7f98ce50b310
|   |   |   |   |   |   |   |   •_UINavigationBarContentView:0x7f98d3805010
|   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a88000 - "BackButtonGuide(0x7f98d38052d0)", layoutFrame = {{0, 0}, {12, 44}}, owningView = <_UINavigationBarContentView: 0x7f98d3805010; frame = (0 0; 414 44); layer = <CALayer: 0x6000003b8840>>>
|   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a880e0 - "LeadingBarGuide(0x7f98d38052d0)", layoutFrame = {{12, 0}, {36, 44}}, owningView = <_UINavigationBarContentView: 0x7f98d3805010; frame = (0 0; 414 44); layer = <CALayer: 0x6000003b8840>>>
|   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a881c0 - "TitleView(0x7f98d38052d0)", layoutFrame = {{48, 0}, {354, 44}}, owningView = <_UINavigationBarContentView: 0x7f98d3805010; frame = (0 0; 414 44); layer = <CALayer: 0x6000003b8840>>>
|   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a882a0 - "TrailingBarGuide(0x7f98d38052d0)", layoutFrame = {{402, 0}, {0, 44}}, owningView = <_UINavigationBarContentView: 0x7f98d3805010; frame = (0 0; 414 44); layer = <CALayer: 0x6000003b8840>>>
|   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a88380 - "UIViewLayoutMarginsGuide", layoutFrame = {{20, 20}, {374, 24}}, owningView = <_UINavigationBarContentView: 0x7f98d3805010; frame = (0 0; 414 44); layer = <CALayer: 0x6000003b8840>>>
|   |   |   |   |   |   |   |   |   *_UIButtonBarStackView:0x7f98d110a480
|   |   |   |   |   |   |   |   |   |   *<UILayoutGuide: 0x600003a94540 - "UIViewLayoutMarginsGuide", layoutFrame = {{0, 0}, {36, 44}}, owningView = <_UIButtonBarStackView: 0x7f98d110a480; frame = (12 0; 36 44); layer = <CALayer: 0x6000003e9680>>>
|   |   |   |   |   |   |   |   |   |   *_UIButtonBarButton:0x7f98ce40f9d0
|   |   |   |   |   |   |   |   |   |   |   *_UIModernBarButton:0x7f98ce42fdc0
|   |   |   |   |   |   |   |   |   |   |   |   UIImageView:0x7f98ce4357d0
|   |   |   |   |   |   |   |   _UINavigationBarModernPromptView:0x7f98ce50b600

Legend:
    * - is laid out with auto layout
    + - is laid out manually, but is represented in the layout engine because translatesAutoresizingMaskIntoConstraints = YES
    • - layout engine host

2019-09-02 08:36:02.740049+0900 APP_NAME[87051:13418262] [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. 
(
    "<NSLayoutConstraint:0x6000020c8370 UIView:0x7f98d1700000.height == 0.5   (active)>",
    "<NSLayoutConstraint:0x6000020d30c0 APP_NAME.CustomLabel:0x7f98ce628890.height == 19   (active)>",
    "<NSLayoutConstraint:0x6000020d1f90 UIImageView:0x7f98ce628660.height == 50   (active)>",
    "<NSLayoutConstraint:0x6000020c8730 V:[UIView:0x7f98d1700000]-(0)-|   (active, names: '|':UIView:0x7f98d1703b40 )>",
    "<NSLayoutConstraint:0x6000020c87d0 V:[APP_NAME.CustomLabel:0x7f98ce628890]-(>=5)-[UIView:0x7f98d1700000]   (active)>",
    "<NSLayoutConstraint:0x6000020c8870 UIImageView:0x7f98ce628660.top == UILayoutGuide:0x600003a997a0'UIViewSafeAreaLayoutGuide'.top + 10   (active)>",
    "<NSLayoutConstraint:0x6000020c8960 V:[UIImageView:0x7f98ce628660]-(5)-[APP_NAME.CustomLabel:0x7f98ce628890]   (active)>",
    "<NSLayoutConstraint:0x600002084b90 'UIView-Encapsulated-Layout-Height' UIView:0x7f98d1703b40.height == 50   (active)>",
    "<NSLayoutConstraint:0x6000020c84b0 'UIViewSafeAreaLayoutGuide-top' V:|-(0)-[UILayoutGuide:0x600003a997a0'UIViewSafeAreaLayoutGuide']   (active, names: '|':UIView:0x7f98d1703b40 )>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000020d1f90 UIImageView:0x7f98ce628660.height == 50   (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.

例如,我可以找到UIView:0x7f98d1703b40,但是找不到它所指的自定义标签。

感谢您的帮助:-/

***** 编辑 *****

我终于能够跟踪到这行代码,为UIView:0x7f98ce622790添加了导航栏。如果我将其注释掉,则错误消失了,但是导航栏消失了。

extension DIBaseController: NavigationDelegate {

    func configureNavigtion(onView view: UIView, title: String?,chatTitle: String? = nil,chatImage: String? = nil, leftButtonAction leftAction: ButtonAction = .back, rightButoonTitle: String? = "" , rightButtonAction:ButtonAction = .hidden ) {
        view.backgroundColor = .clear

        let navBar = NavigationBar()
        addChildViewController(navBar)
        navBar.view.frame = view.bounds
        navBar.view.tag = 10

        // THIS IS THE LINE THAT CAUSES THE PROBLEM
        view.addSubview(navBar.view)

        navBar.configureNavigation(title,chatTitle,chatImage,leftButtonAction: leftAction,rightButoonTitle:rightButoonTitle,rightButtonAction:rightButtonAction)
        navBar.delegate = self
    }

    @objc func navigationBar(_ navigationBar: NavigationBar,leftButtonTapped leftButton: UIButton) {
        switch navigationBar.leftAction {
        case .back:
            navigationController?.popViewController(animated: true)
            break
        case .hidden,.menu:
            break
        default: break
        }
    }

    @objc func navigationBar(_ navigationBar: NavigationBar,rightButtonTapped rightButton: UIButton){
    }
}

NavigationBar类看起来像这样。

protocol NavigationDelegate {
    func navigationBar(_ navigationBar: NavigationBar,leftButtonTapped leftButton: UIButton)
    func navigationBar(_ navigationBar: NavigationBar,rightButtonTapped rightButton: UIButton)
}

enum ButtonAction {

    case back
    case hidden
    case menu
    case chat
    case option

    var icon: UIImage? {
        switch self {
        case .back: return #imageLiteral(resourceName: "back_Arrow")
        case .hidden : return nil
        case .menu: return #imageLiteral(resourceName: "menu")
        case .chat: return #imageLiteral(resourceName: "chatt")
        case .option : return #imageLiteral(resourceName: "ic_chart_more")
        }
    }
}

import UIKit
class NavigationBar: UIViewController {


    //MARK:-IBOulets.
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var chatUserTitle: UILabel!
    @IBOutlet weak var leftButton: UIButton!
    @IBOutlet weak var rightButton: UIButton!
    @IBOutlet weak var chatUserImage: UIImageView!


    //MARK:-Variables.
    var delegate:NavigationDelegate?
    var leftAction:ButtonAction = .back
    var rightAction:ButtonAction = .hidden


    //MARK:-ViewLifeCycle.
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // MARK: - Methods
    //MARK: ... Public
    func configureNavigation(_ title: String? = nil, _ chatTitle: String? = nil, _ chatImage: String? = nil,leftButtonAction leftAction: ButtonAction = .back,rightButoonTitle: String?,rightButtonAction: ButtonAction = .hidden) {
        setupAppearance(on: leftButton, withAction: leftAction)
        self.leftAction = leftAction
        if let url = chatImage ,url != "" {
       self.chatUserImage.isHidden = false
            self.chatUserImage.kf.setImage(with:  URL(string:url), placeholder: #imageLiteral(resourceName: "user_profile"), options: nil, progressBlock: nil, completionHandler: nil)
        }else {
            self.chatUserImage.isHidden = true
            self.chatUserImage.image = #imageLiteral(resourceName: "user_profile")
        }
        self.titleLabel.text = title
        self.chatUserTitle.text = chatTitle


        if rightButoonTitle == "" {
            rightButton.setTitle("", for: .normal)
            setupAppearance(on: rightButton, withAction: rightButtonAction)
            //rightButton.isUserInteractionEnabled = false
        }else{
          rightButton.isUserInteractionEnabled = true
          rightButton.setTitle(rightButoonTitle, for: .normal)
        }


    }

    func setupAppearance(on button: UIButton, withAction action: ButtonAction) -> Void {
        if action == .hidden {
           button.isUserInteractionEnabled = false
        }else{
           button.isUserInteractionEnabled = true
        }
        button.setImage(action.icon, for: UIControlState())
    }


    // MARK:- IBActions Methods
    @IBAction func leftButtonTapped(_ sender: UIButton) -> Void {
        delegate?.navigationBar(self, leftButtonTapped: sender)
    }
    @IBAction func rightButtonTapped(_ sender: UIButton) {
        delegate?.navigationBar(self, rightButtonTapped: sender)
    }

}

2 个答案:

答案 0 :(得分:0)

如果我理解正确,则UIView:0x7f98d1700000APP_NAME.CustomLabel:0x7f98ce628890UIImageView:0x7f98ce628660位于UIView:0x7f98d1703b40内部。图像的高度设置为50,顶部的高度为10,标签的高度为5,标签的高度设置为19,如果将其相加即可得出内容的高度,则至少为84,但是容器视图的高度仅为50(0x7f98d1703b40)。

日志告诉您84不适合50,因此,它必须删除约束以尝试纠正错误。

Will attempt to recover by breaking constraint <NSLayoutConstraint:0x6000020d1f90 UIImageView:0x7f98ce628660.height == 50 (active)>

这会使图像的高度不同于50。如果可以,则可以使用Adrian的解决方案。

如果没有,则可以增加容器视图的高度,或减少内容的高度,解决方案将取决于您要实现的目标。

答案 1 :(得分:0)

感谢Adrian的建议,并感谢cesl的解释。

为了修复它,我不得不更改NavigationBar上约束的优先级。但是,由于没有故事板,它是通过编程方式完成的(我认为它是本机组件),因此我不得不遍历所有约束并将其优先级更改为较低的值,例如200。

for constraint in navBar.view.constraints {
   constraint.priority = UILayoutPriority(200)
}

这允许我将约束保留在适当的位置,同时让自动布局事物根据需要调整组件的大小,并防止UI像我刚删除它们一样破坏自身。