문제 상황
저는 ViewController 파일과 화면 view 세팅 파일을 분리했습니다.
loadView( )를 오버라이딩해서 view를 교체해줬어요.
아래는 HomeViewController의 view를 커스텀 뷰인 HomeView로 교체하는 코드입니다.
override func loadView() {
super.loadView()
homeView = HomeView(frame: self.view.frame)
self.view = homeView
}
문제 1
불필요한 view를 생성합니다.
super.loadView( )에서 기존 view가 생성되고 있었습니다.
어차피 제가 만든 Custom view로 바로 교체하기 때문에 기존 view는 생성하지 않아도 되는 것이죠.
문제 2
위 코드는 모든 ViewController에 공통적으로 들어가 있습니다.
파라미터가 조금씩 다를 때도 있지만
일반적으로 동일한 코드가 중복되고 있었어요.
두 가지 문제를 BaseViewController와 Generic을 이용하여 해결해보았습니다.
loadView 수정
문제 1을 먼저 해결해봅시다.
super.loadView( ) 코드를 삭제하기 위해서는
HomeView를 생성할 때 전달되는 self.view.frame을 수정해야 합니다.
self.view.frame은 어차피 화면 전체 크기이기 때문에
self.view.frame 대신 디바이스의 Screen 사이즈를 이용하면 됩니다.
Screen 사이즈는 다행히 타입 프로퍼티로 간편하게 구할 수 있었습니다.
UIScreen.main.bounds
위 프로퍼티를 이용해 코드를 수정해보았습니다.
override func loadView() {
homeView = HomeView(frame: UIScreen.main.bounds)
self.view = homeView
}
불필요한 view의 생성을 없앴고 코드의 길이도 짧아졌습니다.
사실 loadView의 공식 문서에서도 super.loadView( )의 호출을 비권장하기 때문에
공식 문서의 의도대로 작성한 코드라고 할 수 있습니다.
Generic 활용
BaseViewController와 Generic을 이용해서 문제 2를 해결할 수 있었습니다.
동일한 코드가 타입만 다른 경우이므로 Generic을 이용할 수 있고
BaseViewController에서 loadView( )를 오버라이드하면
BaseViewController를 상속하는 모든 VC에서 loadView( )를 오버라이드 하지 않아도 됩니다.
Generic을 넣은 BaseViewController는 이렇습니다.
class BaseViewController<LayoutView: UIView>: UIViewController {
...
}
보통 T라고 사용되는 Generic 타입은 가독성을 위해 LayoutView로 명했습니다.
LayoutView는 UIView만 들어와야 하므로 클론(:)을 이용해 조건을 지정해줬어요.
LayoutView를 이용해 loadView를 오버라이드합니다.
class BaseViewController<LayoutView: UIView>: UIViewController {
var layoutView: LayoutView {
return view as! LayoutView
}
override func loadView() {
self.view = LayoutView(frame: UIScreen.main.bounds)
}
...
}
이제 BaseViewController는 loadView를 오버라이드하지 않아도 되고
view는 layoutView로 이용할 수 있습니다.
마무리
Generic과 BaseViewController를 이용해
매번 작성해서 번거로웠던 loadView 코드를 대폭 줄일 수 있었습니다.
Swift를 제대로 이해하면 개발이 쉬워진다는 것을
직접적으로 느꼈습니다.
감사합니다!
참고
https://developer.apple.com/documentation/uikit/uiscreen
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.
swift, iOS, iOS 개발, 아이폰, 앱 개발, 개발, 코딩