Hacking with Swift 사이트의 강좌 번역본입니다.
[원문 : https://www.hackingwithswift.com/quick-start/swiftui/composing-views-to-create-a-list-row]
Composing views to create a list row
[동영상 강좌 : https://youtu.be/0xinbTAxbK8]
메뉴 항목에 이름을 작성하는 것만으로는 식당이 특별히 매력적이지는 않기에, 이러한 항목들을 좋아보이도록 꾸며봅시다.
우선, 중요한 교훈은 다음과 같습니다: SwiftUI는 구성가능하도록(composable) 설계 되었으며, 이는 원하는데로 다른 뷰를 만들수 있다는 것을 의미합니다. 지금은 항목들에 대해 Text(item.name)이라는 단순한 텍스트 뷰를 가지고 있지만, 거기에 더 많은 것을 추가할 것입니다. ContentView.swift 안에 직접 넣을수 있지만 읽기 어렵습니다.
더 좋은 생각은 ContentView 안쪽에 포함할 수 있는 새로운 뷰 타입을 만는 것이고, SwiftUI는 쉽고(30초만 배우면 됨) 매우 빠르게(성능에 거의 영향을 미치지 않음) 만들수 있도록 설계되어 있습니다.
새로운 파일을 만들기 위해서, Cmd+N을 누르고, User Interface 카테고리에서 SwiftUI View를 선택하고나서, ItemRow를 입력합니다. ContentView를 시작할때와 매우 비슷한 Xcode가 만들어낸 새로운 뷰를 보게 될 것입니다.
struct ItemRow: View {
var body: some View {
Text("Hello World!")
}
}
잠깐 뒤에 새로운 무언가를 할 것이지만, 먼저 코드에서 ItemRow를 사용하는 곳을 보고자 합니다. 이는 ItemRow에 MenuItem 프로퍼티를 추가해야 하는 것을 의미하고, 다음과 같이 본문에서 사용합니다.
struct ItemRow : View {
var item: MenuItem
var body: some View {
Text(item.name)
}
}
이제 ContentView.swift로 돌오가서 Text(item.name)을 다음과 같이 교체합니다.
ItemRow(item: item)
보다시피, 메뉴 섹션에서 각 항목에 대해 내부에 텍스트가 있는 ItemRow를 생성할 것입니다.
ItemRow.swift에 문제가 있기 때문에, 지금 코드는 빌드되지 않습니다. 이 코드는 유효하지 않습니다.
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow()
}
}
이것은 SwiftUI의 미리보기 코드이며, 작업하는 동안에 라이브 미리보기를 보여줍니다.메뉴 항목을 첨부하지 않고 ItemRow를 생성하려 하므로 이는 불가능합니다. 개별 행을 미리보기 하고 싶은 경우에 전체 메뉴의 복사본을 인스턴스화해서 예제 항목에 전달하면 되지만, 해당 인스턴스는 우리가 볼수 있도록 예제 항목을 제공하고 있습니다.
다시 잘 동작하도록 만들기 위해 코드를 변경합니다.
struct ItemRow_Previews: PreviewProvider {
static var previews: some View {
ItemRow(item: MenuItem.example)
}
}
코드를 완료하고 다시 빌드할 것이고, ContentView.swift로 돌아가는 경우. 이전과 동일한 미리보기를 보게됩니다 - 바뀐것 아무것도 없습니다. 물론, 더 재미있게 하기 위해서 ItemRow구조체에 새로운 것을 추가하기 시작할 수 있습니다!
ItemRow에서, 항목의 썸네일 이미지와 이름을 나란히 배치할 것이고, UITableViewCell에서 일반적으로 볼수 있는 것과 같습니다. 다음과 같이 작성하세요.
var body: some View {
Image(item.thumbnailImage)
Text(item.name)
}
Swift가 다음과 비슷한 오류 메시지를 주는 것을 발견하게 될것 입니다: Function declares an opaque return type, but has no return statements in it body form which to infer an underlying type(함수가 불명확한 반환 타입을 선언했지만, 본문에서 기본 타입을 추론할 수 있는 반환 상태가 없습니다).
이것이 의미하는 것은 some View가 메소드로 부터 하나의 특정 뷰를 반환해야 하는 것을 의미합니다 - 2개의 다른 뷰가 아니고, 확실히 뷰가 없는 것도 아닙니다.
이를 고치기 위해 이러한 2개의 뷰를 컨테이너 안쪽에 넣어야 하며, 우리의 경우에는 HStack이 될 것입니다. 이것은 자식 뷰들을 수평으로 나란히 배치하는 컨테이너 이며, 우리에게 필요한 것입니다.
대신에 다음과 같이 만듭니다.
var body: some View {
HStack {
Image(item.thumbnailImage)
Text(item.name)
}
}
이름 다음에 항목의 가격을 넣고자 하는 경우에, 다음과 같이 만들 수 있습니다.
HStack {
Image(item.thumbnailImage)
Text(item.name)
Text("$\(item.price)")
}
하지만, 가격을 이름의 오른쪽에 넣는것은 좋지 않습니다. UITableViewCell에서 사용하는 부제(subtitle) 스타일의 종류를 원하며, 왼쪽에 이미지가 있을 수 있고, 오른쪽 상세 라벨 위에 제목이 있을 수 있습니다.
VStack(수직(vertical) 스택)이라는 또 다른 스택(stack)으로 그렇게 만들 수 있습니다. 원하는 계층구조를 만들기 위해서 기존 HStack안쪽에 넣을 수 있습니다.
HStack {
Image(item.thumbnailImage)
VStack {
Text(item.name)
Text(String("$\(item.price)"))
}
}
항목 이름과 가격이 중앙에 있는 것을 알 수 있을 것입니다. VStack의 기본 동작때문에 그렇게 되지만, 여기에서는 왼쪽 정렬이 더 좋아보입니다. 다음과 같이 VStack을 만들때 앞쪽(leading) 정렬을 적용할 수 있습니다.
VStack(alignment: .leading) {
Text(item.name)
Text(String("$\(item.price)"))
}
'SwiftUI > Building a complete project' 카테고리의 다른 글
Bindings and forms (0) | 2019.11.08 |
---|---|
Adding TabView and tabItem() (0) | 2019.11.08 |
Adding items to an order with @EnvironmentObject (0) | 2019.11.08 |
Observable objects, environment objects, and @Published (0) | 2019.11.07 |
Displaying a detail screen with NavigationLink (0) | 2019.11.07 |
Polishing designs with fonts and colors (0) | 2019.11.06 |
Building a menu using List (0) | 2019.11.06 |
SwiftUI tutorial: Building a complete project (0) | 2019.11.06 |