📕 iOS/SwiftUI

[SwiftUI] custom view modifier 만들기

이오🐥 2023. 8. 31. 16:43

Text나 Image 등에 같은 modifier를 계속 반복해서 쓰다보면,

아 이거 그냥 한번에 쓸 수 없나? 이런 생각을 하게 되는데!!

 

Apple SwiftUI 문서에 이미 친절하게 알려주고 있었다! 푸하하 이걸 이제 봤다니!!

 

ViewModifier | Apple Developer Documentation

A modifier that you apply to a view or another view modifier, producing a different version of the original value.

developer.apple.com


먼저 ViewModifier가 뭘까?

너무도 당연히 .(dot) 과 함께 사용하고 있는 이 modifier는

view을 원래의 값과 다르게 만들고 싶을 때 view나 다른 view modifier에 적용하는 아이다!

그리고 protocol이네?


그럼 이제 내가 modifier를 만들어서 사용하는 방법을 알아보자!!

 

먼저, ViewModifier protocol을 따르는 struct를 만들어야한다.

여기서는 둥근 사각형 테두리의 파란색 caption text를 만들어보려고 한다.

struct BorderedCaption: ViewModifier {
    func body(content: Content) -> some View {
        content
            .font(.caption2)
            .padding(10)
            .overlay(
                RoundedRectangle(cornerRadius: 15)
                    .stroke(lineWidth: 1)
            )
            .foregroundColor(Color.blue)
    }
}

이렇게 만든 BorderedCaption은 어떻게 쓰냐면

Text("둥근 caption")
	.modifier(BorderedCaption())

이렇게 modifier에 struct를 직접 넣어줘야 한다...!

 

하지만, 이렇게 modifier라고 말하고 struct를 넣어주는 것보다

그냥 내가 직접 .borderedCaption() !! 이렇게 쓰고 싶단 말이다!

 

 

그래서 Apple은 extension에 추가하는 방법을 알려준다ㅎㅎ

extension View {
    func borderedCaption() -> some View {
        modifier(BorderedCaption())
    }
}

이렇게 extension을 추가해주면..! 드디어..!!

Image(systemName: "bus")
    .resizable()
    .frame(width:50, height:50)
Text("Downtown Bus")
    .borderedCaption()

이렇게 아주 편하게 사용할 수 있다~!~!!


나는 custom Font를 사용하면서,

Text의 modifier를 .font, .frame(height: ~~), .foregroundColor() 를 매번 사용해야해서

이 세 개를 합쳤다!

 

그리고 modifier안에 값을 전달해주고 싶었는데,

struct 내부에 font와 color를 선언해주고,

extension으로 만든 method에 전달할 수 있도록 만들었다.

 

추가로, 나는 height를 매번 입력하지 않고 자동으로 들어갈 수 있도록 만들어주었다.

import SwiftUI

struct ㅁㅁFontModifier: ViewModifier {
    let font: Font
    let color: Color
    let heightFor: [Font: CGFloat] = [
        Font.ㅁㅁH1: 36,
        Font.ㅁㅁH2: 32,
        Font.ㅁㅁSubtitle1Medium: 28,
        Font.ㅁㅁSubtitle1Semibold: 28
    ]
    
    func body(content: Content) -> some View {
        content
            .font(font)
            .frame(height: heightFor[font])
            .foregroundColor(color)
    }
}

extension View {
    func ㅁㅁFont(font: Font, color: Color) -> some View {
        modifier(ㅁㅁFontModifier(font: font, color: color))
    }
}

ㅁㅁ은 우리 프로젝트 이름을 바꾼 것ㅎㅎ,,

이렇게 만들어서 어떻게 썼냐면?

 

Text("아직 공지사항이 없어요")
	.ㅁㅁFont(font: .ㅁㅁCaption1, color: .gray400)

요렇게! 각 Text의 font와 color만 전달할 수 있도록 했다~!!

 


반복되는 modifier를 하나로 합쳐서 쓰니 얼마나 좋은가! 우하하

이상 custom view modifier를 만들어 보았다!!

'📕 iOS > SwiftUI' 카테고리의 다른 글

[SwiftUI] storyboard로 Launch Screen 구현  (0) 2024.06.23
[SwiftUI] Info.plist로 Launch Screen 구현  (0) 2023.05.04