ViewModifier 和 圆角以及渐变色

ViewModifier

是什么

把一组样式或 UI 结构打包成可复用的东西,用 .modifier() 链式调用贴到任意 View 上。

类比 UIKit

UIKit 里你会封装一个函数来复用样式:

swift 复制代码
func styleToolButton(_ button: UIButton) {
    button.titleLabel?.font = .systemFont(ofSize: 25)
    button.setTitleColor(.white, for: .normal)
    button.frame.size = CGSize(width: 30, height: 30)
}

ViewModifier 干的是同一件事,但它不只能改属性,还能在原有 View 外面包一层新的 View 结构,这是普通函数做不到的:

swift 复制代码
struct BadgeModifier: ViewModifier {
    func body(content: Content) -> some View {
        ZStack(alignment: .topTrailing) {
            content  // 原来的 View 原封不动
            Text("99")
                .background(Color.red)
                .clipShape(Circle())
                .offset(x: 10, y: -10)
        }
    }
}

Image(systemName: "bell").modifier(BadgeModifier())
Image(systemName: "message").modifier(BadgeModifier())

本质

本质就是一个语法糖,功能上等价于自定义一个 View 然后把其他 View 塞进去,但它能融入 SwiftUI 的链式调用语法,用起来跟 .font() .foregroundColor() 一模一样。


圆角 + 渐变色 + 描边

是什么

SwiftUI 没有 UIKit 那样直接设置 layer.borderWidth 的属性,填充和描边需要两个图层叠加来实现。

类比 UIKit

UIKit 两行搞定:

swift 复制代码
view.layer.borderWidth = 4
view.layer.borderColor = UIColor.green.cgColor

SwiftUI 必须用 ZStack 叠两个 RoundedRectangle:

swift 复制代码
.background(
    ZStack {
        RoundedRectangle(cornerRadius: 20)
            .stroke(model.color, style: StrokeStyle(lineWidth: 4))
        RoundedRectangle(cornerRadius: 20)
            .fill(gradientStyle)
    }
)

为什么先 stroke 再 fill

stroke(描边)默认居中描边,线宽一半在内一半在外。fill 只填充内部区域,所以 fill 会覆盖 stroke 内侧的那一半。先画 stroke 再盖 fill,能让 stroke 外侧的一半露出来,边框视觉上更完整。反过来的话内侧边框线被盖住,边框显得细一半。

本质

这块 UIKit 确实更直观,SwiftUI 的声明式思路在这个场景下反而绕了一圈


本质

SwiftUI 没有 layer,只有 Shape + 绘制规则


fill 和 stroke 的区别

操作 本质
fill 填充 Shape 内部
stroke 沿路径画边

stroke 的问题

less 复制代码
.stroke(lineWidth: 4)

👉 描边在路径两侧(内 + 外)


推荐方案(更精准)

less 复制代码
.strokeBorder(lineWidth: 4)

👉 描边完全在内部


推荐结构

scss 复制代码
.fill(...)
.overlay(stroke)

👉 语义清晰:先填充,再叠加边框

ViewModifier

本质是 (View) -> View,不是修改 View,而是生成新 View


Modifier 顺序

顺序不是语法问题,而是 View 树结构

描边本质

边框不是属性,而是绘制结果(Shape + stroke)


相关推荐
sakiko_17 小时前
Swift学习笔记34-MVC架构,SwiftUI与UIkit混编练习
笔记·学习·swiftui·mvc·swift
sakiko_3 天前
Swift学习笔记33-多线程与UI渲染
笔记·学习·swiftui·swift
东坡肘子5 天前
从社区路标到生态基石:Dave Verwer 的新篇章 -- 肘子的 Swift 周报 #137
人工智能·swiftui·swift
Daniel_Coder9 天前
iOS Widget 开发-18:Widget 的 SwiftUI 视图适配与设计
ios·swiftui·swift·widget·widgetcenter
Daniel_Coder12 天前
iOS Widget 开发-12:Widget 深度链接与导航
ios·swiftui·swift·widget·intents
Daniel_Coder12 天前
iOS Widget 开发-11:Widget 交互按钮实战(iOS 17+ App Intents)
ios·swiftui·swift·widget·link·appintents
东坡肘子12 天前
消失的 WWDC 愿望单 -- 肘子的 Swift 周报 #136
人工智能·swiftui·swift
浩宇软件开发12 天前
SwiftUI入门 10 分钟学会做一个 App 引导页
ios·swiftui·swift
sakiko_15 天前
Swift报错合集(Xcode编译器)
开发语言·swiftui·xcode·swift·uikit
Joseph1818 天前
深度拆解 DanceUI:从声明式视图到原生渲染的全链路技术解析
ios·swiftui