ViewModifier는 중복되는 코드를 줄여줄 수 있는 방법 중 하나입니다
ViewModifier 프로토콜을 사용하여 어떤 뷰에서든 재사용 가능한 modifier를 만들 수 있습니다. 아래는 비슷한 UI를 가진 Text를 여러개를 포함한 코드입니다.
var body: some View {
Text("Hello, world")
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.padding()
Text("Hello, everyone")
.font(.headline)
.foregroundStyle(.green)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.padding()
Text("Hello, anyone")
.font(.headline)
.foregroundStyle(.black)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.padding()
}
하지만 ViewModifier를 사용하게 된다면 다음처럼 간략하게 바뀝니다. ViewModifier에서 body는 수정할 UI의 특징을 작성하는 곳이고 Content는 수정되는 주체를 의미합니다. (버튼이면 버튼, 텍스트면 텍스트)
ViewModifier 적용했을 때
ViewModifier를 사용하면 더 간결하게 코드를 작성할 수 있음을 확인할 수 있습니다.
struct DefaultButtonModifier: ViewModifier {
func body(content: Content) -> some View {
content
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(Color.blue)
.padding()
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world")
.modifier(DefaultButtonModifier())
Text("Hello, everyone")
.modifier(DefaultButtonModifier())
Text("Hello, anyone")
.modifier(DefaultButtonModifier())
}
}
View extension 을 사용하여 커스텀화하기
View extension을 사용하여 modifier를 적용한 뷰를 반환하는 메서드를 만들게 된다면 다음과 같이도 사용될 수 있습니다.
extension View {
func withDefaultButtonFormatting() -> some View {
modifier(DefaultButtonModifier())
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world")
.withDefaultButtonFormatting()
// .modifier(DefaultButtonModifier())
Text("Hello, everyone")
.withDefaultButtonFormatting()
// .modifier(DefaultButtonModifier())
Text("Hello, anyone")
.withDefaultButtonFormatting()
// .modifier(DefaultButtonModifier())
}
}
ViewModifier 다이나믹하게 만들어 사용하기
ViewModifier 내부에 다이나믹하게 동작하도록 배경 색깔을 따로 지정할 수 있도록 만들었습니다. 그 외에 모든 요소들이 가능하며 이는 뷰마다의 제각각 특징을 가져야 하는 상황에서 유용하게 사용됩니다.
struct DefaultButtonModifier: ViewModifier {
let backgroundColor: Color
func body(content: Content) -> some View {
content
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(backgroundColor)
.padding()
}
}
extension View {
func withDefaultButtonFormatting(backgroundColor: Color = .blue) -> some View {
modifier(DefaultButtonModifier(backgroundColor: backgroundColor))
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world")
.withDefaultButtonFormatting()
Text("Hello, everyone")
.withDefaultButtonFormatting(backgroundColor: .orange)
Text("Hello, anyone")
.withDefaultButtonFormatting(backgroundColor: .pink)
}
}
총 코드
import SwiftUI
struct DefaultButtonModifier: ViewModifier {
let backgroundColor: Color
func body(content: Content) -> some View {
content
.font(.headline)
.foregroundStyle(.white)
.frame(height: 55)
.frame(maxWidth: .infinity)
.background(backgroundColor)
.padding()
}
}
extension View {
func withDefaultButtonFormatting(backgroundColor: Color = .blue) -> some View {
modifier(DefaultButtonModifier(backgroundColor: backgroundColor))
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world")
.withDefaultButtonFormatting()
// .modifier(DefaultButtonModifier())
Text("Hello, everyone")
.withDefaultButtonFormatting(backgroundColor: .orange)
// .modifier(DefaultButtonModifier())
Text("Hello, anyone")
.withDefaultButtonFormatting(backgroundColor: .pink)
// .modifier(DefaultButtonModifier())
}
}
#Preview {
'SwiftUI' 카테고리의 다른 글
Background Threads, Queues (0) | 2024.04.07 |
---|---|
버튼 커스텀화하기, Custom ButtonStyle (0) | 2024.04.07 |
@FocusState 로 키보드 다루기 (0) | 2024.04.06 |
swipeActions (0) | 2024.04.06 |
.sheet(), .transition(), .animation (0) | 2024.04.06 |