[SwiftUI] DisclosureGroup & OutlineGroup
SwiftUI์ List ์ ์ํด์๋ ํ์
์ธ DisclosureGroup & OutlineGroup
ย ๋จ์ํ๊ฒ ์๊ฐํด์ ์ ๊ณ ํผ ์ ์๋ ํ์ผ์ธ ํธ๋ฆฌ ๊ตฌ์กฐ์ ํํ๋ฅผ ๊ฐ์ง๊ฒ ํ ์ ์๋ ๋ทฐ
โข
์ด ๋ ๊ฐ์ง๋ iOS 14 ์ด์์์๋ง ์ ๊ณต์ ํ๊ณ ์๋ค.
DisclosureGroup
โข
์ ์ด์ ์ํ์ ๋ฐ๋ผ ํ์ ์ปจํ
์ธ ๋ฅผ ํ์ํ๊ฑฐ๋ ์จ๊ธธ ์ ์๋ ๋ทฐ์ด๋ค.
struct DisclosureGroup<Label, Content> where Label: View, Content: View
Swift
๋ณต์ฌ
์ ๋ค๋ฆญํ๊ฒ Label์ ๋ฐ๊ณ ํ์ ๋ด๊ธธ Content๋ฅผ ๋ฐ์ ๊ตฌ์ฑํ๋ ํ์
์ฆ, ํด๋น ๋ทฐ๋ ๋ด์ฉ์ ์๋ณํ ์ ์๋ Label๊ณผ ํ์ ๋ฐ ์จ๊น ์ฒ๋ฆฌํ ์ ์๋ ํ์ ๋ทฐ๋ก ์ปจํธ๋กค ํ๋ค.
DisclosureGroup ๊ตฌํ
import SwiftUI
struct DisclosureGroupView: View {
@State private var expanded: Bool = false
var body: some View {
DisclosureGroup("1๋ฒ ๊ทธ๋ฃน", isExpanded: $expanded) {
Text("1๋ฒ ๊ทธ๋ฃน์ ์ํ ํ
์คํธ")
DisclosureGroup("2๋ฒ ๊ทธ๋ฃน") {
Text("2๋ฒ ๊ทธ๋ฃน์ ์ํ ํ
์คํธ")
}
}
}
}
Swift
๋ณต์ฌ
์์์ ํผ์น๊ณ ์จ๊ธฐ๋ ์ํ๋ฅผ ์ ์ดํ๋ expanded ๋ณ์๋ฅผ ์์ฑ
๊ทธ๋ฆฌ๊ณ 1๋ฒ, ์ฆ, ์ต์์์์ DisclosureGroup์ ๋ง๋ค๊ณ ์ด ๋ณ์๋ฅผ ํตํด ๋ฃ์ด์ฃผ๋ฉด ์ฌ๋ถ ๊ตฌํ์ ํตํด ์ด ๊ฐ์ ์ฌ์ฉ์์ ์ก์
์ ๋ฐ๋ผ ๋ฐ๊ฟ์ค๋ค.
์ฆ, isExpanded ํ๋ผ๋ฏธํฐ๋ Binding<Bool> ํ์
์ธ ๊ฒ.
public init(_ titleKey: LocalizedStringKey, isExpanded: Binding<Bool>, @ViewBuilder content: @escaping () -> Content)
Swift
๋ณต์ฌ
๊ทธ๋ฆฌ๊ณ ํ์์ Content๋ก ์ํ๋ ํ
์คํธ๋ฅผ ๋ฃ๊ฑฐ๋ ๋ ์ด์ด์ DisclosureGroup์ ๋ง๋ค์ด ๋ฃ์ ์๋ ์๋ค.
์ฌ๊ธฐ์ ์ค์ํ๊ฑด ๋ DisclosureGroup์ ์ํ์ ๊ฐ๋
์ผ๋ก ์ํ๊ณ ์์ง๋ง ํผ์นจ/์จ๊น์ ๋ํด์๋ ๋ฐ๋ก ๊ฐ์ ธ๊ฐ๊ฑฐ๋ ๊ฐ์ด ๊ฐ์ก๊ฐ ์๋ ์๋ค.
๋ฐ๋ก ๊ฐ์ ธ๊ฐ๋ ค๋ฉด ์๋์ ๊ฐ์ด ๋ณ๋ ๋ณ์๋ก ์ปจํธ๋กค ํด์ฃผ๋ฉด ๋๋ค.
import SwiftUI
struct DisclosureGroupView: View {
@State private var firstExpanded: Bool = false
@State private var secondExpanded: Bool = true
var body: some View {
DisclosureGroup("1๋ฒ ๊ทธ๋ฃน", isExpanded: $firstExpanded) {
Text("1๋ฒ ๊ทธ๋ฃน์ ์ํ ํ
์คํธ")
DisclosureGroup("2๋ฒ ๊ทธ๋ฃน", isExpanded: $secondExpanded) {
Text("2๋ฒ ๊ทธ๋ฃน์ ์ํ ํ
์คํธ")
}
}
}
}
Swift
๋ณต์ฌ
โ ์ด๋ ๊ฒ ์ปค์คํ
ํ DisclosureGroup์ ๋ง๋ค์ด ํ์ผ ๊ตฌ์กฐ์ฒ๋ผ ๋ทฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
OutlineGroup
Disclosure Views๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ํ๋ผ ์ ์๋ View๊ฐ ํ์ํ ๋ OutlineGroup์ ์ฌ์ฉํ๋ฉด ๋๋ค.
์ ์์์ ๋งํ ๋ฐ์ดํฐ ๊ณ์ธต ๊ตฌ์กฐ (ํด๋ ๊ณ์ธต ๊ตฌ์กฐ)
์ ํ ์์ )
struct FileItem: Hashable, Identifiable {
var id: Self { self }
var name: String
var children: [FileItem]? = nil
var fileName: String {
switch self.children {
case nil:
return "๐ \(self.name)"
case .some(let children):
return children.isEmpty ? "๐ \(self.name)" : "๐ \(self.name)"
}
}
}
let data = FileItem(name: "users", children:
[FileItem(name: "Zedd", children:
[FileItem(name: "Photos", children:
[FileItem(name: "photo001.jpg"),
FileItem(name: "photo002.jpg")]),
FileItem(name: "Movies", children:
[FileItem(name: "movie001.mp4")]),
FileItem(name: "Documents", children: [])
]),
FileItem(name: "Alan Walker", children:
[FileItem(name: "Documents", children: [])
])
])
Swift
๋ณต์ฌ
์ด๋ ๊ฒ FileItem ํ์
์ด ์๋ค.
ํ์ผ์ด ์์์ผ๋ก ๋ ํ์ผ์ ๊ฐ์ง ์ ์์ผ๋ฏ๋ก children์ ํ์
์ [FileItem]์ด๊ณ ,
๊ฐ์ง ์๋ ์๊ณ , ์๊ฐ์ง ์๋ ์๊ธฐ ๋๋ฌธ์ ์ต์ข
ํ์
์ [FileItem]? ์ด ๋๋ค.
๊ทธ๋ฆฌ๊ณ fileName์ ๋ง์ฝ children์ด ์์ผ๋ฉด ํ์ผ ์ด๋ฆ์ ๋ณด์ฌ์ฃผ๊ณ ,
์๋ค๋ฉด ํด๋ ์์ด์ฝ๊ณผ ํจ๊ป ํด๋ ์ด๋ฆ์ ๋ณด์ฌ์ค๋ค.
OutlineGroup(root: Identifiable, children: KeyPath<Identifiable, _?>, content: (Identifiable) -> _)
Swift
๋ณต์ฌ
OutlineGroup์ ์ด๋ ๊ฒ root์ children์ ๋ฐ๋๋ค.
struct ContentView: View {
let data =
FileItem(...)
var body: some View {
NavigationView {
Form {
OutlineGroup(self.data, children: \.children) { item in
Text("\(item.fileName)")
}
}.navigationTitle("ํ์ผ")
}
}
}
Swift
๋ณต์ฌ