SwiftUI List 완벽 마스터 2탄: 고급 기능 및 심화 사용법

작성일 :

SwiftUI List 완벽 마스터 2탄: 고급 기능 및 심화 사용법

SwiftUI List의 기본 사용법을 숙지했다면, 이제 고급 기능과 심화 사용법을 통해 더욱 강력하고 유연한 리스트를 만들어 보세요. 이 글에서는 리스트의 다양한 고급 기능과 그 활용 방법을 다룹니다.

리스트의 고급 기능

  1. 커스텀 셀 사용하기 리스트의 기본 텍스트 셀 외에도 복잡한 커스텀 셀을 만들 수 있습니다. 예를 들어, 이미지와 텍스트가 함께 포함된 셀을 만들려면 다음과 같이 할 수 있습니다:

    swift
    struct CustomRow: View {
        var item: String
    
        var body: some View {
            HStack {
                Image(systemName: "star")
                Text(item)
            }
        }
    }
    
    struct ContentView: View {
        let items = ["Item 1", "Item 2", "Item 3"]
    
        var body: some View {
            List(items, id: \.self) { item in
                CustomRow(item: item)
            }
        }
    }
  2. 그룹화된 리스트 그룹화된 리스트는 아이템을 논리적으로 그룹화하여 보여줍니다. 이를 통해 리스트의 구조를 더욱 명확하게 만들 수 있습니다:

    swift
    struct ContentView: View {
        let items = [
            ["Header 1": ["Item 1", "Item 2"]],
            ["Header 2": ["Item 3", "Item 4"]]
        ]
    
        var body: some View {
            List {
                ForEach(items, id: \.keys.first!) { section in
                    Section(header: Text(section.keys.first!)) {
                        ForEach(section.values.first!, id: \.self) { item in
                            Text(item)
                        }
                    }
                }
            }
        }
    }
  3. 리스트 스타일 커스터마이징 listStyle 수정자를 사용하여 리스트의 외관을 변경할 수 있습니다. 다양한 스타일 옵션을 제공하여 리스트의 디자인을 맞춤 설정할 수 있습니다:

    swift
    var body: some View {
        List(items, id: \.self) { item in
            Text(item)
        }
        .listStyle(InsetGroupedListStyle())
    }
  4. 비동기 데이터 로딩 SwiftUI와 Combine 프레임워크를 사용하여 비동기 데이터 로딩을 구현할 수 있습니다. 예를 들어, API 호출을 통해 데이터를 로드하고 리스트에 표시하는 방법은 다음과 같습니다:

    swift
    class ViewModel: ObservableObject {
        @Published var items: [String] = []
    
        func fetchData() {
            let url = URL(string: "https://api.example.com/items")!
            URLSession.shared.dataTask(with: url) { data, response, error in
                if let data = data {
                    let items = try? JSONDecoder().decode([String].self, from: data)
                    DispatchQueue.main.async {
                        self.items = items ?? []
                    }
                }
            }.resume()
        }
    }
    
    struct ContentView: View {
        @StateObject private var viewModel = ViewModel()
    
        var body: some View {
            List(viewModel.items, id: \.self) { item in
                Text(item)
            }
            .onAppear {
                viewModel.fetchData()
            }
        }
    }
  5. 편집 가능한 리스트 리스트의 아이템을 추가, 삭제 및 재정렬할 수 있는 편집 가능한 리스트를 만들 수 있습니다. onMoveonDelete 수정자를 사용하여 이러한 기능을 구현할 수 있습니다:

    swift
    struct ContentView: View {
        @State private var items = ["Item 1", "Item 2", "Item 3"]
    
        var body: some View {
            List {
                ForEach(items, id: \.self) { item in
                    Text(item)
                }
                .onDelete(perform: deleteItems)
                .onMove(perform: moveItems)
            }
            .toolbar {
                EditButton()
            }
        }
    
        func deleteItems(at offsets: IndexSet) {
            items.remove(atOffsets: offsets)
        }
    
        func moveItems(from source: IndexSet, to destination: Int) {
            items.move(fromOffsets: source, toOffset: destination)
        }
    }

심화 활용 예제

  1. 필터링된 리스트 사용자 입력에 따라 리스트 아이템을 필터링하는 기능을 구현할 수 있습니다. SearchBar를 사용하여 리스트를 동적으로 필터링하는 방법은 다음과 같습니다:

    swift
    struct ContentView: View {
        @State private var searchText = ""
        let items = ["Apple", "Banana", "Cherry", "Date", "Fig", "Grape"]
    
        var filteredItems: [String] {
            if searchText.isEmpty {
                return items
            } else {
                return items.filter { $0.contains(searchText) }
            }
        }
    
        var body: some View {
            VStack {
                SearchBar(text: $searchText)
                List(filteredItems, id: \.self) { item in
                    Text(item)
                }
            }
        }
    }
    
    struct SearchBar: UIViewRepresentable {
        @Binding var text: String
    
        class Coordinator: NSObject, UISearchBarDelegate {
            @Binding var text: String
    
            init(text: Binding<String>) {
                _text = text
            }
    
            func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
                text = searchText
            }
        }
    
        func makeCoordinator() -> Coordinator {
            return Coordinator(text: $text)
        }
    
        func makeUIView(context: Context) -> UISearchBar {
            let searchBar = UISearchBar(frame: .zero)
            searchBar.delegate = context.coordinator
            return searchBar
        }
    
        func updateUIView(_ uiView: UISearchBar, context: Context) {
            uiView.text = text
        }
    }
  2. 리스트 내비게이션 리스트 아이템을 선택하면 상세 화면으로 이동하는 네비게이션을 구현할 수 있습니다. NavigationViewNavigationLink를 사용하여 다음과 같이 할 수 있습니다:

    swift
    struct ContentView: View {
        let items = ["Item 1", "Item 2", "Item 3"]
    
        var body: some View {
            NavigationView {
                List(items, id: \.self) { item in
                    NavigationLink(destination: DetailView(item: item)) {
                        Text(item)
                    }
                }
                .navigationTitle("Items")
            }
        }
    }
    
    struct DetailView: View {
        let item: String
    
        var body: some View {
            Text("Detail for \(item)")
                .navigationTitle(item)
        }
    }

성능 최적화

리스트의 성능을 최적화하기 위해서는 고유 식별자를 사용하고, 가능한 경우 LazyVStack을 사용하는 것이 좋습니다. 또한, 불필요한 리렌더링을 피하기 위해 상태 관리를 신중하게 해야 합니다.

  1. 고유 식별자 사용 리스트 아이템의 고유 식별자를 지정하여 효율적인 업데이트를 보장합니다.

  2. LazyVStack 사용 많은 아이템을 렌더링할 때 LazyVStack를 사용하여 성능을 개선할 수 있습니다.

  3. 상태 관리 상태 변수가 변경될 때마다 불필요한 리렌더링을 피하기 위해 상태 관리를 신중하게 해야 합니다. 상태 변수를 최소화하고, 가능한 경우 부모 뷰가 아닌 하위 뷰에서 상태를 관리하도록 합니다.

결론

SwiftUI List의 고급 기능과 심화 사용법을 통해 더욱 강력하고 유연한 리스트를 구현할 수 있습니다. 멀티 선택, 데이터 새로고침, 섹션 구성, 계층형 리스트, 비동기 데이터 로딩, 편집 가능한 리스트, 필터링된 리스트, 리스트 내비게이션 등 다양한 기능을 활용하여 사용자 경험을 향상시킬 수 있습니다.

추가 자료

자세한 예제와 고급 사용법은 아래 자료를 참조하세요: