はじめに
SwiftUI のコンポーネントまとめです。下記ドキュメントにあるやつをまとめました(ターゲットは iOS14 です)。
Stacks
HStack
UIStackView
の horizontal 相当?
1 |
@frozen struct HStack<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 |
HStack(alignment: .center, spacing: 16) { Rectangle() .fill(Color.red) .frame(width: 100, height: 100) Rectangle() .fill(Color.blue) .frame(width: 100, height: 100) } |
VStack
UIStackView
の vertical 相当?
1 |
@frozen struct VStack<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 |
VStack(alignment: .center, spacing: 4) { Rectangle() .fill(Color.red) .frame(width: 100, height: 40) Rectangle() .fill(Color.blue) .frame(width: 100, height: 40) } |
ZStack
View
を重ねるときに使うやつ?
1 |
@frozen struct ZStack<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 |
ZStack { Rectangle() .fill(Color.red) .frame(width: 100, height: 100) Rectangle() .fill(Color.blue) .frame(width: 100, height: 100) .offset(x: 10, y: 10) } |
Lazy Stacks
LazyHStack
HStack
のメモリ改善版?たぶん ScrollView
とかと組み合わせて使うやつ。画面表示される部分だけ読み込まれる。
1 |
struct LazyHStack<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 |
ScrollView(.horizontal) { LazyHStack { ForEach(1...100, id: \.self) { Text("Column \($0)") } } } |
LazyVStack
VStack
のメモリ改善版?たぶん ScrollView
とかと組み合わせて使うやつ。画面表示される部分だけ読み込まれる。
1 |
struct LazyVStack<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 |
ScrollView { LazyVStack { ForEach(1...100, id: \.self) { Text("Row \($0)") } } } |
Grids
LazyHGrid
UICollectionView
相当?横方向のグリッド表示ができる。
1 |
struct LazyHGrid<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 |
let rows: [GridItem] = Array(repeating: .init(.fixed(44)), count: 2) ScrollView(.horizontal) { LazyHGrid(rows: rows, alignment: .top) { ForEach(1...30, id: \.self) { num in ZStack { Rectangle().fill(Color.blue) Text("\(num)") } } } } |
LazyVGrid
UICollectionView
相当?縦方向のグリッド表示ができる。
1 |
struct LazyVGrid<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 |
let columns: [GridItem] = Array(repeating: .init(.flexible()), count: 2) ScrollView { LazyVGrid(columns: columns) { ForEach(0...30, id: \.self) { num in ZStack { Rectangle().fill(Color.green) Text("\(num)") } } } } |
GridItem
UICollectionViewCell
相当?たぶん LazyHGrid
, LazyVGrid
と組み合わせて使うやつ。
1 |
struct GridItem |
サイズは下記 3 つがある。
- adaptive
- fixed
- flexible
Containers
Form
入力系をグループ化するやつ?今まで UITableViewController
の static cell でやってたのがこいつでできるようになった感じ?
1 |
struct Form<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
@State private var name: String = "" @State private var birthday = Date() Form { Section(header: Text("Profile")) { TextField("Name", text: $name) DatePicker( "Birthday", selection: $birthday, displayedComponents: [.date] ) } } |
Group
View をグループ化するやつ?たぶんレイアウトに影響はない。
1 |
@frozen struct Group<Content> |
簡易実装。
1 2 3 4 5 6 |
Group { Text("First") Text("Second") Text("Third") } .font(.headline) |
GroupBox
ラベルを付けてグループ化してくれるやつ?(どういうとき使うかはちょっとよくわかってない。。。)
1 |
struct GroupBox<Label, Content> where Label : View, Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 |
@State private var userAgreed = false GroupBox(label: Label("Agreement", systemImage: "building.columns")) { ScrollView { Text("agreementText\nhogehoge\nfugafuga\npiyopiyo\nfoofoo") } .frame(height: 100) Toggle(isOn: $userAgreed) { Text("I agree") } } |
ControlGroup
iOS 15 以上用なので割愛。
1 |
struct ControlGroup<Content> where Content : View |
Scroll Views
ScrollView
UIScrollView
相当?Axis
で縦横指定ができる。デフォルトは vertical
。
1 |
struct ScrollView<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 |
ScrollView { VStack { ForEach(0..<100) { Text("Row \($0)") } } } |
ScrollViewReader
ScrollViewProxy
を利用して指定の ScrollView
の子 View にスクロールできるようにするためのやつ?
1 |
@frozen struct ScrollViewReader<Content> where Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
@Namespace var topID @Namespace var bottomID ScrollViewReader { proxy in ScrollView { Button("Scroll to Bottom") { withAnimation { proxy.scrollTo(bottomID) } } .id(topID) VStack { ForEach(0..<100) { Text("Row \($0)") } } Button("Top") { withAnimation { proxy.scrollTo(topID) } } .id(bottomID) } } |
ScrollViewProxy
指定の View にスクロールさせたいときに使うやつ?ScrollViewReader
を介して利用するもので直接生成とかはしない。
1 |
struct ScrollViewProxy |
Lists
List
UITableView
相当?これはよく使いそうなので別記事でまとめたい。
1 |
struct List<SelectionValue, Content> where SelectionValue : Hashable, Content : View |
簡易実装。
1 2 3 4 5 |
List { Text("First") Text("Second") Text("Third") } |
Section
List
, Picker
, Form
などで使えるヘッダー・フッター?
1 |
struct Section<Parent, Content, Footer> |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
List { Section(header: Text("First"), footer: Text("First")) { Text("Item 1") Text("Item 2") } Section(header: Text("Second"), footer: Text("Second")) { Text("Item 1") Text("Item 2") } } |
ForEach
Identifiable
に準拠したデータを一覧表示してくれるやつ(イマイチ List
との違いがわからない。。。)。
1 |
struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable |
簡易実装。
1 2 3 |
ForEach(0...3, id: \.self) { Text("Row \($0)") } |
Tables
Table
macOS 用なので割愛。
1 |
struct Table<Value, Rows, Columns> where Value == Rows.TableRowValue, Rows : TableRowContent, Columns : TableColumnContent, Rows.TableRowValue == Columns.TableRowValue |
Hierarchical Views
NavigationView
UINavigationController
相当?これはよく使いそうなのでまた別記事でまとめたい。
1 |
struct NavigationView<Content> where Content : View |
簡易実装。
1 2 3 |
NavigationView { Text("Select a Note").navigationTitle("Text") } |
NavigationLink
NavigationView
の画面遷移用?
1 |
struct NavigationLink<Label, Destination> where Label : View, Destination : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
NavigationView { List { NavigationLink("Purple", destination: ColorDetail(color: .purple)) NavigationLink("Pink", destination: ColorDetail(color: .pink)) NavigationLink("Orange", destination: ColorDetail(color: .orange)) } .navigationTitle("Colors") } struct ColorDetail: View { var color: Color var body: some View { color .frame(width: 200, height: 200) .navigationTitle(color.description.capitalized) } } |
OutlineGroup
ツリー構造がつくれる?
1 |
struct OutlineGroup<Data, ID, Parent, Leaf, Subgroup> where Data : RandomAccessCollection, ID : Hashable |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
struct FileItem: Hashable, Identifiable, CustomStringConvertible { var id: Self { self } var name: String var children: [FileItem]? = nil var description: String { switch children { case nil: return "📄 \(name)" case .some(let children): return children.isEmpty ? "📂 \(name)" : "📁 \(name)" } } } let data = FileItem(name: "users", children: [FileItem(name: "user1234", 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: "newuser", children: [FileItem(name: "Documents", children: []) ]) ]) OutlineGroup(data, children: \.children) { item in Text("\(item.description)") } |
DisclosureGroup
開閉式の View が表示できる?
1 |
struct DisclosureGroup<Label, Content> where Label : View, Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 |
@State private var expanded = true DisclosureGroup("Items", isExpanded: $expanded) { Text("Item 1") Text("Item 2") DisclosureGroup("Sub-items") { Text("Sub-item 1") } } |
TabView
UITabBarController
相当?
1 |
struct TabView<SelectionValue, Content> where SelectionValue : Hashable, Content : View |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
TabView { Text("The First Tab") .tabItem { Image(systemName: "1.square.fill") Text("First") } Text("Another Tab") .tabItem { Image(systemName: "2.square.fill") Text("Second") } Text("The Last Tab") .tabItem { Image(systemName: "3.square.fill") Text("Third") } } |
HSplitView
macOS 用なので割愛。
1 |
struct HSplitView<Content> where Content : View |
VSplitView
macOS 用なので割愛。
1 |
struct VSplitView<Content> where Content : View |
Scheduled View Updates
TimelineView
iOS 15 以上なので割愛。
1 |
struct TimelineView<Schedule, Content> where Schedule : TimelineSchedule |
Spacers and Dividers
Spacer
自動で拡縮される余白?UIBarButtonItem
の flexibleSpace
のようなもの?
1 |
@frozen struct Spacer |
簡易実装。
1 2 3 4 5 |
HStack { Spacer() Image(systemName: "checkmark") Text("name") } |
Divider
セパレータ?これで View
同士の区切りがわかりやすくなる!
1 |
struct Divider |
簡易実装。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
HStack { Image(systemName: "checkmark") Divider() Text("name") Divider() VStack { Divider() Image(systemName: "checkmark") Divider() Text("name") Divider() } } |
おわりに
一覧表示系が充実した印象。今まで UITableView
, UITableViewController
で頑張ってたのをいろいろなやつに分けられた感じがする。
まだあまりそれぞれの使い道がよくわかっていないのでじっくりならしたいきたい。
パーツ系でもう一つドキュメントがあったけど上級者向けな気がしてまとめるか迷う。。。
コメント