apple/SwiftUI & Combine
[SwiftUI] LazyVGrid
lgvv
2022. 5. 25. 17:20
LazyVGrid
SwiftUI에 대해서 알아가고 있는데, UIKit에 비해서는 아직 어렵다.
UIKit이라면 금방 했을탠데, 아직까지는 숙련도가 낮은 것 같아서 어렵다. 적응하면 쉬워지겠지
iOS 14 혹은 15를 타겟으로 개발하고 있는데 SwiftUI가 80프로까지는 금방 만드는데, 결국 UIKit을 사용해야하는 시점에서는 점점 손이 많이가기 시작한다.
SwiftUI가 시간이 흐르면서 더 발전하겠지
✅ 코드
import Foundation
import SwiftUI
enum LayoutType: CaseIterable {
case table, grid, multiple
}
extension LayoutType {
// 레이아웃 타입에 대한 컬럼이 자동으로 설정되도록 한다
var columns : [GridItem] {
switch self {
case .table:
return [
// flexible 하나로 한줄로 표현
GridItem(.flexible())
]
case .grid:
return [
// flexible 두개를 넣어서 두개 아이템 들어가게 함
GridItem(.flexible()),
GridItem(.flexible())
]
case .multiple:
return [
// 어답티브를 통해 크기 닿는데 까지 아이템 여러개 넣기
GridItem(.adaptive(minimum: 100))
]
}
}
}
struct SegmentLayoutView: View {
var dummyDatas = MyModel.dummyDataArray
@State var selectedLayoutType: LayoutType = .table
var body: some View{
VStack{
// 피커
Picker(selection: $selectedLayoutType, label: Text("레이아웃 타입"), content: /*@START_MENU_TOKEN@*/{
ForEach(LayoutType.allCases, id: \.self , content: { layoutType in
switch layoutType {
case .table:
Image(systemName: "list.dash")
case .grid:
Image(systemName: "square.grid.2x2.fill")
case .multiple:
Image(systemName: "circle.grid.3x3.fill")
}
})
}/*@END_MENU_TOKEN@*/)
.frame(width: 250)
.pickerStyle(SegmentedPickerStyle())
// 내용물
ScrollView{
LazyVGrid(columns: selectedLayoutType.columns, content: /*@START_MENU_TOKEN@*/ {
// Contents쪽에 switch문 달아서 view전환
ForEach(dummyDatas) { dataItem in
switch selectedLayoutType {
case .table:
Card(icon: "book.fill", title: "책읽기", start: "1 PM", end: "3 PM", bgColor: Color.green)
case .grid:
RoundedRectangle(cornerRadius: 25.0)
.foregroundColor(Color.init(#colorLiteral(red: 1, green: 0.5758225922, blue: 0.3784928128, alpha: 1)))
.frame(height: 200)
.overlay(
VStack(spacing: 2){
Circle().frame(height: 100)
.foregroundColor(.yellow)
Spacer().frame(height: 10)
Text("\(dataItem.title)")
.font(.system(size: 20))
.fontWeight(.bold)
Text("\(dataItem.content)")
}
)
case .multiple:
Rectangle()
.foregroundColor(.blue)
.frame(height: 100)
}
}
}/*@END_MENU_TOKEN@*/)
.animation(.easeInOut) // 효과 달아주기
.padding(.horizontal, 10)
}
}
}
}
✅ 내가 직접 구현해보자
import SwiftUI
enum LayoutType: CaseIterable {
case table, grid, multiple
var columns: [GridItem] {
switch self {
case .table:
return [GridItem(.flexible())]
case .grid:
return [
GridItem(.flexible()),
GridItem(.flexible())
]
case .multiple:
return [GridItem(.adaptive(minimum: 100))]
}
}
}
struct HomeView: View {
@State var selectedLayoutType: LayoutType = .table
var body: some View {
VStack(spacing: 0) {
Picker("", selection: $selectedLayoutType) { // picker를 스위치문으로 관리
ForEach(LayoutType.allCases, id: \.self) {
switch $0 {
case .table: Image(systemName: "list.dash")
case .grid: Image(systemName: "square.grid.2x2.fill")
case .multiple: Image(systemName: "circle.grid.3x3.fill")
}
}
}
.pickerStyle(.segmented)
.padding()
Spacer()
ScrollView {
LazyVGrid(
columns: selectedLayoutType.columns,
spacing: 5
) {
ForEach((0...30), id: \.self) { index in
switch selectedLayoutType { // 스위치문!
case .table:
RoundedRectangle(cornerRadius: 25.0)
.frame(height: 100)
.foregroundColor(.blue)
.padding([.leading, .trailing], 10)
case .grid:
RoundedRectangle(cornerRadius: 25.0)
.frame(height: 200)
.foregroundColor(.blue)
.overlay(
VStack(spacing: 2){
Circle()
.frame(height: 100)
.foregroundColor(.yellow)
Spacer().frame(height: 10)
Text("\(index)")
.font(.system(size: 20))
.fontWeight(.bold)
Text("\(index)")
}
)
case .multiple:
Rectangle()
.foregroundColor(.blue)
.frame(height: 100)
}
}
}
.animation(.easeInOut)
.padding(.horizontal, 10)
}
Spacer()
}
}
}
struct HalfSheet_Previews: PreviewProvider {
static var previews: some View {
HomeView()
}
}
extension Color {
static func random() -> Color {
let random = Double(CGFloat(arc4random()) / CGFloat(UInt32.max))
return Color(
red: random,
green: random,
blue: random
)
}
}