꾸준히 안타치기

UIButton(스토리보드, code) 본문

iOS/기본편 | 실전편 -꼼꼼한재은씨

UIButton(스토리보드, code)

글자줍기 2022. 2. 4. 18:41
반응형

1) CSButton2.swift / 커스텀클래스 작성후, 스토리보드에서 연결해서 버튼 만들기 

1.버튼 클래스를 만들고, 스토리보드에서 사용하는 초기화 메소드 init을 한다.

import UIKit

class CSButton2 :UIButton {
    // 스토리보드에서 사용하는 초기화 메소드는 init(coder:)로 정해져 있다.
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        
        // 스토리보드 방식으로 버튼을 정의했을때 적용됨
        self.backgroundColor = .green
        self.layer.borderWidth = 2
        self.layer.borderColor = UIColor.black.cgColor
        self.setTitle("버튼", for: .normal)
    }
}

2.메인스토리보드에서 버튼을 하나 임의로 만든다.

3. 클래스를 작성한 CSButton으로 변경해준다. 녹색버튼 완성!

 


2) CSButton.swift / 커스텀클래스 생성 , ViewController에 버튼코드를 작성해서 연결하기

프로그래밍방식

enum으로 케이스를 나눠서 정의해두고 가져다 사용할수 있다.

액션메소드를 정의하는 위치는 주로 뷰컨트롤러 이지만, 객체 자체 클래스 내부에서도 액션 메소드를 정의 할수 있다.

이 메소드는 해당타입을 사용하는 모든 곳에 일괄로 적용된다.

1. CSButton.swift / 버튼 클래스 생성

import UIKit

public enum CSButtonType {
    case rect // 네모버튼
    case circle // 원형?버튼
}

class CSButton: UIButton {
    
    // 버튼이 클릭된 횟수를 카운트하여 타이틀에 표시해 주는 함수
    @objc func counting(_ sender: UIButton){
        sender.tag = sender.tag + 1
        sender.setTitle("\(sender.tag)번째 클릭", for: .normal)
      
    }
    
    // 버튼 초기값 2개 스타일
    convenience init(type: CSButtonType){
        self.init()
        // csButton 타입의 모든 버튼에 터치이벤트가 발생할때마다 메소드 호출******** 액션메소드
        self.addTarget(self, action: #selector(counting(_:)), for: .touchUpInside)
        
        switch type {
        case.rect :
            self.backgroundColor = .black
            self.layer.borderColor = UIColor.black.cgColor
            self.layer.borderWidth = 2
            self.layer.cornerRadius = 0
            self.setTitleColor(.white, for: .normal)
            self.setTitle("Rect Button", for: .normal)
            
        case.circle :
            self.backgroundColor = .red
            self.layer.borderColor = UIColor.black.cgColor
            self.layer.borderWidth = 2
            self.layer.cornerRadius = 50
            self.setTitleColor(.white, for: .normal)
            self.setTitle("circle Button", for: .normal)
        }
    }
}

옵저버 프로퍼티를 적용해서 프로퍼티의 값이 변할때마다 자동으로 호출한다.

 

프로퍼티 옵저버란? 특정 프로퍼티의 값이 변할 때마다 자동으로 호출된다. 값변경을 감시하는 이벤트 리스너라고 할 수 있다.
프로퍼티의 값이 변경될때 그에 맞춰 특정 코드를 실행하기 위한 목적으로 사용된다.

didSet - 프로퍼티값이 변경된 직후에 수행되는 블록

willSet - 프로퍼티값이 변경되기 직전에 수행되는 블록

최종코드

더보기
import UIKit

public enum CSButtonType {
    case rect // 네모버튼
    case circle // 원형버튼
}

class CSButton: UIButton {
    
    // 버튼타입스타일 저장,기본값 rect스타일 *****************************************
    // 옵저버 프로퍼티 didSet을 이용해 특정 프로퍼티 값이 변할때 자동으로 호출된다.
    var style: CSButtonType = .rect{
        didSet{
            switch style {
            case.rect :
                self.backgroundColor = .black
                self.layer.borderColor = UIColor.black.cgColor
                self.layer.borderWidth = 2
                self.layer.cornerRadius = 0
                self.setTitleColor(.white, for: .normal)
                self.setTitle("Rect Button", for: .normal)
                
            case.circle :
                self.backgroundColor = .red
                self.layer.borderColor = UIColor.black.cgColor
                self.layer.borderWidth = 2
                self.layer.cornerRadius = 50
                self.setTitleColor(.white, for: .normal)
                self.setTitle("circle Button", for: .normal)
            }
        }
    }
  
    // 버튼이 클릭된 횟수를 카운트하여 타이틀에 표시해 주는 함수
    @objc func counting(_ sender: UIButton){
        sender.tag = sender.tag + 1
        sender.setTitle("\(sender.tag)번째 클릭", for: .normal)
      
    }
    
    // 버튼 초기값 2개 스타일
    convenience init(type: CSButtonType){
        self.init()
        // csButton 타입의 모든 버튼에 터치이벤트가 발생할때마다 메소드 호출******** 액션메소드
        self.addTarget(self, action: #selector(counting(_:)), for: .touchUpInside)
        
        switch type {
        case.rect :
            self.backgroundColor = .black
            self.layer.borderColor = UIColor.black.cgColor
            self.layer.borderWidth = 2
            self.layer.cornerRadius = 0
            self.setTitleColor(.white, for: .normal)
            self.setTitle("Rect Button", for: .normal)
            
        case.circle :
            self.backgroundColor = .red
            self.layer.borderColor = UIColor.black.cgColor
            self.layer.borderWidth = 2
            self.layer.cornerRadius = 50
            self.setTitleColor(.white, for: .normal)
            self.setTitle("circle Button", for: .normal)
        }
    }
}

2. ViewController에서 작성한 커스텀클래스 버튼 불러오기

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 인자값에 따라 다른 스타일로 결정되는 버튼1
        let rectBtn = CSButton(type: .rect)
        rectBtn.frame = CGRect(x: 30, y: 200, width: 150, height: 30)
        self.view.addSubview(rectBtn)
        
        // 인자값에 따라 다른 스타일로 결정되는 버튼2
        let circleBtn = CSButton(type: .circle)
        circleBtn.frame = CGRect(x: 200, y: 200, width: 150, height: 30)
        self.view.addSubview(circleBtn)
        
        // 프로퍼티옵저버 사용으로, 버튼을 생성한 후에도 스타일 변경이 가능하다.
//        circleBtn.style = .rect // 타원 형태로 정의된 버튼의 스타일을 다시 사각형으로 설정
    }
}

커스텀 버튼 타입 자체의 기능을 구현할 목적이나 모든 버튼 객체에 일괄로 기능을 적용해야 할때는  커스텀 내부에 액션 메소드를 정의하는 것이 좋다. 

-> 그래야 반복적인 코드를 줄일수 있고, 코드도 깔끔하게 정리할수 있다.

 

버튼의 개별적인 사용목적을 위해 액션 메소드를 구현할때는 커스텀 클래스 외부에 메소드를 정의하는 것이 좋다. 비지니스 로직에 관련된 기능은 커스텀클래스 외부에 작성하는 것을 원칙으로 한다.

액션메소드를 커스텀 클래스 내부에 정의 커스텀 버튼 타입 자체의 기능을 구현하고자 할때
모든 버튼 객체에 일괄로 기능을 적용할때
액션메소드드를 커스텀 클래스 외부에 정의 버튼의 개별적인 사용목적을 위해
비지니스 관련된 로직은 내부에 작성할필요가 없음

 

반응형
Comments