Swift + iOS/iOS

[ios] AutoLayout - Unable to simultaneously satisfy constraints

군옥수수수 2018. 3. 12. 09:42

[ios] AutoLayout - Unable to simultaneously satisfy constraints


안녕하세요. 오늘은 제가 오토레이아웃을 사용하면서 콘솔창에 생기는 에러 메시지들의 의미를 파악하고 해결한 것을 기록하고자 이렇게 글을 작성하게 되었습니다.


저는 코드를 이용하여 동적으로 오토레이아웃을 자주 변경하는 편입니다. 하지만 가끔 작동은 되지만 알 수 없는 오토레이아웃 에러 메시지들이 콘솔창에 출력이 되고 평소에는 이를 무시하였으나 오늘은 이를 확실히 알고 싶어 살짝 공부해보았습니다.


먼저 에러가 났던 코드는 다음과 같습니다.


  • 코드를 이해하실 필요는 없습니다. 간단히 말씀드리자면 오토레이아웃의 초기 설정은 setupPlayerDetailView입니다. 하지만 특정 액션이 주어지면 maximizeAnimation에 정의한 오토레이아웃 설정으로 변경되면서 애니메이션이 수행되게 됩니다.

위의 코드에서 maximizeAnimation이 호출될 때 다음과 같은 메시지가 콘솔창에 출력되었습니다.


와…..!! 정말 저는 이 메시지들을 보고 경악을 금치못하였습니다. 변수명이 존재하는 것도 아니고 작동은 되는데 이 메시지가 출력이 되는 이유도 모르겠고...! 그냥 무시할까도 생각했지만 오늘은 무시하지 않고 이를 해결하고자 하였습니다.


먼저 대충 뜻을 해석해보자면 Constraint들을 동시에 만족할 수 없고 아마 다음 리스트들 중에서 최소 한 개는 당신이 의도하지 않는 Constraint가 있을 것이라는 메시지입니다. 즉 제가 의도하지 않은 Constraint가 있고 이러한 Constraint 때문에 Constraint간 충돌이 일어난 것으로 보입니다.


이러한 의도를 파악해도 어떤 Constraint인지 저런식으로 되어있다면 파악하기 힘들 것입니다. 하지만 이렇게 느끼는 것은 저뿐만이 아니였나봅니다. 이런 불편하고 알아보기 어려운 메시지들을 개발자들이 가만히 있을리가 없죠! 그리하여 그들은 https://www.wtfautolayout.com/를 만들었습니다.


위 사이트는 위의 ( ) 안에 나열된 리스트들을 붙여넣으면 이를 알아보기 수월한 형태로 바꿔줍니다. 제 콘솔창에 출력된 Constraint들을 붙여 넣어봤습니다. 결과는 다음과 같습니다.



처음에는 딱히 이상을 느끼지 못하였습니다. 하지만 마지막 두 개의 항목을 보시면 문제가 무엇인지 알 수 있습니다. 바로 EpisodeDetailViewtop edge를 결정하는 Constraint 두 개가 서로 충돌하는 모습을 볼 수 있습니다. 저는 동시에 두 개의 Constraint를 주지 않았는데 저러한 문제가 일어난다는 것을 도무지 이해할 수 없었습니다. 그리고 인내의 시간이 흐른뒤...!! 저는 그 원인을 알 수 있었습니다.


원인은 바로 maximizeAnimation코드 안에 있었습니다.


문제는 바로 1,2번 라인입니다. 그 중에서도 해당 메시지는 1번 라인에서 발생하게 됩니다. 그 이유는 현재 ConstrainttopAnchor에 대해 minimizedTopAnchorConstraint가 활성화되어 있는 상태입니다. 하지만 거기에 같은 topAnchor에 대한 Constraint이지만 maximizedTopAnchorConstraint를 활성화시켜버리니 maximizedTopAnchorConstraintminimizedTopAnchorConstraint가 충돌이 일어나는 것입니다. 이를 해결하기 위한 방법은 매우 간단합니다. 두 개의 순서를 바꿔주면됩니다. 즉 충돌이 일어나는 것을 회피하고자 먼저 이전의 Constraint를 비활성화하고 그 이후에 다음 순서의 Constraint를 활성화 시켜주면 됩니다.



마무리

오늘은 이렇게 Constraint가 충돌하여 생기는 메시지에 대한 의미를 알아보고 이를 좀 더 쉽게 파악하는 방법과 충돌의 원인과 이를 해결하기 위한 방법들에 대해 알아보고 제가 해결한 방법을 기록해보았습니다. 상당히 많은 시간이 걸렸지만 의외로 매우 간단한 문제였고 이를 통해 많은 것을 배운 시간이었습니다. 감사합니다.