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...

相关推荐
默_笙9 分钟前
🚤 CSS 布局的"圈地运动":BFC 就是浏览器的独立领地
前端·javascript
我爱写代码i11 分钟前
AI对话绘画数字人源码 - uniapp前端
前端·人工智能·uni-app
OpenTiny社区34 分钟前
太酷了!装上OpenTiny dsh‑genui这个插件,你的DeepSeek Harness点击就能干活了!
前端·ai编程
ModyQyW40 分钟前
vite-plugin-uni-pages 更新了什么
前端·uni-app
前端大卫1 小时前
H5 渲染 PDF 并添加高亮的两种方案【附源码】
前端
因_崔斯汀2 小时前
用 AI 生成 Three.js 沉浸式网站,代码与 Skill 均已开源
前端·人工智能
葡萄城技术团队2 小时前
一键触发工作表中所有异步函数:用依赖单元格刷新 SpreadJS 公式
前端
Bigger2 小时前
谁动了我的 URL?——记一次微前端"灵异 Bug"的排查实录
前端·ai编程·vue-router
JavaGuide3 小时前
轻量开源版 IDEA 来了!
前端·后端
张洪权3 小时前
nest.js websocket 群聊----私聊功能
前端·nestjs