티스토리 뷰

Swift + iOS/iOS

[ios] Auto Layout Programmatically - 1

군옥수수수 2017. 11. 8. 11:05

Auto Layout Programmatically


처음 iOS 개발을 시작할 때 UI를 구성하는 가장 좋은 방법은 storyboard를 사용하는 것입니다. 위치를 잡기 쉽고 육안으로 확인을 할 수 있기 때문입니다. 저 역시 계속해서 storyboard를 사용해왔습니다. 하지만 항상 모든 영상이나 블로그들의 글을 보면


storyboard로는 한계가 있다. 코드로 작성을 해야할 때가 있다”


사실 이 말에 크게 공감할 일이 없었습니다. 아직까지는 공부를 이제 막 시작한 저에게는 storyboard만으로도 충분히 좋은 결과물을 볼 수 있었습니다.


하지만 협업을 할 일이 생겼고 iOS 프로젝트는 협업을 어떻게 해야하나를 알아보던 중 git을 통해 협업을 하다보면 storyboardconflict가 상당히 많이 일어나는 것을 알게 되었고, 하나의 storyboard파일만 사용하는 것은 옳지 않은 방법이라는 것을 알게 되었습니다.


그래서 직접 코드로 UI를 구성하고 위치시키는 것도 역시 공부를 해보아야겠다는 생각이 들었고 공부한 것을 기록하고자 이렇게 글을 작성하게 되었습니다. 이러한 주제들에 대해서 많은 글들이 있습니다. 꼭 한번 읽어보시기 바랍니다.


  1. iOS User Interfaces: Storyboards vs. NIBs vs. Custom Code
  2. Storyboard vs Programmatically in Swift
  3. stackoverflow - When to use Storyboard and when to use XIBs

그렇다면 오늘은 간단한 UIButtonUILabel을 코드로 만들고 배치시켜보도록 하겠습니다.


1. Create UIButton Programmatically

먼저 viewDidLoad() 안에 버튼을 하나 동적으로 생성해보도록 하겠습니다.

class ViewController:UIViewController {
    let myButton = UIButton()
    override func viewDidLoad(){
        super.viewDidLoad()
        
        myButton.setTitle("This is Button", for: .normal)
        myButton.setTitleColor(.white, for: .normal)
        myButton.backgroundColor = .darkGray
        
        self.view.addSubview(myButton)
    }
}

기본적으로 버튼을 하나 생성하고 superview에 붙여보았습니다. 하지만 실행시켜보면 버튼은 어디에도 보이지 않을 것입니다. 왜냐하면 버튼의 위치와 사이즈를 정해주지 않았기 때문입니다. 그럼 위치와 사이즈를 지정해보도록 하겠습니다.

class ViewController:UIViewController {
    let myButton = UIButton()
    override func viewDidLoad(){
        super.viewDidLoad()
        
        myButton.setTitle("This is Button", for: .normal)
        myButton.setTitleColor(.white, for: .normal)
        myButton.backgroundColor = .darkGray
        myButton.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
        self.view.addSubview(myButton)
    }
}

위와 같은 버튼은 왼쪽 상단의 끝에 위치하게 됩니다.


기본적으로 xy좌표는 좌측 상단에서부터 (0, 0)으로 시작하게 됩니다. 오른쪽 방향이 x의 양의 방향이고, 아래쪽 방향이 y의 양의 방향입니다. 또한 이 좌표 위치는 컴포넌트의 좌측 상단 모서리에 해당하게 됩니다. 즉 좌측 상단의 끝이 위치를 정하는 기준점이 되고 너비와 높이로 컴포넌트의 크기를 정하게 되는 것입니다.


storyboard를 통해 버튼을 위치시킬 때도 여러분은 단순히 버튼을 올려놓기만 하지는 않을 것입니다. 다양한 디바이스에서 일관되거나 혹은 다르게 보이게 하기 위해 Constraints를 사용하실 겁니다. 그럼 이제 우리가 만든 버튼에 Constraints를 코드로 적용시켜보도록 하겠습니다.


2. Set constraints for UIButton Programmatically

Constraints를 적용하기 위해서는 일단 절대적인 위치와 크기를 정해준 코드를 지워주고 코드로 Constraints를 적용시키기 위해서는 반드시 some_View.translatesAutoresizingMaskIntoConstraints = false를 설정해주어야 합니다.

class ViewController:UIViewController {
    let myButton = UIButton()
    override func viewDidLoad(){
        super.viewDidLoad()
        
        myButton.setTitle("This is Button", for: .normal)
        myButton.setTitleColor(.white, for: .normal)
        myButton.backgroundColor = .darkGray
        self.view.addSubview(myButton)
        
        myButton.translatesAutoresizingMaskIntoConstraints = false
    }
}

기본적으로 Constraintssuperview에 붙인 후에 작성해야합니다.

그럼 이제 본격적으로 Constraints를 적용시켜보도록 하겠습니다.

class ViewController:UIViewController {
    let myButton = UIButton()
    override func viewDidLoad(){
        super.viewDidLoad()
        
        myButton.setTitle("This is Button", for: .normal)
        myButton.setTitleColor(.white, for: .normal)
        myButton.backgroundColor = .darkGray
        self.view.addSubview(myButton)
            
        myButton.translatesAutoresizingMaskIntoConstraints = false
        myButton.centerXAnchor.constraint(equalTo:view.centerXAnchor)
            .isActive = true // ---- 1
        myButton.centerYAnchor.constraint(equalTo:view.centerYAnchor)
            .isActive = true // ---- 2
        myButton.heightAnchor.constraint(equalToConstant: 200)
            .isActive = true // ---- 3
        myButton.widthAnchor.constraint(equalToConstant: 200)
            .isActive = true // ---- 4
    }
}
  1. myButtonsuperviewx축을 기준으로 가운데 정렬시키는 코드입니다. 반드시 .isActive = true를 해주어야 적용이 됩니다. 우리가 storyboard로 구성할 때 Horizontal Alignment와 같은 역할입니다.
  2. myButtonsuperviewy축을 기준으로 가운데 정렬시키는 코드입니다. 우리가 storyboard로 구성할 때 Vertical Alignment와 같은 역할입니다.
  3. myButton 너비의 크기를 200으로 고정시켜주는 코드입니다.
  4. myButton 높이의 크기를 200으로 고정시켜주는 코드입니다.

코드로 Constraints를 적용시킬 때는 equalTo, 즉 기준 고정점이 중요합니다.

이렇게 화면에 정가운데로 버튼을 위치시켜보았습니다.


3. Create UILabel and Set constraints for UILabel Programmatically

그렇다면 이제는 기존의 코드에 하나의 UILabel을 코드로 만들고 myButton아래 위치시켜보도록 하겠습니다.

class ViewController:UIViewController {
    let myButton = UIButton()
    let myLabel = UILabel()
    override func viewDidLoad(){
        super.viewDidLoad()
        
        myButton.setTitle("This is Button", for: .normal)
        myButton.setTitleColor(.white, for: .normal)
        myButton.backgroundColor = .darkGray
        self.view.addSubview(myButton)
            
        myButton.translatesAutoresizingMaskIntoConstraints = false
        myButton.centerXAnchor.constraint(equalTo:view.centerXAnchor)
            .isActive = true 
        myButton.centerYAnchor.constraint(equalTo:view.centerYAnchor)
            .isActive = true 
        myButton.heightAnchor.constraint(equalToConstant: 200)
            .isActive = true 
        myButton.widthAnchor.constraint(equalToConstant: 200)
            .isActive = true 
            
        myLabel.text = "This is My Label"
        myLabel.backgroundColor = .white
        self.view.addSubview(myLabel)
        
        myLabel.translatesAutoresizingMaskIntoConstraints = false
        myLabel.topAnchor.constraint(equalTo: myButton.bottomAnchor
            ,constant: 30).isActive = true // ---- 1
        myLabel.leftAnchor.constraint(equalTo: view.leftAnchor
            , constant: 40).isActive = true // ---- 2
        myLabel.rightAnchor.constraint(equalTo: view.rightAnchor
            , constant: -40).isActive = true // ---- 3
    }
}
  1. myLabelmyButton의 밑 변을 기준으로 30만큼 아래로 위치시키는 코드입니다. 즉 myButton의 30만큼 아래에 myLabel을 위치시키는 코드입니다.
  2. myLabelsuperview의 왼쪽 변을 기준으로 40 만큼 떨어뜨려 놓는 코드입니다.
  3. myLabelsuperview의 오른쪽 변을 기준으로 –40 만큼 떨어뜨려 놓는 코드입니다. 여기서 –40인 이유는 x좌표의 양의 방향은 오른쪽이기 때문에 오른쪽에서 40만큼 왼쪽으로 떨어뜨려놓기 위해서는 –40을 사용해야합니다.

4. Add Action to UIButton

우리가 storyboard로 버튼을 생성하고 이를 ViewController로 연결시키면 자동으로 클릭에 대한 액션이 설정됩니다. 하지만 코드로 버튼을 생성한다면 이러한 과정까지 직접해주어야 합니다.


그렇다면 버튼을 눌렀을 때 Alert 창이 뜨는 액션을 만들어보도록 하겠습니다.

class ViewController:UIViewController{
    /*
        code
    */
    override func viewDidLoad(){
        super.viewDidLoad()
        /*
            code
        */
        myButton.addTarget(self, action: #selector(btnClicked),
            for: .touchUpInside)
    }
    
    @objc func btnClicked(){
        let alert = UIAlertController(title: "Click!"
            , message: "You clicked that button"
            , preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Confirm"
            , style: .default , handler: nil))
        
        present(alert, animated: true, completion: nil)
    }
}

마무리

오늘은 이렇게 간단하게 UIButtonUILabel을 코드로 만들고 위치시켜보는 것을 해보았습니다. 이렇게 코드로 Constraints를 적용시킬 때 다음의 두 가지의 코드는 반드시 작성해주셔야 합니다.


  1. some_View.translatesAutoresizingMaskIntoConstraints = false
  2. .isActive = true

그리고 Constraints의 종류에는 storyboard로 적용시킬 때와 마찬가지로 많은 종류가 존재합니다. 다음의 링크를 통해 어떤 종류가 있는지 반드시 숙지해놓으시면 많은 도움이 되실 것입니다.


Working With Auto Layout and Layout Anchors


다음에는 보다 복잡하고 동적인 화면을 코드로 작성해보는 시간을 갖도록 하겠습니다. 감사합니다.


Sourcehttps://github.com/ehdrjsdlzzzz/ios_constraints_programmatically/tree/master/Practice1


참고자료


  1. iOS User Interfaces: Storyboards vs. NIBs vs. Custom Code
  2. Storyboard vs Programmatically in Swift
  3. stackoverflow - When to use Storyboard and when to use XIBs
  4. Working With Auto Layout and Layout Anchors
  5. Lets build that App


공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함