본문 바로가기
iOS/SwiftUI

[SwiftUI] List

by Sky Titan 2022. 1. 22.
728x90
 

핵심만 골라 배우는 SwiftUI 기반의 iOS 프로그래밍 - YES24

SwiftUI는 물론 애플리케이션 개발과 출시를 위한 모든 과정을 담았다!이 책의 목적은 SwiftUI와 Xcode 11, 그리고 스위프트 5 프로그래밍 언어를 사용하여 iOS 13 애플리케이션 제작 기술을 전달하는 데

www.yes24.com

List


  • List 뷰는 수직 방향의 목록 형태로 사용자에게 정보를 제공할 수 있게 해준다.
  • 정적 데이터, 동적 데이터 모두를 표현할 수 있다.
    • 추가, 삭제, 항목 순서 재정렬 작업 또한 가능하도록 확장할 수 있다.
  • UIKit의 TableView와 비슷한 기능을 제공한다.

 

Example


List의 셀을 Stack뷰로 만들어서 여러가지 뷰들을 조합할 수 있다.

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        List {
            HStack {
                Image(systemName: "trash.circle.fill")
                Text("Take out the trash")
            }
            HStack {
                Image(systemName: "trash.circle")
                Text("No Trash")
                
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

동적 리스트


  • 항목이 추가, 편집, 삭제 등 동적으로 변할 때 이것을 리스트에 업데이트 해줄 수 있는 것이 동적 리스트이다.
  • 동적 리스트에 사용될 데이터 객체는 Identifiable 프로토콜을 채택해야한다.
    • 그리고 리스트에서 각 항목을 식별할 수 있는 id 프로퍼티가 객체에 있어야 한다.
    • String, Int, UUID 등 Hashable 프로토콜을 따르는 모든 Swift 타입이나 커스텀 타입이 id 프로퍼티가 될 수 있다.
    • 보통은 UUID()로 설정을 많이 하게 된다.

 

동적 리스트 예제1


//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var dataList: [PersonItem] = {
        var list: [PersonItem] = []
        list.append(PersonItem(name: "Park", age: 20, iconName: "person"))
        list.append(PersonItem(name: "Kim", age: 25, iconName: "person.fill"))
        list.append(PersonItem(name: "Lee", age: 30, iconName: "person.2"))
        return list
    }()
    
    var body: some View {
        List(dataList) { item in
            HStack {
                Image(systemName: item.iconName)
                Text(item.name)
                Text(item.age.description)
                    .font(.system(size: 14))
            }
        }
    }
}

class PersonItem: Identifiable {
    var id = UUID()
    var name: String
    var age: Int
    var iconName: String
    
    init(name: String, age: Int, iconName: String) {
        self.name = name
        self.age = age
        self.iconName = iconName
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

동적 리스트 예제2


 Custom View 활용

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var dataList: [PersonItem] = {
        var list: [PersonItem] = []
        list.append(PersonItem(name: "Park", age: 20, iconName: "person"))
        list.append(PersonItem(name: "Kim", age: 25, iconName: "person.fill"))
        list.append(PersonItem(name: "Lee", age: 30, iconName: "person.2"))
        return list
    }()
    
    var body: some View {
        List(dataList) { item in
            PersonItemView(item: item)
        }
    }
}

// Custom View 만들기
struct PersonItemView: View {
    var item: PersonItem
    var body: some View {
        HStack {
            Image(systemName: item.iconName)
            Text(item.name)
            Text(item.age.description)
                .font(.system(size: 14))
        }
    }
}

class PersonItem: Identifiable {
    var id = UUID()
    var name: String
    var age: Int
    var iconName: String
    
    init(name: String, age: Int, iconName: String) {
        self.name = name
        self.age = age
        self.iconName = iconName
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

동적 리스트 예제3


 ObservableObject를 활용해서 List 셀 뷰의 컨텐트의 변화가 실시간으로 뷰에 업데이트 되도록 하기

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var dataList: [PersonItem] = {
        var list: [PersonItem] = []
        list.append(PersonItem(name: "Park", age: 20, iconName: "person"))
        list.append(PersonItem(name: "Kim", age: 25, iconName: "person.fill"))
        list.append(PersonItem(name: "Lee", age: 30, iconName: "person.2"))
        return list
    }()
    
    var body: some View {
        VStack {
            List(dataList) { item in
                PersonItemView(item: item)
            }
            
            // 클릭 시 list의 첫번째 아이템의 name 프로퍼티를 바꾼다.
            Button(action: {
                dataList[0].name = "Wow"
            }, label: {
                Text("Click")
            })
        }
    }
}

struct PersonItemView: View {
    //Custom View에 ObservedObject 두기
    @ObservedObject var item: PersonItem
    var body: some View {
        HStack {
            Image(systemName: item.iconName)
            Text(item.name)
            Text(item.age.description)
                .font(.system(size: 14))
        }
    }
}


//Observable Object 채택
class PersonItem: Identifiable, ObservableObject {
    var id = UUID()
    @Published var name: String
    @Published var age: Int
    @Published var iconName: String
    
    init(name: String, age: Int, iconName: String) {
        self.name = name
        self.age = age
        self.iconName = iconName
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

ForEach문 활용


  • List에 동적 데이터와 정적 데이터를 함께 표현해야 하는 경우, ForEach 문을 통해 동적 데이터에 대해 반복문을 돌려서 정적 항목을 선언할 수 있다.
//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var dataList: [PersonItem] = {
        var list: [PersonItem] = []
        list.append(PersonItem(name: "Park", age: 20, iconName: "person"))
        list.append(PersonItem(name: "Kim", age: 25, iconName: "person.fill"))
        list.append(PersonItem(name: "Lee", age: 30, iconName: "person.2"))
        return list
    }()
    
    var body: some View {
        VStack {
            List {
                Button(action: {
                    
                }, label: {
                    Text("Top Button")
                })
                
                //ForEach 반복문 사용
                ForEach(dataList) { item in
                    PersonItemView(item: item)
                }
            }
        }
    }
}

struct PersonItemView: View {
    @ObservedObject var item: PersonItem
    var body: some View {
        HStack {
            Image(systemName: item.iconName)
            Text(item.name)
            Text(item.age.description)
                .font(.system(size: 14))
        }
    }
}


//Observable Object 채택
class PersonItem: Identifiable, ObservableObject {
    var id = UUID()
    @Published var name: String
    @Published var age: Int
    @Published var iconName: String
    
    init(name: String, age: Int, iconName: String) {
        self.name = name
        self.age = age
        self.iconName = iconName
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

Section 뷰


List의 Row들을 Section 뷰에 넣고 각 섹션마다의 header, footer를 지정할 수 있다.

//
//  ContentView.swift
//

import SwiftUI

struct ContentView: View {
    
    var dataList: [PersonItem] = {
        var list: [PersonItem] = []
        list.append(PersonItem(name: "Park", age: 20, iconName: "person"))
        list.append(PersonItem(name: "Kim", age: 25, iconName: "person.fill"))
        list.append(PersonItem(name: "Lee", age: 30, iconName: "person.2"))
        return list
    }()
    
    var body: some View {
        VStack {
            List {
                
                //Section 사용
                Section(header: Text("Header 1"), footer: Text("Footer 1")) {
                    Button(action: {
                        
                    }, label: {
                        Text("Top Button")
                    })
                }
                
                Section(header: Text("Header 2"), footer: Text("Footer 2")) {
                    ForEach(dataList) { item in
                        PersonItemView(item: item)
                    }
                }
            }
        }
    }
}

struct PersonItemView: View {
    @ObservedObject var item: PersonItem
    var body: some View {
        HStack {
            Image(systemName: item.iconName)
            Text(item.name)
            Text(item.age.description)
                .font(.system(size: 14))
        }
    }
}


class PersonItem: Identifiable, ObservableObject {
    var id = UUID()
    @Published var name: String
    @Published var age: Int
    @Published var iconName: String
    
    init(name: String, age: Int, iconName: String) {
        self.name = name
        self.age = age
        self.iconName = iconName
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .previewDevice("iPhone 11")
            .previewDisplayName("아이폰 11")
    }
}

 

 

728x90

'iOS > SwiftUI' 카테고리의 다른 글

[SwiftUI] NavigationView, NavigationLink  (0) 2022.01.31
[SwiftUI] Slider 활용 예제  (0) 2022.01.18
[SwiftUI] Environment 객체  (0) 2022.01.16
[SwiftUI] List, Observable 객체 활용 예시  (0) 2022.01.16
[SwiftUI] Observable 객체  (0) 2022.01.16

댓글