Tong's Blog

[Swift] Custom View 만들기 (code only) 본문

iOS/Swift

[Swift] Custom View 만들기 (code only)

통스 2020. 12. 13. 01:50
반응형

안녕하세요. 오늘은 Custom View Class를 만들기를 해보려고 합니다.

 

우선 Custom View 라는 건 어떤 것을 말하는 걸까요?

 

(아 시작전에 저는 이번 포스트에서 xib로 Custom View를 만드는 방법을 포함하지 않습니다. Storyboard와 xib로 Custom View 구현하는 것을 찾으신다면 다른 좋은 포스트들에 잘 설명 되어 있으니, 그 곳에서 찾아보시면 될 거 같습니다.)

 

예를 들어 우리가 만드는 어플리케이션에 간단한 프로필 뷰가 있다고 가정해보겠습니다.

간단히 이런식으로 구현했다고 가정해봅니다.

 

프로필 화면 예시

어느정도 iOS를 공부하신 분들이라면 UIImageView 하나에, UILabel이 2개가 필요하다는 것을 알 수 있을 겁니다.

 

이 화면에 우리 프로젝트에 첫번째가 되는 화면이라면 아마 우리는 이렇게 구현할 수 있을 거 같습니다.

 

import UIKit

//프로젝트에 첫번째 화면
class ViewController1: UIViewController{
    
    let imageView = UIImageView()
    let nameLabel = UILabel()
    let ageLabel = UILabel()
    //...다른 UIComponenet들
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //위에 있는 UI들을 배치할 코드들..
    }
}

 

스토리보드를 사용한다면 선언과 viewDidLoad안에 autolayout이나 각 UIComponent들을 위한 setting 코드가 줄어들고 선언부 모양도 조금 다를테지만 저는 코드로 UI를 짜는 사람이라 양해드립니다..

 

이렇게 ViewController 안에 잘 구현해두었는데 추후에 2번째 화면(ViewController2)에도 같은 프로필을 넣어야 한다고 합니다.

import UIKit

//프로젝트에 두번째 화면
class ViewController2: UIViewController{
    
    let imageView = UIImageView()
    let nameLabel = UILabel()
    let ageLabel = UILabel()
    //...다른 UIComponenet들
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //위에 있는 UI들을 배치할 코드들..
    }
}

 

그럼 다음과 같이 코드를 작성하면 같은 프로필 화면을 나타낼 수 있을 겁니다.

 

하지만 다음과 같은 상황이 생긴다면 어떻게 할까요?

 

  • 3,4,5...화면에서도 프로필 화면이 필요하다
  • 해당 프로필 화면에 성별이라는 새 Label이 필요하다.

같은 View를 그리는데 ViewController안에 매번 같은 코드를 그리는 일도 엄청 비효율적이지만

변경사항이 있을 때 모든 ViewController에 변경사항을 적용하는 일도 비효율적이라고 생각합니다.

 

view class를 만들어 재사용을 할 수 있도록 이런 상황을 피할 수 있을 겁니다.

이렇게 특정 View를 만드는 것을 Custom View라고 할 수 있겠습니다.

 

서론이 길었습니다..

이제 바로 Custom View class를 만들어 보겠습니다.

import UIKit

class CustomView: UIView{
    
    let imageView = UIImageView()
    let nameLabel = UILabel()
    let ageLabel = UILabel()
    //추가한 성별 UILabel()
    let gender = UILabel()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        //code
        ab()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        
        //storyboard
    }
    
    private func ab(){
        print("Init")
    }
}

 

만들어진 Custom View class에 대한 설명은 잠시 뒤에 하고 어떻게 사용하는지 먼저 보겠습니다.

 

import UIKit

class ViewController1: UIViewController{
    
    let profileView = CustomView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //profileView autolayout code or setting...
        profileView.imageView.image = ...
        profileView.nameLabel.text = "홍길동"
        profileView.ageLabel.text = "1970년 1월 1일"
    }
}

Custom View class는 UIView를 상속받아 만들어진 클래스이기 때문에

다른 UIComponent들(UILabel, UIImageView...등)이랑 똑같이 사용하시면 됩니다.

 

그러면 다시 Custom View class로 돌아와서 설명을 드리자면

Custom View class에는 우리가 ViewController에서 보던것과 다르게 생성자가 있는 것을 확인할 수 있습니다.

 

init(frame:)init(coder:) 생성자가 있는데 각 생성자의 역할은 다음과 같습니다.

 

  • init(frame:) : 코드로 뷰를 생성할 때(위에 ViewController1 코드 참조) 생성자
  • init(coder:) : Storyboard로 뷰가 생성될 때 생성자

두개 생성자 모두 필수 생성자이기 때문에 둘 다 구현하지 않으면 에러를 내보낸다.(오류 메세지에서 자동 fix를 지원하긴 합니다.)

 

이제 우리는 각 ViewController에

let profileView = CustomView()

//    let imageView = UIImageView()
//    let nameLabel = UILabel()
//    let ageLabel = UILabel()

3줄 대신 1줄로 UI를 선언할 수 있고(실제로 코드의 양은 1/3보다 줄어들 겁니다,)

만약 해당 UI에 변경 사항이 생기더라도 해당 class만 변경하면 CustomView()가 선언된 다른 모든 화면에도 적용이 될 겁니다.

 

오늘은 Custom View를 코드로만 구현해서 사용하는 것에 대해서 적어봤습니다.

사실 구현 자체에 어려움이 있다기 보단 '왜 굳이 Custom View class를 만들어서 사용해야 하는가?' 에 고민을 하면서 이번 포스트를 작성하게 되었습니다.

 

혹시 제가 모르는 Custom View class을 만드는 이유나 사용 방법이 있다면 공유 부탁드립니다.

오늘도 부족한 글 읽어주셔서 감사합니다.

반응형
Comments