-
Notifications
You must be signed in to change notification settings - Fork 0
SwiftUI Code Convention
Joonyong Ji edited this page Jan 4, 2024
·
5 revisions
해당 문서는 채널톡 ios-convention-guide를 참고하였습니다.
- body 내부의 View를 여러 개 생성할 때에는 개행을 둔다.
- 단, body의 처음과 끝은 개행을 두지 않는다.
var body: some View { Text("Hello") .frame(width: 200, height: 50, alignment: .center) Spacer() Text("World") }
- @ViewBuilder 함수보다 struct를 활용한 SubView선언을 지향한다.
- 부모 뷰에 있는 @State를 변경하기 위해 @ViewBuilder를 통해 함수 선언이 가능하지만, 뷰 계층 간 위계를 명확히 하기 위해 @Binding을 사용한다.
// Preferred struct SubView: View { @Binding private var isFavorited: Bool init(isFavorited: Binding<Bool>) { self._isFavorited = isFavorited } var body: some View { ... } } // Not Preferred @ViewBuilder public func subView(title: String) -> some View { VStack { ... Button(title) { self.isFavorited.toggle() } } }
- 부모 뷰에 있는 @State를 변경하기 위해 @ViewBuilder를 통해 함수 선언이 가능하지만, 뷰 계층 간 위계를 명확히 하기 위해 @Binding을 사용한다.
- 명확히 View가 아닌 컴포넌트에 대해서는 suffix(~View)를 사용하지 않는다.
// Preferred struct ChannelButton: View { ... } struct ChannelSwitch: View { ... } // Not Preferred struct ChannelButtonView: View { ... } struct ChannelSwitchView: View { ... }
-
뷰 크기를 확장할 때에는
Spacer()
대신.frame()
을 사용한다.- 수직 확장은
maxHeight: .infinity
, 수평 확장은maxWidth: .infinity
를 사용한다.
// Preferred HStack { ... } .frame(maxWidth: .infinity, alignment: .leading) // Not Preferred HStack { ... Spacer() }
- 수직 확장은
-
Custom View Modifier
적용 시, 아래와 같이 extension을 활용해 해당 modifier에 접근한다.// Preferred struct ContentView: View { var body: some View { Text("Eddy") .asPrimaryCaption() } } extension View { func asPrimaryCaption() -> some View { modifier(PrimaryCaptionText()) } } // Not Preferred struct ContentView: View { var body: some View { Text("Eddy") .modifier(asPrimaryCaption()) } }
- 필수 Propety는 init시점에 적용한다. 옵셔널한 Property는 ViewModifier함수로 참조한다.
- ViewModifier함수 생성 시, Property에 대한 불필요한 접근을 최소화하기 위해 접근제어자를 활용한다.
// Required Action struct ChannelButton: View { private let title: String private let action: () -> () init(title: String, action: @escaping () -> ()) { self.title = title self.action = action } ... } // Optional Action struct ChannelView: View { private let title: String private let optionalAction: (() -> ())? init(title: String) { self.title = title } ... func optionalAction(_ optionalAction: (() -> ())?) -> Self { var view = self view.optionalAction = optionalAction return view } }
copyrightⓒ 2023 All rights reserved by JUNY0110