SwiftUI

SwiftUI 공통 스타일 주기 Custom View Modifier

하이D:) 2023. 6. 1. 17:47

재사용되는 SwiftUI 코드를 Custom View Modifier로 만들어주기

UI를 만들다보면 재사용되는 스타일이 생기기 마련이다. 이 경우에 같은 코드를 반복해서 사용하면 매우 길고 가독성이 낮은 코드가 되기 때문에 이러한 상황에서 유용하게 사용할 수 있는 Custom View Modifier를 활용해서 코드를 가독성있게 만들어주었다.

🥨 1. 단순한 Custom View Modifier 만들어주기

1) 우선 나는 다양한 Custom View Modifier를 만들기 위해 폴더를 생성해주고 그 아래에 각각 관련된 Modifier를 작성할 파일을 나누어주었다.

2) 우선 내가 가장 자주 사용한 스타일에 대한 구조체는 이렇게 작성해주었다

import Foundation
import SwiftUI

struct GreenGradientButton : ViewModifier {
    func body(content: Content) -> some View {
        content
            .frame(maxWidth: .infinity)
            .padding()
            .font(.system(size: 16, weight : .bold))
            .foregroundColor(.white)
            .background( LinearGradient(gradient: Gradient(colors: [.gradation1, .gradation2, .gradation3]), startPoint: .leading, endPoint: .trailing))
            .cornerRadius(12)
    }
}

3) 이제 이렇게 만들어준 구조체를 View의 extension에 함수로서 저장해주어야한다

extension View {

    func asGreenGradientButton() -> some View {
        modifier(GreenGradientButton())
    }

}

4) 실제 코드에 적용

    Button {
        print("--")

    } label: {
        Text("시작하기")
            .asGreenGradientButton()
    }

🥨 2. 다양한 파라미터를 받아 활용하는 View Modifier 만들어주기

1) 이렇게 구조체에서 속성값을 받아주고 그 값으로 뷰를 그려주면된다

import Foundation
import SwiftUI

struct GreenToggleButton : ViewModifier {
    var isGreen : Bool //초록 버튼일 때 true, 회색 버튼일 때 false

    func body(content: Content) -> some View {
        content
            .frame(maxWidth: .infinity)
            .padding()
            .font(.system(size: 16, weight : .bold))
            .foregroundColor( isGreen ? .white : .gray)
            .background( isGreen ? .pointGreen3 : Color(UIColor.systemGray5))
            .cornerRadius(12)
    }
}

2) 위의 방법과 동일하게 구조체를 View의 extension에 함수로서 저장해준다. 이 때 중요한 것은 View Modifier를 초기화하며 속성값을 전달해야하는 것이다.

extension View {

    func asGreenGradientButton() -> some View {
        modifier(GreenGradientButton())
    }

    func asGreenToggleButton(isGreen bool : Bool) -> some View {
        modifier(GreenToggleButton(isGreen : bool))
    }

}

3) 실제코드에서 활용할 때에는 이렇게 인수를 전달하면 그 값에 따라 스타일이 다르게 변화하게된다.

    Button {
        print("--")

    } label: {
        Text("시작하기")
            .asGreenToggleButton(isGreen : vm.haveExperience == item)
    }

🥨 3. 실제 활용 코드 및 시뮬레이터

import SwiftUI

struct CustomViewModifierView: View {
    @State var isGreen : Bool = true

    var body: some View {
        VStack{
            Button {
                self.isGreen.toggle()
            } label: {
                Text("시작하기")
                    .asGreenToggleButton(isGreen : isGreen)
            }
            .padding(.horizontal)
        }
    }
}