ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Swift 로 iOS 앱 만들기 - 04 : SnapKit 사용 / leading 과 trailing
    Swift 2019. 7. 2. 20:59

     

    [예제] SnapKit을 이용하여 Label, TextField, Button 을 만들어보자. - 02

    [추가] leading 과 trailing 에 대해서 알아보자.

     

     

    01. Label, TextField, Button 추가하기

    viewController.swift 에서 내가 추가하고자 하는 요소들을 입력한다.

    let 이름(원하는 것으로) = 넣고자 하는 요소()

    넣고자 하는 요소 뒤에 " () " 를 붙여 주어 개체로 만들어 준다.

     

     

     

    02. Label, TextField, Button 등록하기

    내가 넣고자 하는 요소를 추가하고 나서 잘 들어 갔는지 디버그로 확인을 해보면, 빈 화면인 것을 볼 수 있다.
    빈 화면인 이유는 아직 내가 넣을 요소들을 추가만 했을 뿐 등록하지 않았기 때문이다.
    따라서 요소를 화면에 등록을 하도록 한다.

     

    self.view.addSubview(self.nameLabel)

    해당 코드를 풀어서 보자면,

     

    ViewController가 디버그 할 때 파란색 선이라면, 실제로 눈에 보이는 영역, 빨갛게 혹은 하얗게 배경색을 넣었던 부분.
    즉 요소가 보이는 부분은 view다. 따라서

    self.view

     

    addSubview는 매개변수로 추가할 뷰를 받는다.
    따라서 내가 뷰에다가 등록을 할 건데 무엇을 등록할지 매개변수로 넣어주면 된다.
    이때, 당연히 나는 class 안에서 선언한 nameLabel을 매개변수로 넣어줄 것인데,
    이때 중요한 것은 class 안에 상수/변수를 선언한 후에 그것을 쓸 때는 꼭 self.상수/변수 로 써야 한다.
    왜냐하면 self의 의미가 class 자체 이기 때문이다. 따라서 나는 class 안에 선언한 상수 nameLabel을 쓸 것이기 때문에

    addSubview(self.nameLabel)

     

     

    Textfeild와 Button도 똑같이 써준다.

    self.view.addSubview(self.nameTextFeild)
    self.view.addSubview(self.changeButton)

     

    03. Label, TextField, Button 위치 잡아주기

    등록을 하였지만, 아직 위치를 잡아 주지 않아서 디버그를 했을 때 보이지 않는다.
    따라서 위치를 잡아 줘야 그 위치에 요소들이 배치 될 것이다.

     

    예를 들어 이런 모양의 화면을 구현 하자고 가정해보자.

     

    • 화면 중앙에 Button 배치하기
    self.changeButton.snp.makeConstraints { 
    	  $0.center.equalToSuperview() 
        }

     

    해당 코드를 풀어서 보자면,

     

     

    class 내에서 선언한 changeButton 이기 때문에

    self.changeButton

     

     

    SnapKit 을 사용하여서 배치 할 것이기 때문에

    .snp

     

     

    위치를 잡아주는 것이기 때문에

    .makeConstraints

    $0 = self.changeButton

     

     

    View의 정 중앙에 배치 할 것이기 때문에

    center.equalToSuperview()

     

     

    이제 디버그로 확인을 해보면 아직 배경색이나 기타 속성을 지정해주지 않았기 때문에 잘 보이지 않지만,

    분명하게 정 가운데에 버튼이 생긴 것을 볼 수 있다.

    • 화면 상단에 Label 배치하기

    self.nameLabel.snp.makeConstraints{ 
    	  $0.top.equalToSuperview().offset(80) 
      }

     

    화면 정중앙에 배치했던 Button과 똑같지만 view의 top 기준이기 때문에

    top.equalToSuperview()

     

    top 기준 80만큼 내려와 있기 때문에

    .offset(80)

     

     

    이제 위에서 80 만큼 내려오기는 했다. 그러면 좌우 24는 어떻게 맞출까?

    우선 왼쪽 오른쪽 여백을 맞춰야 하는데, 이때 내가 쓰던 언어와 다른 점은 left와 right가 아닌

    leading 과 trailing 을 쓴다는 점이다.

     

    • leading은 시작하는 방향
    • trailing은 끝나는 방향

     

     

    으로 생각하면 된다.
    왜 굳이? 이렇게 쓰냐고 하니, 우리나라처럼 왼쪽부터 글을 읽고 쓰는 문화가 있는 반면에, 오른쪽부터 읽고 쓰는 문화가 있다.
    만약 왼쪽부터 글을 읽고 쓰는 문화에 맞춰서 앱을 만들면 후에 오른쪽 부터 읽고 쓰는 문화에서는 그 앱을 이용할 때 불편함이 따를 수 있다는 것이다.

    따라서 무조건 왼쪽(left)이 시작이 아닐수도 있기 때문에, 각 요소들의 시작하는 점은 leading으로 끝나는 점은 trailing으로 쓴다고 한다.
    무조건 left, right만 썼던 나에게는 신기한 부분이었다.

     

    또 알아두어야 하는 점은

    예를 들어 다음과 같은 화면이 있을 때 좌측 상단이 (0,0) 이라면 우측 하단은(100,100) 이다.
    이때 앱은 읽는 방향이 좌측 상단 에서 우측 하단으로 내려가게 되는데, 좌측상단 (0,0)에서 우측과 아래로 내려갈 수록 (100,100)에는 가까워 지기 때문에 '+' 가 되는 것이고, 우측하단(100,100)에서 위로 올라갈 수록 (0,0)에 가까워 지기 때문에 '-' 가 된다.

     

     

     

    자 그럼, label이 시작하는 지점 leading 위치까지 적용해보자.

    self.nameLabel.snp.makeConstraints{ 
    	   $0.top.equalToSuperview().offset(80) 
           $0.leading.equalToSuperview().offset(24) 
        }

     

    View의 시작점 기준이기 때문에

    leading.equalToSuperview()

     

    '+'의 방향 (우측)으로 24만큼 이기 때문에

    .offset(24)

     

     

    마지막으로 label이 끝나는 지점 trailing 위치까지 적용해보자.

    self.nameLabel.snp.makeConstraints{ 
    	  $0.top.equalToSuperview().offset(80) 
          $0.leading.equalToSuperview().offset(24) 
          $0.trailing.equalToSuperview().offset(-24) 
      }

     

    View의 끝나는점 기준이기 때문에

    trailing.equalToSuperview()

     

    '-'의 방향 (좌측)으로 24만큼 이기 때문에

    .offset(-24)

     

     

    • Label 기준으로 TextFeild 배치하기

    TextFeild는 Label과 leading, trailing은 같고, Label bottom 기준으로 24 만큼 아래에 있다.

    self.nameTextField.snp.makeConstraints{ 
    	  $0.top.equalTo(self.nameLabel.snp.bottom).offset(24) 
          $0.leading.equalTo(self.nameLabel) 
          $0.trailing.equalTo(self.nameLabel) 
      }

     

    button이나 label과 다른게 TextField는 View 기준이 아니고 Label의 bottom 기준이기 때문에

    equalTo(self.nameLabel.snp.bottom)

     

    leading과 trailing이 Label의 leading과 trailing의 기준과 같기 때문에

    leading.equalTo(self.nameLabel)
    trailing.equalTo(self.nameLabel)

     

     

    이때, 중복되는 부분이 많은 것을 볼 수 있는데 위 코드는 아래의 코드로 줄여서 쓸 수 있다.

    $0.leading.equalTo(self.nameLabel) 
    $0.trailing.equalTo(self.nameLabel) 
    
    // 아래처럼 줄여서 쓸 수 있다. 
    $0.leading.trailing.equalTo(self.nameLabel)

     

    그러면 다음과 같이 코드가 작성된다.

     

    04. 코드 정리하기

    현재 내가 써놓은 부분은 viewDidLoad()안이다.
    viewDidLoad() 이 부분은 지금은 코드가 없지만, 후에 개발을 하다보면 수많은 코드가 들어가는 부분이기도 하고,
    뷰 를 올리는 코드나, 뷰의 위치를 작성하는 코드는 대규모 업데이트 전까지는 건드리는 일이 적기 때문에 후에 유지보수를 위해서라도 viewDidLoad()에 쓰지 않는 것이 좋다고 한다.  따라서 아래 함수로 빼서 호출을 하는 것이 좋다.

     

    다음과 같이 정리해준다.

    기존의 코드를 복사를 해서 viewDidLoad() 아래에 새로운 함수를 작성하고 그 안에 코드를 넣는다.

    그리고 viewDidLoad() 안에서는 함수를 호출 하기만 한다.

    viewDidLoad() 안 코드가 훨씬 보기 좋아졌다!

     

     

     

     

    -

    * 본 글은 글쓴이가 스터디를 하고 배운 내용을 정리하는 식으로 쓰여지기 때문에 완전 초보자의 글입니다. 
    틀린 부분이 있을 수도 있고 글의 흐름이 일정하지 않을 수 있습니다.*

    -

     

     

    댓글

Designed by Tistory.