솔직히 제목은 어그로가 맞다. SwiftUI는 특성상 { } 가 많아질 수 밖에 없다. 거기다가 if문 같은 녀석들을 넣게 되면 상당히 길어지고 복잡해보인다. 대부분의 선언형 프레임워크들이 그렇듯 어쩔 수 없는듯 하다. 나는 이전부터 이것들이 너무 거슬렸었다.
{ } 들이 중첩되면 가독성이 매우 안좋아질 뿐더러 기분이 매우 언짢아진다. 내 기분을 위해서 연구했었고, 나름 괜찮았던 방법들을 소개해보자 한다.
View를 쪼개는 방법에는 크게 3가지가 있다.
// Computed Property
var aView: some View {
// View
}
// Function
var bView() -> some View {
// View
}
// Struct
struct CView: View {
var body: some View {
// View
}
}
각각의 차이점이라곤, 있기는 한데 그거 달달 외워서 뭐할건가. 상황과 본인의 취향에 따라 선택하면 된다.
필자는 Computed Property로 뷰를 쪼개는걸 가장 선호한다. 그리고 TableView Cell처럼 data가 들어가서 반복되는 뷰 라면 funtion으로 쪼개고, 다른 뷰에서도 사용할 뷰 라면 Struct로 쪼갠다.
나는 뷰를 쪼갤때 최소 단위로 쪼갠다. 그리고 마지막 var body에 파츠들을 조립한다. 마치 레고 하듯이 말이다. 그러면 좋은점은 수정에 굉장히 용이해진다. 특정뷰를 잠시 없애고 싶다면 var body에서 그 파츠를 주석처리 하면 된다. 위치를 바꾸고 싶다면 위에서 위치만 바꿔주면 된다. 이러면 수정속도가 굉장히 빨라지고, 최소 단위로 보기 때문에 코드를 읽는 시간도 현저히 줄어들게 된다.
View파일에 if문을 사용할일이 생각보다 많다. 얘를들어 Foreach를 돌릴때 짝수마다 하나를 더 추가하고 싶다던가, 뭐 그럴때 if문을 자주 사용할 것이다.
또한, if let으로 옵셔널을 처리할때에도 많이 사용할 것이다.
여기서 if문같은걸 없애기 위해 몇가지 만들어 둔것이 있다.
// Hidden
struct HiddenModifier: ViewModifier {
let isHidden: Bool
func body(content: Content) -> some View {
Group {
if isHidden {
EmptyView()
} else {
content
}
}
}
}
extension View {
func hidden(of condition: Bool) -> some View {
modifier(HiddenModifier(isHidden: condition))
}
}
또한 이런 경우도 있다.
URL(string: "www.example.com") ?? URL(string: "www.naver.com") ?? URL(string: "www.google.com").....
차마 포스언래핑을 하기 찜찜해서 이런 상황이 생긴다.
그러면 단하나의 수..
if let url = URL(string: "www.example.com") {
// Link View
}
이렇게 해야하는데, if let을 보자마자 🤮🤮🤮🤮🤮
이런 상황일 때
// Link
extension Link {
public init?(string: String, @ViewBuilder label: () -> Label) {
guard let url = URL(string: string) else {
return nil
}
self.init(destination: url, label: label)
}
}
그거 알았는가? init에 ?를 달 수 있다. url로 변환이 실패하면 View가 아에 나오질 않는다.
이런 방식으로 가독성을 높일 수 있을 것이다.
가끔가다 스유가 코드가 드러워서 별로다 라고 하는 사람들은 반성 요망