작성
·
42
·
수정됨
0
안녕하세요! 다름이 아니라 강의를 보면 @ViewBuilder 어노테이션을 사용하시는데 강사님이 쓰신 블로그인지는 모르겠지만
https://dev200ok.blogspot.com/2022/05/swiftui.html(블로그 주인 이름이 강사님과 동일)
위 링크에 따르면
SwiftUI에서 UI를 그리다 보면, 뷰를 따로 떼어내서 작업을 해야하는 경우들이 발생
@ViewBuilder
어노테이션을 붙여 뷰를 만들어 주는 메소드를 만들어 줄 수 있습니다. 뷰를 코드와 분리하기 때문에 코드의 가독성을 높여주며 다른 뷰를 독립적으로 보기 좋음
@ViewBuilder
를 붙여서 만든다면 암시적으로 해당 뷰 안에서만들어 사용하겠다는 뜻
위와 같은 이유로 @ViewBuilder를 사용한다고 되어 있습니다 근데 제 코드를 보시면
import SwiftUI
struct ContentView: View {
@State private var airplaneMode: Bool = false
func Profile() -> some View{
NavigationLink{
Text("프로필 화면")
} label: {
HStack{
Image(systemName: "person.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.padding(.all, 10)
.background(.green)
.clipShape(Circle())
VStack(alignment: .leading, spacing: 3){
Text("홍길동")
.font(.system(size: 24))
.fontWeight(.regular)
Text("Apple ID, iCloud, 미디어 및 구입")
.font(.system(size: 14))
}
.padding(.leading, 6)
}
.padding(.vertical, 10)
}
}
func ImageDesign(sysName: String, imgColor: Color) -> some View{
Image(systemName: sysName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 20, height: 20)
.padding(.all, 4)
.background(imgColor)
.foregroundColor(.white)
.cornerRadius(6)
}
func ListMenuLetter(sysName: String, NaviLinkText: String, imgColor: Color) -> some View{
HStack{
NavigationLink{
switch NaviLinkText{
case "WI-FI":
Text("WI-FI 화면")
case "Bluetooth":
Text("Bluetooth 화면")
default:
EmptyView() // 빈 뷰를 반환
}
} label: {
switch NaviLinkText{
case "WI-FI":
ImageDesign(sysName: sysName, imgColor: imgColor)
HStack{
Text("WI-FI")
Spacer()
Text("IPTIME")
.foregroundColor(.gray)
}
case "Bluetooth":
ImageDesign(sysName: sysName, imgColor: imgColor)
HStack{
Text("Bluetooth")
Spacer()
Text("켬")
.foregroundColor(.gray)
}
default:
EmptyView() // 빈 뷰를 반환
}
}
}
}
func ListMenu(sysName: String, NaviLinkText: String, imgColor: Color) -> some View{
HStack{
ImageDesign(sysName: sysName, imgColor: imgColor)
if NaviLinkText != "에어플레인 모드"{
NavigationLink(NaviLinkText){ // 여기에 지금 label이 따로 지정되어 있지 않은데 이럴 경우 괄호 안에 있는 NaviLinkText가 label 역할을 함
switch NaviLinkText{
case "셀룰러":
Text("셀룰러 화면")
case "개인용 핫스팟":
Text("개인용 핫스팟 화면")
case "스크린 타임":
Text("스크린 타임 화면")
case "일반":
Text("일반 화면")
case "손쉬운 사용":
Text("손쉬운 사용 화면")
case "개인 정보 보호":
Text("개인 정보 보호 화면")
case "암호":
Text("암호 화면")
default:
EmptyView() // 빈 뷰를 반환
}
}
}
else{
Toggle("에어플레인 모드", isOn: $airplaneMode)
}
}
}
var body: some View {
NavigationView {
List{
Section{
Profile()
}
Section{
ListMenu(sysName: "airplane", NaviLinkText: "에어플레인 모드", imgColor: .orange)
ListMenuLetter(sysName: "wifi", NaviLinkText: "WI-FI", imgColor: .blue)
ListMenuLetter(sysName: "b.circle", NaviLinkText: "Bluetooth", imgColor: .blue)
ListMenu(sysName: "antenna.radiowaves.left.and.right", NaviLinkText: "셀룰러", imgColor: .green)
ListMenu(sysName: "personalhotspot", NaviLinkText: "개인용 핫스팟", imgColor: .green)
}
Section{
ListMenu(sysName: "hourglass", NaviLinkText: "스크린 타임", imgColor: .blue)
}
Section{
ListMenu(sysName: "gear", NaviLinkText: "일반", imgColor: .gray)
ListMenu(sysName: "person.crop.circle", NaviLinkText: "손쉬운 사용", imgColor: .blue)
ListMenu(sysName: "hand.raised.fill", NaviLinkText: "개인 정보 보호", imgColor: .blue)
}
Section{
ListMenu(sysName: "key.fill", NaviLinkText: "암호", imgColor: .gray)
}
}
.navigationTitle(Text("설정")) // 타이틀 위치 코드가 맨 위가 아닌데 정상 동작하는 이유는 무엇인가
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Profile 함수나 ImageDesign 등 뷰를 함수로 따로 빼서 독립적인 코드를 구성했는데 @ViewBuilder를 사용하지 않고도 아무런 문제가 없이 정상적으로 동작합니다. 사용하지 않아도 문제가 없는데 강의에서 @ViewBulider를 사용하시는 이유가 궁금합니다 답변 주시면 감사하겠습니다!
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
@ViewBuilder
어노테이션은 SwiftUI에서 복잡한 뷰 구조를 더 간결하고 선언적으로 표현하기 위해 사용됩니다. 함수나 클로저에서 여러 뷰를 조건부로 표시하거나, 다양한 뷰를 조합하여 새로운 뷰 컴포넌트를 만들 때 유용하게 사용할 수 있습니다.
질문하신 코드에서는 @ViewBuilder
를 사용하지 않고도 정상 동작하는 이유는, 개별 함수들이 이미 단일 뷰를 반환하고 있기 때문에, 복수의 뷰를 조건부로 반환하거나 복잡한 뷰 로직을 다루지 않기 때문입니다.
하지만, 만약 한 함수 내에서 여러 조건에 따라 다른 뷰를 반환해야 하거나, 뷰의 구성이 복잡해지는 경우에는 @ViewBuilder
를 사용함으로써 더 나은 유연성과 코드의 가독성을 얻을 수 있습니다. 예를 들어, 조건에 따라 다른 뷰를 보여주거나, 여러 뷰를 순차적으로 배치해야 하는 상황에서 @ViewBuilder
를 사용하면 코드를 훨씬 간결하고 명시적으로 작성할 수 있습니다.
요약하자면, 현재 코드에서는 @ViewBuilder
를 필요로 하지 않을 수 있지만, 더 복잡한 뷰 구성이나 조건부 뷰 렌더링을 다루게 될 때 @ViewBuilder
의 이점을 활용할 수 있습니다. 강의에서 @ViewBuilder
를 사용하는 이유도 바로 이러한 유연성과 가독성을 높이기 위함일 것입니다.
혹시 그럼 @ViewBuilder를 사용할만한 상황이 뭐가 있는지 코드로 알려주실 수 있을까요?