UIViewAlertForUnsatisfiableConstraints를 잡는 방법?


234

디버거 로그에 오류가 나타납니다.

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

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.

그 전화를 어떻게 잡을 수 있습니까? 내 코드의 어느 곳에도 나타나지 않습니다.

스크린 샷 1


10 가지 중 9 가지 경우 : 이것은 단지 원인 : yoru 스토리 보드의 일부보기 또는 항목의 경우 "설치됨"을 선택 취소합니다. (예를 들어, 개발 버튼이나 더 이상 필요하지 않은 것) 일반적으로 "설치되지 않은"을 잘못 처리합니다. 설치되지 않은 항목이 없으면 제약 조건이 남는 경우가 종종 있습니다. 종종 해결책은 잊어 버린 항목을 삭제하고 "설치되지 않은"항목 주위에있는 항목을 삭제하는 것입니다.
— Fattie

답변:


442

이 게시물 은 많은 도움 이 되었습니다 !

UIViewAlertForUnsatisfiableConstraints 기호 중단 점을 제안 된 조치로 추가 했습니다 .

Obj-C 프로젝트

po [[UIWindow keyWindow] _autolayoutTrace]

Objective-C 프로젝트에서 사용자 정의 조치가있는 기호 브레이크 포인트

스위프트 프로젝트

expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]

사용자 정의 동작이있는 상징적 인 중단 점

이 힌트를 통해 로그가 더 자세 해졌고 제약 조건이 손상된 뷰를 쉽게 식별 할 수있었습니다.

UIWindow:0x7f88a8e4a4a0
|   UILayoutContainerView:0x7f88a8f23b70
|   |   UINavigationTransitionView:0x7f88a8ca1970
|   |   |   UIViewControllerWrapperView:0x7f88a8f2aab0
|   |   |   |   •UIView:0x7f88a8ca2880
|   |   |   |   |   *UIView:0x7f88a8ca2a10
|   |   |   |   |   |   *UIButton:0x7f88a8c98820'Archived'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb0e30'Archived'
|   |   |   |   |   |   *UIButton:0x7f88a8ca22d0'Download'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8cb04e0'Download'
|   |   |   |   |   |   *UIButton:0x7f88a8ca1580'Deleted'
|   |   |   |   |   |   |   UIButtonLabel:0x7f88a8caf100'Deleted'
|   |   |   |   |   *UIView:0x7f88a8ca33e0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca35b0
|   |   |   |   |   *_UILayoutGuide:0x7f88a8ca4090
|   |   |   |   |   _UIPageViewControllerContentView:0x7f88a8f1a390
|   |   |   |   |   |   _UIQueuingScrollView:0x7f88aa031c00
|   |   |   |   |   |   |   UIView:0x7f88a8f38070
|   |   |   |   |   |   |   UIView:0x7f88a8f381e0
|   |   |   |   |   |   |   |   •UIView:0x7f88a8f39fa0, MISSING HOST CONSTRAINTS
|   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8cb9bf0'Retrieve data'- AMBIGUOUS LAYOUT for UIButton:0x7f88a8cb9bf0'Retrieve data'.minX{id: 170}, UIButton:0x7f88a8cb9bf0'Retrieve data'.minY{id: 171}
|   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8f3ad80- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8f3ad80.minX{id: 172}, UIImageView:0x7f88a8f3ad80.minY{id: 173}
|   |   |   |   |   |   |   |   |   *App.RecordInfoView:0x7f88a8cbe530- AMBIGUOUS LAYOUT for App.RecordInfoView:0x7f88a8cbe530.minX{id: 174}, App.RecordInfoView:0x7f88a8cbe530.minY{id: 175}, App.RecordInfoView:0x7f88a8cbe530.Width{id: 176}, App.RecordInfoView:0x7f88a8cbe530.Height{id: 177}
|   |   |   |   |   |   |   |   |   |   +UIView:0x7f88a8cc1d30- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1d30.minX{id: 178}, UIView:0x7f88a8cc1d30.minY{id: 179}, UIView:0x7f88a8cc1d30.Width{id: 180}, UIView:0x7f88a8cc1d30.Height{id: 181}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc1ec0- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc1ec0.minX{id: 153}, UIView:0x7f88a8cc1ec0.minY{id: 151}, UIView:0x7f88a8cc1ec0.Width{id: 154}, UIView:0x7f88a8cc1ec0.Height{id: 165}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e68e10- AMBIGUOUS LAYOUT for UIView:0x7f88a8e68e10.minX{id: 155}, UIView:0x7f88a8e68e10.minY{id: 150}, UIView:0x7f88a8e68e10.Width{id: 156}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e65de0- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e65de0.minX{id: 159}, UIImageView:0x7f88a8e65de0.minY{id: 182}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e69080'8-6-2015'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8e69080'8-6-2015'.minX{id: 183}, UILabel:0x7f88a8e69080'8-6-2015'.minY{id: 184}, UILabel:0x7f88a8e69080'8-6-2015'.Width{id: 185}
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0690'16:34'- AMBIGUOUS LAYOUT for UILabel:0x7f88a8cc0690'16:34'.minX{id: 186}, UILabel:0x7f88a8cc0690'16:34'.minY{id: 187}, UILabel:0x7f88a8cc0690'16:34'.Width{id: 188}, UILabel:0x7f88a8cc0690'16:34'.Height{id: 189}
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8cc2050- AMBIGUOUS LAYOUT for UIView:0x7f88a8cc2050.minX{id: 161}, UIView:0x7f88a8cc2050.minY{id: 166}, UIView:0x7f88a8cc2050.Width{id: 163}
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e69d90- AMBIGUOUS LAYOUT for UIImageView:0x7f88a8e69d90.minX{id: 190}, UIImageView:0x7f88a8e69d90.minY{id: 191}, UIImageView:0x7f88a8e69d90.Width{id: 192}, UIImageView:0x7f88a8e69d90.Height{id: 193}
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cc00
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e618d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5ba10
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cd70
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e58e10
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e5e7a0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3cee0
|   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dc70
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e64dd0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e65290'Average flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8e712d0'177.0 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8c97150'1299.4'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3dde0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3df50'Maximum flow rate'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbfdb0'371.6 ml/s'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0230'873.5'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e2a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3e410'Total volume'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0f20'371.6 ml'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3e870
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3ea00'Time do max. flow'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc0ac0'3.6 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ee10
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3efa0'Flow time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cbf980'2.1 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f3e0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3f570'Voiding time'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc17e0'3.5 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3f9a0
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8f3fb30'Voiding delay'
|   |   |   |   |   |   |   |   |   |   |   |   *UILabel:0x7f88a8cc1380'1.0 s'
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8e65000
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52f20'Show'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6e1d0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e52c90'Send'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e61bb0
|   |   |   |   |   |   |   |   |   |   |   |   *UIButton:0x7f88a8e528e0'Delete'
|   |   |   |   |   |   |   |   |   |   |   |   *UIImageView:0x7f88a8e6b3f0
|   |   |   |   |   |   |   |   |   |   |   |   *UIView:0x7f88a8f3ff60
|   |   |   |   |   |   |   |   |   *UIActivityIndicatorView:0x7f88a8cba080
|   |   |   |   |   |   |   |   |   |   UIImageView:0x7f88a8cba700
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3150
|   |   |   |   |   |   |   |   |   *_UILayoutGuide:0x7f88a8cc3b10
|   |   |   |   |   |   |   UIView:0x7f88a8f339c0
|   |   UINavigationBar:0x7f88a8c96810
|   |   |   _UINavigationBarBackground:0x7f88a8e45c00
|   |   |   |   UIImageView:0x7f88a8e46410
|   |   |   UINavigationItemView:0x7f88a8c97520'App'
|   |   |   |   UILabel:0x7f88a8c97cc0'App'
|   |   |   UINavigationButton:0x7f88a8e3e850
|   |   |   |   UIImageView:0x7f88a8e445b0
|   |   |   _UINavigationBarBackIndicatorView:0x7f88a8f2b530

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

그런 다음 실행을 일시 중지 중지 하고 문제가있는보기의 배경색을 명령으로 변경했습니다 ( 물론 객체 의 0x7f88a8cc2050메모리 주소로 대체 ) ...

오브제 C

expr ((UIView *)0x7f88a8cc2050).backgroundColor = [UIColor redColor]

스위프트 3.0

expr -l Swift -- import UIKit
expr -l Swift -- unsafeBitCast(0x7f88a8cc2050, to: UIView.self).backgroundColor = UIColor.red

... 그리고 결과 대단했습니다!

힌트보기

놀랍습니다! 희망이 있습니다.


3
@iAnurag 실행이 일시 중지되면 콘솔 영역에서 명령을 실행할 수 있습니다.
— Thomás Calmon

2
@TomCalmon 나는 똑같이 ...하지만 그것은 다음과 같은 오류를 보여줍니다 rror: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x7f88a8cc2050). The process has been returned to the state before expression evaluation.
— iAnurag

2
expr -l objc++ -O -- [[UIWindow keyWindow] _autolayoutTrace]nil나를 위해 돌아온다
— Igor Andreev 12

2
0x7f88a8cc2050을 객체의 메모리 주소로 바꾸고 실행이 일시 중지 될 때 콘솔에서 명령을 실행하십시오.
— Tom Howard

3
놀랍습니다. 여기서 유용한 팁은 문제를 바로 잡는 데 완전히 도움이되었습니다. 항목이 빨간색으로 변경되면 가능하면 실행을 계속하면 하이라이트가 표시됩니다.
— Aaron

255

을 추가하고 싶을 것 Symbolic Breakpoint입니다. Apple 은이를 수행하는 방법에 대한 훌륭한 안내서 를 제공합니다 .

  1. 중단 점 네비게이터여 cmd+7( cmd+8엑스 코드 9)를
  2. Add왼쪽 하단 의 버튼을 클릭하십시오
  3. 고르다 Add Symbolic Breakpoint...
  4. Symbol그냥 입력 이라고 말하는 곳UIViewAlertForUnsatisfiableConstraints

또한 다른 중단 점처럼 처리하거나 설정, 해제 또는 조치를 추가하거나 메시지를 로그 할 수 있습니다.


55
이 힌트로 문제를 더 잘 디버깅하는 방법을 이해하지 못합니다. 상징적 인 중단 점을 추가했지만 여전히 문제에 대한 충분한 정보를 제공하지 않습니다. 유일한 방법은 한 줄씩 읽고 문제의 원인을 이해하는 것입니다. 그렇지 않으면 제약 조건을 지우고 미리보기를 미리보기와 함께 추가하는 것이 가장 도움이됩니다!
— Alex Cio

11
중단 점에서 정지 한 후 자세한 정보를 얻는 데 도움이 될 수 있습니다. staxmanade.com/2015/06/debugging-ios-autolayout-issues
— fabb

1
IB에서 직접 제약 조건에 식별자를 부여 할 수 있다는 것을 추가하면 디버깅 할 때 볼 수있는 이름입니다.
— Mark A. Donohoe

2
(@MarqueIV의 후속 조치) NSLayoutConstraint는 identifieriOS 7 - Xcode 7 이상 부터 속성 을 가졌으며, IB 스토리 보드와 코드에서 모두 설정할 수 있습니다. 식별자를 설정하여 사용자가 쉽게 디버그 로그에 시스템 생성 및 사용자 생성 제약 구별 할 수, 예를 들어 myConstraint.identifier = "centered image"(소스 및 예 : useyourloaf.com/blog/using-identifiers-to-debug-autolayout )
— PDK

@AlexCio 어떻게 도움이 되나요? 가장 적은 일이 발생하는 순간 일시 중지됩니다. 역 추적하고 원점을 찾을 수있는 스택 추적을 제공합니다.
— Honey

10

Stephen의 조언을 따르고 코드와 whoa를 디버깅하려고했습니다! 효과가있었습니다. 대답은 디버그 메시지 자체에 있습니다.

Will attempt to recover by breaking constraint NSLayoutConstraint:0x191f0920 H:[MPKnockoutButton:0x17a876b0]-(34)-[MPDetailSlider:0x17a8bc50](LTR)>

위의 줄은이 제약 조건을 제거하여 런타임이 작동했음을 나타냅니다. 버튼에 수평 간격이 필요하지 않을 수도 있습니다 (MPKnockoutButton). 이 제약 조건을 지우면 런타임에 불평하지 않으며 원하는 동작을 얻습니다.


3
컴파일러? 런타임을 의미합니까? 컴파일러가 제약 조건을 제거하지 않았습니다. 컴파일러는 런타임에서 처리 할 수 ​​있도록 런타임 상태를 유지하므로 런타임 중에 "제약 조건을 해제하여 복구" 합니다 .
— drhr

그래, 난 런타임 의미
— Sategroup

2

시스템이 깨뜨려야 할 제약 조건을 제거하려고 할 때마다 제약 조건이 더 이상 IB를 충족시키기에 충분하지 않습니다 (즉, IB의 "결석 제약 조건"표시). 불완전하고 사용되지 않음을 의미합니다. 실제로 우선 순위를 낮게 설정하려는 제약 조건을 설정 하여이 문제를 해결했습니다.이 제한은 시스템이 제약 조건을 정상적으로 중단 할 수있게합니다. 아마도 최상의 솔루션은 아니지만 내 문제를 해결하고 결과 제약 조건이 완벽하게 작동했습니다.


2
일반적으로 런타임시 제거되는 자리 표시 자 제약 조건을 사용하려는 상황입니다. 제약 조건을 자리 표시 자 제약 조건으로 만들려면 제약 조건 관리자로 이동하여 "빌드 타임에 제거"를 클릭하십시오. 이를 나타 내기 위해 IB 도면 영역의 구속 조건 I- 빔 기호가 파란색에서 회색으로 어떻게 변하는 지 확인하십시오.
— spencery2

1
나는 같은 문제가 있었다. 깨진 구속 조건을 제거하면 디자인이 깨졌습니다. 그래서 우선 순위를 중간으로 설정했습니다.
— Jeremy Piednoel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.