제라스의 iOS 공부/Swift 기능

[Swift 기능] Auto-Layout을 스토리보드 사용하지 않고 코드로 구현

Xerath(제라스) 2023. 9. 18. 01:10
728x90
반응형

iOS의 시작을 스토리보드를 써버릇을 했다.

하지만 React Native에 익숙한 나는 이런 IB(Interface Builder, 스토리보드의 도구들을 이용해서 UI를 구현하는 방식) 구현보다는

차라리 코드로 하는 것이 익숙하다.

 

한번 코드로 Auto-Layout을 잡는 방법을 정리해보자.

 

일단 다음과 같이 잡을 수 있다.

func setUpAutoLayout() {
    view.addSubview(stackView)
    view.addSubview(passwordResetButton)
    
	//코드로 짜면 이 뷰가 자동으로 Frame 기준으로 오토 레이아웃을 잡아줌. 그래서 이걸 꺼줘야 함.
    emailInfoLabel.translatesAutoresizingMaskIntoConstraints = false
    emailTextField.translatesAutoresizingMaskIntoConstraints = false
    emailTextFieldView.translatesAutoresizingMaskIntoConstraints = false

    emailInfoLabel.leadingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8).isActive = true
    emailInfoLabel.trailingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8).isActive = true
    emailInfoLabel.centerYAnchor.constraint(equalTo: emailTextFieldView.centerYAnchor).isActive = true

    emailTextField.leadingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8).isActive = true
    emailTextField.trailingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8).isActive = true
    emailTextField.topAnchor.constraint(equalTo: emailTextFieldView.topAnchor, constant: 15).isActive = true
    emailTextField.bottomAnchor.constraint(equalTo: emailTextFieldView.bottomAnchor, constant: 2).isActive = true


    emailTextFieldView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30).isActive = true
    emailTextFieldView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30).isActive = true
    emailTextFieldView.topAnchor.constraint(equalTo: view.topAnchor, constant: 200).isActive = true
    emailTextFieldView.heightAnchor.constraint(equalToConstant: 40).isActive = true

}

이런 식으로 일단

.translatesAutoresizingMaskIntoConstraints = false

위 코드로 Auto-Layout을 잡도록 짜두고,

 

이후 각 요소들의 Auto-layout을 constraint로 잡는다.

 

근데... 자세히 보면 마지막에

.isActive = true

가 중복적으로 계속 들어가는 것을 볼 수 있다...!!

 

아휴~~~ 이런거 보기 드러우니 하나로 합치자. 다음과 같이 줄일 수 있다.

딴건 볼 필요없고 NSLayoutConstraint.activate 이 함수 내에 배열로 넣어주면 된다.

func setUpAutoLayout() {
        view.addSubview(stackView)
        view.addSubview(passwordResetButton)
        
        emailInfoLabel.translatesAutoresizingMaskIntoConstraints = false
        emailTextField.translatesAutoresizingMaskIntoConstraints = false
        passwordInfoLabel.translatesAutoresizingMaskIntoConstraints = false
        passwordTextField.translatesAutoresizingMaskIntoConstraints = false
        passwordSecureButton.translatesAutoresizingMaskIntoConstraints = false
        stackView.translatesAutoresizingMaskIntoConstraints = false
        passwordResetButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            emailInfoLabel.leadingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8),
            emailInfoLabel.trailingAnchor.constraint(equalTo: emailTextFieldView.trailingAnchor, constant: -8),
            emailInfoLabel.centerYAnchor.constraint(equalTo: emailTextFieldView.centerYAnchor),
            
            emailTextField.leadingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8),
            emailTextField.trailingAnchor.constraint(equalTo: emailTextFieldView.leadingAnchor, constant: 8),
            emailTextField.topAnchor.constraint(equalTo: emailTextFieldView.topAnchor, constant: 15),
            emailTextField.bottomAnchor.constraint(equalTo: emailTextFieldView.bottomAnchor, constant: 2),
            
            passwordInfoLabel.leadingAnchor.constraint(equalTo: passwordTextFieldView.leadingAnchor, constant: 8),
            passwordInfoLabel.trailingAnchor.constraint(equalTo: passwordTextFieldView.trailingAnchor, constant: -8),
            passwordInfoLabel.centerYAnchor.constraint(equalTo: passwordTextFieldView.centerYAnchor),
            
            passwordTextField.topAnchor.constraint(equalTo: passwordTextFieldView.topAnchor, constant: 15),
            passwordTextField.bottomAnchor.constraint(equalTo: passwordTextFieldView.bottomAnchor, constant: -2),
            passwordTextField.leadingAnchor.constraint(equalTo: passwordTextFieldView.leadingAnchor, constant: 8),
            passwordTextField.trailingAnchor.constraint(equalTo: passwordTextFieldView.trailingAnchor, constant: -8),
            
            passwordSecureButton.topAnchor.constraint(equalTo: passwordTextFieldView.topAnchor, constant: 15),
            passwordSecureButton.bottomAnchor.constraint(equalTo: passwordTextFieldView.bottomAnchor, constant: -15),
            passwordSecureButton.trailingAnchor.constraint(equalTo: passwordTextFieldView.trailingAnchor, constant: -8),
            
            stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30),
            stackView.heightAnchor.constraint(equalToConstant: textViewHeight*3 + 36),
            
            passwordResetButton.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 10),
            passwordResetButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30),
            passwordResetButton.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30),
            passwordResetButton.heightAnchor.constraint(equalToConstant: textViewHeight),
        ])
    }

 

728x90
반응형