[TIL] UIButton Action, Delegate Methods, 비율 설정

고라니·2023년 7월 20일
0

TIL

목록 보기
13/67

오늘은 이전에 배운 내용들을 활용하여 간단한 로그인/회원가입 기능을 구현해보았다.
과정 중 소소하게 배운 점들을 정리 해본다.

UIButton action함수 naming

함수명이나 변수명 등 어느정도 규칙이 있지만 아무래도 완벽하게 정해지진 않아서 가끔 적합한 이름을 선별하기 위해 고민이 되는 경우가 많았다. 그 중 오늘은 버튼 액션 함수명은 보편적으로 어떻게 정하는지 궁굼해서 알아보았다.

UIButton의 액션 함수 이름은 그 버튼이 수행하는 작업을 반영해야 한다. 함수 이름은 이벤트를 드러내는 동사로 시작하고, 그 액션이 무엇인지 설명하는 명사로 끝나는 경우가 많다고 한다. (다른 메서드도 마찬가지)

보편적으로 많이 쓰이는 이름: "☐ ☐ ButtonPressed", "☐ ☐ ButtonTapped", "작업을 반영한 순수한 이름"

예시

로그인 버튼의 경우 "loginButtonTapped" 또는 "loginButtonPressed", "handleLogin" 등이 될 수 있다.

다만, 로그인 버튼을 눌렀을 로그인을 하기위한 어떠한 추가적인 작업이나 과정이 있다면 그 과정에 관한 메서드를 따로 만들어서 버튼 함수에서 호출하게 하는것이 좋다. 버튼 함수 이름만으로는 어떤 과정이 이루어지는지 알기 힘들기 때문이다.

Delegate Method 함수 호출

iOS, Swift는 Delegate 패턴을 많이 사용한다. 그래서 Delegate의 요구 함수를 구현하는 경우가 많은데 오늘 여러 예시 코드를 봤는데 많은 코드들이 Delegate함수 블럭에서 다른 함수만 호출하는 경우가 많았다. 처음에는 불필요하게 왜 함수를 새로 만들어서 호출하게 하는지 이해하지 못했지만 잠시 자리를 비우고 돌아온 뒤 이유를 체감하게 되었다.

일단 내가 본 예시 코드를 보자

    func textFieldDidChangeSelection(_ textField: UITextField) {
        checkTextFieldInputs()
    }

    private func checkTextFieldInputs() {
        if let id = idTextfield.text, let pw = passwordTextField.text, !id.isEmpty, !pw.isEmpty {
            loginButton.isEnabled = true
        } else {
            loginButton.isEnabled = false
        }
    }

참고로 해당 코드 내용은 알 필요 없음

내 의문은 checkTextFieldInputs를 따로 만들지 않고 바로 textFieldDidChangeSelection에 구현하지 않았을까? 하는 생각이었다. 그래서 나의 프로젝트에는 따로 checkTextFieldInputs처럼 메서드를 새로 만들지 않고 델리게이트 메서드에 바로 구현 하였다.

func textFieldDidChangeSelection(_ textField: UITextField) {
        if let id = idTextfield.text, let pw = passwordTextField.text, !id.isEmpty, !pw.isEmpty {
            loginButton.isEnabled = true
        } else {
            loginButton.isEnabled = false
        }
    }

잠시 자리를 비우고 온 후 이 방식의 문제점을 알 수 있었다.
textFieldDidChangeSelection이 무슨 작업을 처리하는지 내부 블럭을 모두 읽어야 이해할 수 있었다. 반면 checkTextFieldInputs() 메서드로 작성한 경우 textFieldDidChangeSelection가 어떤 작업을 처리하는지 바로 알수 있어서 가독성(Readability) 이 좋았다. 또한 checkTextFieldInputs()를 재사용(Reusability) 가능하여 코드의 중복을 줄일 수 있었다.

결론적으로 특정 코드 조각이 여러 위치에서 사용되거나, 코드의 의도를 명확히 하려는 경우에는 첫 번째 방식이 좋다.
물론 후자의 경우도 코드가 간결해진다는 장점이 있기 때문에 간단한 기능이라면 후자 처럼 작성해도 된다.

StoryBoard에서 너비or높이 비율 정하기

스택뷰 안에 이미지뷰와 텍스트필드가 필요했고 비율이 1:2 비율로 위치하고 싶어서 해당 방법을 알아보았다.

이 경우처럼 이미지 뷰가 텍스트필드의 절반크기 비율로 설정하고 싶었다.
해결 방법은 바로 equal width이다. 너비를 같게 하는 것이기 때문에 몰랐는데 비율 조절이 가능하다.

원하는 비율이 적용되었다.

"Content hugging priority"과 "compression resistance priority"

이름이 너무 길어서 무섭지만 개념은 간단하다.

Content hugginh priority

공간을 채우기 위해 두 개 이상의 뷰가 늘어나야 할때 사용한다.
값이 상대적으로 작은 뷰가 늘어나고, 값이 큰 뷰는 기존 크기를 유지한다.

예시

1. 두개의 라벨이 있다.

2. 좌측 라벨의 제약 조건으로 좌측,우즉,상단을 20씩 설정한다.

3. 우측 라벨도 마찬가지로 제약 조건으로 좌측,우즉,상단을 20씩 설정한다. 서로 좌우측으로 20씩 붙으려고 하니까 올바른 위치를 찾기 못한다.

4. 이떄 좌측 라벨의 Content hugging priority의 값을 감소시키면?

5. 상대적으로 값이 낮아진 좌측 라벨이 제약 사항에 맞게 늘어나는것을 볼 수 있다.

compression resistance priority

공간이 축소되어 두 개 이상의 뷰 중 축소되어야 할때 사용한다.
값이 상대적으로 작은 뷰가 축소되고, 값이 큰 뷰는 기존 크기를 유지한다.

Content hugginh priority와 작동 방식이 유사 함 (이미지 설명은 없다...)

마무리

오늘은 소소하게 깨닳은 것들에 대해 정리해 보았다. 명확하고, 가독성이 좋고, 재사용 가능한 코드를 작성하는 것의 중요성을 직접 체감하게 되었다. 친절한 개발을 위해 이런것들을 항상 신경써서 학습해야 겠다.

profile
🍎 무럭무럭

2개의 댓글

comment-user-thumbnail
2023년 7월 20일

소중한 정보 잘 봤습니다!

1개의 답글