swiftUI视图修改器(ViewModifier)解析

作为SwiftUI框架的核心概念之一,视图修改器(ViewModifier)为我们提供了一种优雅的方式来封装和重用视图的样式和行为。

这是视图修改器的源码

swift 复制代码
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
extension View {

    /// Applies a modifier to a view and returns a new view.
    ///
    /// Use this modifier to combine a ``View`` and a ``ViewModifier``, to
    /// create a new view. For example, if you create a view modifier for
    /// a new kind of caption with blue text surrounded by a rounded rectangle:
    ///
    ///     struct BorderedCaption: ViewModifier {
    ///         func body(content: Content) -> some View {
    ///             content
    ///                 .font(.caption2)
    ///                 .padding(10)
    ///                 .overlay(
    ///                     RoundedRectangle(cornerRadius: 15)
    ///                         .stroke(lineWidth: 1)
    ///                 )
    ///                 .foregroundColor(Color.blue)
    ///         }
    ///     }
    ///
    /// You can use ``modifier(_:)`` to extend ``View`` to create new modifier
    /// for applying the `BorderedCaption` defined above:
    ///
    ///     extension View {
    ///         func borderedCaption() -> some View {
    ///             modifier(BorderedCaption())
    ///         }
    ///     }
    ///
    /// Then you can apply the bordered caption to any view:
    ///
    ///     Image(systemName: "bus")
    ///         .resizable()
    ///         .frame(width:50, height:50)
    ///     Text("Downtown Bus")
    ///         .borderedCaption()
    ///
    /// ![A screenshot showing the image of a bus with a caption reading
    /// Downtown Bus. A view extension, using custom a modifier, renders the
    ///  caption in blue text surrounded by a rounded
    ///  rectangle.](SwiftUI-View-ViewModifier.png)
    ///
    /// - Parameter modifier: The modifier to apply to this view.
    @inlinable nonisolated public func modifier<T>(_ modifier: T) -> ModifiedContent<Self, T>
}

首先要明确ViewModifier协议

swift 复制代码
@MainActor @preconcurrency
public protocol ViewModifier {
    associatedtype Body : View

    @ViewBuilder
    func body(content: Self.Content) -> Self.Body

    typealias Content
}

可以看出,必须有一个要修改的视图和修改的方法。

下面是一个推荐的示例

1 视图样式定义

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

2 添加到视图view中,作为view的扩展

这样应用中的所有视图都可以像普通样式一样添加

swift 复制代码
extension View {
    func borderedCaption() -> some View {
        modifier(BorderedCaption())
    }
}

3 应用修改器

swift 复制代码
Image(systemName: "bus")
    .resizable()
    .frame(width:50, height:50)
Text("Downtown Bus")
    .borderedCaption()

如果你需要传递参数:

swift 复制代码
struct CustomPadding: ViewModifier {
    let amount: CGFloat
    
    func body(content: Content) -> some View {
        content.padding(amount)
    }
}

extension View {
    func customPadding(_ amount: CGFloat) -> some View {
        modifier(CustomPadding(amount: amount))
    }
}

其实SwiftUI 中每个 .padding(), .background(), .foregroundColor() 其实都是 视图修饰器 (modifier)

官方地址:developer.apple.com/documentati...

相关推荐
Komorebi_999918 分钟前
Unocss
开发语言·前端
goto_w1 小时前
前端实现复杂的Excel导出
前端·excel
Baklib梅梅1 小时前
2025文档管理软件推荐:效率、安全与协作全解析
前端·ruby on rails·前端框架·ruby
卷Java2 小时前
小程序前端功能更新说明
java·前端·spring boot·微信小程序·小程序·uni-app
FogLetter2 小时前
前端性能救星:虚拟列表原理与实现,让你的10万条数据流畅如丝!
前端·性能优化
我是天龙_绍2 小时前
前端驼峰,后端下划线,问:如何统一?
前端
知识分享小能手2 小时前
微信小程序入门学习教程,从入门到精通,微信小程序常用API(下)——知识点详解 + 案例实战(5)
前端·javascript·学习·微信小程序·小程序·vue·前端开发
code_YuJun2 小时前
nginx 配置相关
前端·nginx
对不起初见3 小时前
PlantUML 完整教程:从入门到精通
前端·后端