SwiftUI ViewModifier

ViewModifier 是应用于视图或其他视图修改器的修改器,生成一个新View

image.png

关于 ViewModifiers 的另一个有趣的事实是它符合View协议。这意味着可以在ViewModifiers内部使用属性包装器,例如 @State@Binding@Environment@ObservableObject@EnvironmentObject。还可以使其具有动画效果等。

只要遵循ViewModifier,任何类型 (通常是 struct) 都可以當一個view modifier。此协议只有一個必要条件,就是要有一個可以接收View然後將它转换成另一个View 的方法:body()

protocol ViewModifier {
    // input type of body() method
    typealias Content
    // output type of body() method
    associatedtype Body : View
    // #todo: 為什麼 Content 是 typealias,而 Body 是 associatedtype?

    // only requirement
   func body(content: Self.Content) -> Self.Body
}

通常实现ViewModifier后,搭配extension View使用。

示例

import SwiftUI

public struct Watermark: ViewModifier {
    
    // watermark text
    public var text: String     = "📌 watermark"
    public var align: Alignment = .bottomTrailing
    
    // body
    public func body(content: Content) -> some View {
        
        let textView = Text(text)
            .font(.caption)
            .foregroundColor(.white)
            .padding(8)
            .background(Color.black).padding(5)
            .opacity(0.6)
        
        return content.overlay(textView, alignment: align)
    }
}

extension View {
    // use view modifier
    public func watermark(
        _ text : String    = "📌 watermark", 
        _ align: Alignment = .bottomTrailing
    ) -> some View {
        self.modifier(Watermark(text: text, align: align))
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            Color.gray.watermark()
            Color.gray.watermark("hello", .topTrailing)
        }
    }
}