SwiftUI로 무작정 만들기 4탄, Grid 기본형

해류·2022년 6월 9일
0
post-thumbnail

결과물

설명 : 가장 간단한 그리드뷰를 만들어 봤다. 2행짜리 column으로 구성하고 ForEach로 struct 데이터를 뿌렸고, TabView의 tag와 TabButton의 index를 연동시켰다.

사실 설명할 것도 없다. 처음 만들어보는 그리드뷰이지만, 아주 쉬운 방법으로 만들었다. 코드에 대한 자세한 설명은 코드안에


Home

import SwiftUI

struct Home: View {
    
    @State var index = 0

    var body: some View {
        
        VStack {
            //Title
            HStack {
                Text("STAT")
                    .font(.title)
                    .fontWeight(.bold)
                    .foregroundColor(.black)
                
                Spacer(minLength: 0)
            }
            .padding(.horizontal)
            
            //TabButton
            HStack(spacing: 0) {
                //Day
                Text("Day")
                    .foregroundColor(index == 0 ? .white : .black.opacity(0.7))
                    .fontWeight(.bold)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 35)
                    .background(.black.opacity(index == 0 ? 1 : 0))
                    .clipShape(Capsule())
                    .onTapGesture {
                        index = 0
                    }
                Spacer(minLength: 0)
                //Week
                HStack(spacing: 0) {
                    Text("Week")
                        .foregroundColor(index == 1 ? .white : .black.opacity(0.7))
                        .fontWeight(.bold)
                        .padding(.vertical, 10)
                        .padding(.horizontal, 35)
                        .background(.black.opacity(index == 1 ? 1 : 0))
                        .clipShape(Capsule())
                        .onTapGesture {
                            index = 1
                        }
                }
                Spacer(minLength: 0)
                //Month
                HStack(spacing: 0) {
                    Text("Month")
                        .foregroundColor(index == 2 ? .white : .black.opacity(0.7))
                        .fontWeight(.bold)
                        .padding(.vertical, 10)
                        .padding(.horizontal, 35)
                        .background(.black.opacity(index == 2 ? 1 : 0))
                        .clipShape(Capsule())
                        .onTapGesture {
                            index = 2
                        }
                }
            }//TabButton
            .background(.black.opacity(0.06))
            .clipShape(Capsule())
            .padding(.top, 25)

            
            TabView(selection: $index) {
                GridView(fit_Data: day_Fit_Data)
                    .tag(0)
                GridView(fit_Data: week_Fit_Data)
                    .tag(1)
                GridView(fit_Data: month_Fit_Data)
                    .tag(2)
            }
            //TabView의 selection에 animation을 적용하면, index의 변화에 따라 화면의 이동을 보여준다.
            //이곳이 아닌 위의 TabButton에 적용시, day-week-month에 적용해둔 index를 따라 애니메이션이 적용됨.
            .animation(.easeInOut, value: index)
            //탭뷰에 스크롤링 기능 추가
            .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
            
            Spacer(minLength: 0)
            
        }
        .padding(.top)
    }
}

GridView

import SwiftUI

struct GridView: View {
    
    //Grid에 필요한 columns 어레이와 GridItem을 repeating을 이용해 표현
    //columns에 있는 spacing은 행간의 공간 너비를 뜻함
    var columns = Array(repeating: GridItem(.flexible(), spacing: 20), count: 2)
    
    //아니라면 아래처럼 일일히 배열을 넣어줘야함
//    let columns: [GridItem] = [
//            GridItem(.flexible(), spacing: 20),
//            GridItem(.flexible(), spacing: 20) ]
    
    var fit_Data: [Fitness]
    
    var body: some View {
        
        //Grid에 있는 spacing은 열간의 여분 공간 높이를 뜻함
        LazyVGrid(columns: columns, spacing: 30) {
            
            ForEach(fit_Data) { fitness in
                ZStack(alignment: .topTrailing) {
                    VStack(alignment: .leading, spacing: 15) {
                        Text(fitness.title)
                            .foregroundStyle(.white)
                        Text(fitness.data)
                            .font(.system(size: 25, weight: .bold))
                            .foregroundStyle(.white)
                            .padding(.top, 10)
                        
                        HStack {
                            Spacer()
                            
                            Text(fitness.suggest)
                                .foregroundStyle(.white)
                        }
                    }
                    .padding()
                    .background(Color(fitness.image))
                    .cornerRadius(20)
                    .shadow(color: .black.opacity(0.2), radius: 5, x: 1, y: 5)
                    
                    Image(fitness.image)
                        .foregroundColor(.white)
                        .padding()
                        .background(.white.opacity(0.12))
                        .clipShape(Circle())
                        .padding(5)
                }
            }
        }
        .padding(.horizontal)
        .padding(.top, 25)
    }
}

생각

이걸 만든 후에 차례로 어려운 그리드를 그려보려고 했는데. 갑자기 만들고 싶은게 생겼다.. 그것은 바로!! 이거.

나는 단순히 탭뷰로 화면이 이동하고 배경이 온오프 하도록 만들었는데, 위에 것처럼 스크롤링에 따라 불이 글씨 색이 점점 변하고 하단 캡슐바가 따라 이동하면서 스냅되도록 만들고 싶다. 추가로 위에 탭버튼을 그냥 누를때도 살짝 딜레이 있게 캡슐바가 이동한다. 나는 버튼 애니메이션 같이 뭔가 쓸데없지만 멋지걸 만드는게 재밌고 좋다. 만들어 봐야지.

profile
iOS 개발자 지망생

0개의 댓글