SwiftUI List 만들기

  • 이번에는 SwiftUI에서 List를 어떻게 만들고 다루는지 알아보겠습니다.

리스트(List) 란

  • List는 이름 그대로 목록(List) 인터페이스를 구현하기 위해 존재합니다.
  • SwiftUI의 리스트는 UIKit의 UITableView와 하는 일이 상당히 비슷합니다.
  • 하지만 구현하기는 훨씬 간편하다고 생각합니다.

정적 리스트

  • 정적 List에 대한 예시를 보여드리겠습니다.
  • 우선 FamilyRow라는 struct가 있습니다.
  • 이 struct는 name 변수와 Text를 리턴하는 body를 갖고 있습니다.
  • List의 아이템으로 FamilyRow를 넣어주고, 각각의 FamilyRow에 서로 다른 name을 입력해줍니다.
  • 그리고 실행해보면, 각 FamilyRow의 텍스트가 리스트 형태로 표시되는 것을 볼 수 있습니다.
struct FamilyRow: View {
  var name: String
  
  var body: some View {
    Text("Family: \(name)")
  }
}

struct ContentView: View {
  var body: some View {
    List {
      FamilyRow(name: "Hohyeon")
      FamilyRow(name: "Moon")
      FamilyRow(name: "Jigom")
    }
  }
}
swiftui-tutorial-list

다이나믹 리스트

  • Family라는 Identifiable 프로토콜을 상속 받는 struct가 있습니다.
  • Identifiable을 상속 받기 위해서는 고유 id 값만 있으면 되는데요.
  • Family struct에 id와 name 변수를 선언합니다.
  • FamilyRow는 정적 List를 다룰 때와 비슷한데요.
  • 다이나믹 리스트를 구성하는 것인만큼 정적인 name 변수 대신 family라는 Family 타입 변수를 선언합니다.
  • ContentView에서는 List에 들어갈 first, second, third 아이템을 만듭니다.
  • 이를 families 배열에 넣어준 뒤, return 값으로 리스트를 반환합니다.
  • families 배열안에 있는 family element를 각각 반복 실행해서 List에 보여줍니다.
struct Family: Identifiable {
  var id = UUID()
  var name: String
}

struct FamilyRow: View {
  var family: Family
  
  var body: some View {
    Text("Family: \(family.name)")
  }
}

struct ContentView: View {
  let first = Family(name: "Hohyeon")
  let second = Family(name: "Moon")
  let third = Family(name: "Jigom")
  
  var body: some View {
    let families = [first, second, third]
    
    return List(families) { family in
      FamilyRow(family: family)
    }
  }
}
swiftui-tutorial-list

List 아이템 선택

  • 앞에서와 같이 Family 구조체와 families라는 배열이 있습니다.
  • 여기에 binding 가능한 multiSelection Set 타입 변수가 있습니다.
  • List에 families와 multiSelection을 넣어주고 네비게이션 바 버튼으로 EditButton을 넣어봅니다.
  • 그러면 EditButton을 눌렀을때 List의 각 row를 선택할수 있게됩니다.
struct ContentView: View {
  struct Family: Identifiable {
    var id = UUID()
    var name: String
  }

  private var families = [
    Family(name: "Hohyeon"),
    Family(name: "Moon"),
    Family(name: "Jigom")
  ]

  @State private var multiSelection = Set<UUID>()
  
  var body: some View {
    NavigationView {
      List(families, selection: $multiSelection) {
        Text($0.name)
      }
      .navigationTitle("Family")
      .toolbar { EditButton() }
    }
  }
}
swiftui-tutorial-list

List 아이템 순서 변경

  • List의 아이템을 편집하기 위해서는 편집 버튼과 편집 상태에서 작동하는 함수의 정의가 필요한데요.
  • 우선, 네비게이션 바 아이템으로 편집 버튼을 만듭니다.
  • .onMove(perform: ...)으로 편집 상태에 진입 했을 때 작동할 함수를 부여합니다.
  • 그리고 편집 상태에서 실행할 함수를 정의 해줍니다.
struct ContentView : View {
  @State var users = ["Hohyeon", "Moon", "Jigom"]
  
  var body: some View {
    NavigationView {
      List {
        ForEach(users, id: \.self) { user in
          Text(user)
        }
        .onMove(perform: move)
      }
      .navigationBarItems(trailing: EditButton())
    }
  }
  
  func move(from source: IndexSet, to destination: Int) {
    let reversedSource = source.sorted()
    
    for index in reversedSource.reversed() {
      users.insert(users.remove(at: index), at: destination)
    }
  }
}
swiftui-tutorial-list

List 아이템 삭제

  • List의 아이템을 삭제하기 위해서는 어려울것 없습니다.
  • ForEach로 뿌려진 Text 아이템 뒤에 .onDelete(perform: )을 달아줍니다.
  • 그리고 삭제 버튼을 누르면 실행할 함수를 정의 해줍니다.
struct ContentView : View {
  @State var users = ["Hohyeon", "Moon", "Jigom"]
  
  var body: some View {
    List {
      ForEach(users, id: \.self) { user in
        Text(user)
      }
      .onDelete(perform: delete)
    }
  }
  
  func delete(at offsets: IndexSet) {
    if let first = offsets.first {
      users.remove(at: first)
    }
  }
}
swiftui-tutorial-list

List에 섹션 추가

  • List에 섹션을 추가하기 위해서는 리스트안에 Section(header: ...){...}을 넣어줍니다.
  • 그리고 Section 안에 List 아이템을 넣어줍니다.
struct TaskRow: View {
  var body: some View {
    Text("Task item")
  }
}

struct ContentView : View {
  var body: some View {
    List {
      Section(header: Text("Important")) {
        TaskRow()
        TaskRow()
        TaskRow()
      }
      Section(header: Text("Other")) {
        TaskRow()
        TaskRow()
        TaskRow()
      }
    }
  }
}
swiftui-tutorial-list

List 스타일링

  • List를 스타일링 하기 위해서는 List 뒤에 .listStyle(...)를 달아줍니다.
  • listStyle 안에는 ListStyle 타입이 들어가서 예를들어, .grouped가 있습니다.
struct GroupedRow: View {
  var body: some View {
    Text("Task Row")
  }
}

struct ContentView : View {
  var body: some View {
    List {
      Section(header: Text("Grouped")) {
        GroupedRow()
        GroupedRow()
        GroupedRow()
      }
    }
    .listStyle(.grouped)
  }
}
swiftui-tutorial-list

마무리

  • 이렇게 해서 SwiftUI에서는 List를 어떻게 만드는지에 대해 알아봤습니다.