순진이의 하루/study정리

4. CustomView_2022.08.10

순진이 2022. 8. 9. 19:44

CustomView 만들기

import UIKit

class InputView: UIView {
    // 1️⃣
    enum TextFieldType: String {
        case id = "아이디"
        case password = "패스워드"
    }
    
    private let inputLabel = UILabel()
    private let inputTextField = UITextField()
    
    // 2️⃣
    var text: String? {
        return inputTextField.text
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    init(type: TextFieldType) {
        super.init(frame: .zero)
        inputLabel.text = type.rawValue
        inputLabel.font = UIFont.systemFont(ofSize: 13)
        inputLabel.textColor = .gray
        
        inputTextField.borderStyle = .roundedRect
        inputTextField.keyboardType = .default
        inputTextField.autocapitalizationType = .none
        
        if type == .password {
            inputTextField.isSecureTextEntry = true
        }
        setUI()
    }
    
    func setUI() {
        addSubview(inputLabel)
        addSubview(inputTextField)
        inputLabel.translatesAutoresizingMaskIntoConstraints = false
        inputTextField.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            inputLabel.topAnchor.constraint(equalTo: topAnchor),
            inputLabel.leadingAnchor.constraint(equalTo: leadingAnchor),
            inputTextField.topAnchor.constraint(equalTo: inputLabel.bottomAnchor, constant: 8),
            inputTextField.leadingAnchor.constraint(equalTo: leadingAnchor),
            inputTextField.trailingAnchor.constraint(equalTo: trailingAnchor),
            inputTextField.heightAnchor.constraint(equalToConstant: 40),
            inputTextField.bottomAnchor.constraint(equalTo: bottomAnchor)
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

1️⃣

enum 타입을 만들고 rawValue를 설정하여, 이후 String값으로 인한 오류 발생 가능성을 낮춤.

rawValue를 쓰고 싶을 때는 .rawValue로 사용해주면 되고, 객체를 찍어낼 때 아래처럼 쓰면 됨.

    let idInputView = InputView(type: .id)
    let passwordInputView = InputView(type: .password)

 

2️⃣

외부에서 inputLabel, inputTextField에 접근할 수 없도록 private으로 접근제어 해놓음

접근이 필요할 때는 text와 같은 변수를 하나 선언해서 text만 통해서 접근하면 됨.

 


import UIKit

class ViewController: UIViewController {

    let loginLabel = UILabel()
    
    let idInputView = InputView(type: .id)
    let passwordInputView = InputView(type: .password)
    
    let loginButton = UIButton(type: .system)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loginLabel.text = "로그인"
        loginLabel.font = UIFont.systemFont(ofSize: 25, weight: .bold)

        
        loginButton.setTitle("로그인", for: .normal)
        loginButton.backgroundColor = .systemBlue
        loginButton.setTitleColor(.white, for: .normal)
        loginButton.layer.cornerRadius = 4
        loginButton.addTarget(self, action: #selector(loginButtonTapped(_:)), for: .touchUpInside)
 
        setUI()
    }
    
    func setUI() {
        view.addSubview(loginLabel)
        view.addSubview(idInputView)
        view.addSubview(passwordInputView)
        view.addSubview(loginButton)
        
        loginLabel.translatesAutoresizingMaskIntoConstraints = false
        idInputView.translatesAutoresizingMaskIntoConstraints = false
        passwordInputView.translatesAutoresizingMaskIntoConstraints = false
        loginButton.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            loginLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 200),
            loginLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            
            idInputView.topAnchor.constraint(equalTo: loginLabel.bottomAnchor, constant: 40),
            idInputView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            idInputView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            
            passwordInputView.topAnchor.constraint(equalTo: idInputView.bottomAnchor, constant: 40),
            passwordInputView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
            passwordInputView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20),
            
            loginButton.topAnchor.constraint(equalTo: passwordInputView.bottomAnchor, constant: 92),
            loginButton.widthAnchor.constraint(equalToConstant: 100),
            loginButton.centerXAnchor.constraint(equalTo: view.centerXAnchor)
        ])
    }
    
    @objc func loginButtonTapped(_ sender: UIButton) {
        //                     ⬇️                                       ⬇️
        guard let id = idInputView.text, let password = passwordInputView.text else { return }
        if LoginManager().check(id: id, password: password) {
            //login
            present(HomeViewController(), animated: true)
        } else {
            let alert = UIAlertController(title: "로그인 실패", message: "아이디 혹은 비밀번호를 확인하세요.", preferredStyle: .alert)
            let confirmAction = UIAlertAction(title: "확인", style: .default)
            alert.addAction(confirmAction)
            present(alert, animated: true)
        }
    }
}

private으로 선언한 inputLabel과 inputTextField에는 접근할 수 없으므로, 접근을 위해 만들어둔 text를 통해 접근함.