[Swift] ViewController로 메모 앱 만들기(7) : 오토레이아웃

Oni·2023년 9월 4일
0

TIL

목록 보기
23/47
post-thumbnail

원문 포스팅 🔗

날짜 기능까지 다 넣고 시뮬레이터를 돌려보고 문제 없다고 생각했는데, 팀원분께서 아이폰 8로 돌려보면 다 깨진다고 하셔서 나도 확인해봤다.

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 처참히 일그러진 앱,,,, 그래서 부랴부랴 오토레이아웃에 대해 찾아봤고, 결론은 잘 적용됐다!
본 포스팅에서는 찾아본 내용을 공유하고 내 화면에는 어떤 식으로 적용했는지 정리하려고 한다.

🤳🏻 적용화면


오토레이아웃

오토레이아웃은 이름만 들어도 예상되듯이 사용하는 기기에 따라 객체들이 의도한 위치에 맞게 배치될 수 있게 레이아웃을 자동으로 설정해주는 기능이다.

예를 들어 메인화면의 이미지뷰와 버튼들로 설명하자면, 아래와 같이 제약 조건을 들 수 있다.

  • 이미지뷰는 위쪽과 간격이 유지되어야 하며, 왼쪽 간격 == 오른쪽 간격 또는 가운데 정렬이 되어야 한다.
  • 첫번째 버튼은 왼쪽 간격 == 오른쪽 간격 또는 가운데 정렬이 되어야하며, 이미지뷰와 간격이 유지되어야 한다.
  • 두번째 버튼은 왼쪽 간격 == 오른쪽 간격 또는 가운데 정렬이 되어야하며, 첫번째 버튼과 간격이 유지되어야 한다.

상기 조건을 만족하기 위해서 스토리보드에서 오토레이아웃을 적용하는 방법은 아래와 같다.

먼저 control 버튼과 이미지뷰를 동시에 클릭하고 왼쪽 여백으로 드래그를 하면 파란색으로 View가 표시된다. 이때 클릭을 해제하면 오른쪽 사진과 같은 팝업창이 뜨는데, 지금은 왼쪽 여백을 지정해야 하므로 Leading Space to Safe Area를 클릭한다. 같은 방법으로 오른쪽 여백으로 드래그하면 Trailing Space to Safe Area를 클릭하면 된다.

위쪽과의 여백을 설정하려면 같은 방법으로 드래그하고 Top Space to Safe Area를 선택하면 된다.

이제 추가된 Constraints의 여백을 지정해야하는데 해당 여백은 오른쪽 Inspector에서 확인할 수 있으며, 스토리보드 Document Outline에 Constraints에 추가된 항목을 클릭하면 수정할 수 있다.

상기와 같은 방법으로 객체간의 위치를 지정하면 해상도가 달라져도 지정한 여백에 따라 보여지기 때문에 아까와 같은 불상사는 일어나지 않을 것이다.

그리고 객체를 선택하고 하단 Add New Constaints를 누르면 좀 더 간편하게 상하좌우 간격을 지정할 수 있다. 객체에 따라서 width나 height를 필수로 지정해야 하는 사항도 있으니 여기서 지정해줘도 된다.

이런식으로 뷰컨트롤러에 들어가 있는 객체에 대한 여백을 모두 지정하였으나, 디테일페이지에서는 좌우간격만 지정해서 아래 사진과 같이 빨간 에러(같지만 빌드는 됨)가 떴다.

문제가 있는 레이아웃에 대한 경고를 뷰컨트롤러 타이틀 옆에 빨간 화살표로 안내해주고, 들어가보니까 Memo Text View와 Date Label의 height가 지정이 되지 않았다고 한다.
그도 그럴것이 해당 텍스트뷰에는 텍스트 길이에 맞게 높이를 지정하는 코드를 넣었고, 라벨의 경우는 높이값을 넣었는데도 해당 메세지가 사라지지 않더라.
내 의도는 메모 길이에 따라 바로 아래에 작성(수정)날짜가 붙어서 나오는 형태를 원했는데, 그렇게 하려면 텍스트뷰의 길이를 지정할 수는 없었다. 해당 메세지가 뜨더라도 빌드는 되지만 아무래도 빨간색이 해결하지 않으면 안될 것 같은 느낌을 준다..😭

텍스트뷰 관련 코드

extension DetailViewController : UITextViewDelegate {
    
    func textViewDidChange(_ textView: UITextView) {
        let size = CGSize(width: view.frame.width, height: .infinity)
        let estimatedSize = textView.sizeThatFits(size)
        
        textView.constraints.forEach{ (constraint) in
            if constraint.firstAttribute == .height {
                constraint.constant = estimatedSize.height
            }
        }
    }
}

어찌됐든 해상도에 따라 깨지는 문제는 해결해서 만족스럽다! 디테일페이지 Missing Constraints는 좀 더 생각해봐야겠다.

profile
하지만 나는 끝까지 살아남을 거야!

0개의 댓글