使用 IBDesignable 和 IBInspectable 添加 CAGradientLayer

原文:Adding a CAGradientLayer with IBDesignable and IBInspectable @ Hacking With Swift

魔术实际上是一种误导的艺术:让人们将注意力集中到一件事情上,以阻止他们关注另一件事。在我们的案例中,我们不想让用户怀疑你的 Apple Watch 是在帮你找星星,所以我们要用误导的方式让他们过度关注,让他们在想到你的手表之前就怀疑其他一切。

我们要做的第一件事是给我们的视图添加一个背景。这将是一个简单的渐变,但我们要让渐变颜色在红色和蓝色之间缓慢变化。这不会影响你找到星星的能力,但如果它让你的朋友怀疑这个技巧是在背景为红色时点击卡片,那么它就完成了误导的工作。

在 iOS 中创建渐变并不难,这要归功于一个名为 CAGradientLayer 的特殊 CALayer 子类。尽管如此,直接使用图层并不令人愉快,因为它们不能参与诸如自动布局这样的事情,也不能在 Interface Builder 中使用。

所以,我将教你如何在 UIView 中添加一个渐变,同时也增加了让你在 Interface Builder 中直接控制渐变的好处。更重要的是,你会惊讶于它的简单程度。

在你的项目中创建一个新的 Cocoa Touch 类。将其作为 UIView 的子类,然后将其命名为 GradientView。我们需要这个类为我们的渐变有一个顶部和底部的颜色,但我们也希望这些值在 Interface Builder 中是可见的(和可编辑的)。这可以通过两个新的关键字来实现。@IBDesignable@IBInspectable

其中第一个关键字 @IBDesignable 意味着 Xcode 应该构建该类,并使其在每当做出更改时都能在 Interface Builder 中绘制。这意味着您所做的任何自定义绘图都将反映在 Interface Builder 中,就像您的应用程序实际运行时一样。

第二个新的关键字,@IBInspectable,从您的类中公开一个属性,作为接口生成器中的一个可编辑的值。Xcode 知道如何以有意义的方式处理各种数据类型,因此字符串将有一个可编辑的文本框,布尔值将有一个复选框,颜色将有一个颜色选择调色板。

除了为渐变的顶部和底部颜色定义属性外,GradientView 类只需要完成另外两件事:当 iOS 询问它使用什么样的图层进行绘制时,它应该返回 CAGradientLayer,当 iOS 告诉视图布局其子视图时,它应该将颜色应用到渐变中。

使用这种方法意味着整个类只有 12 行代码,包括空格和括号。下面是 GradientView 类的代码:

swift 复制代码
@IBDesignable class GradientView: UIView {
    @IBInspectable var topColor: UIColor = UIColor.white
    @IBInspectable var bottomColor: UIColor = UIColor.black
    
    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }
    
    override func layoutSubviews() {
        (layer as! CAGradientLayer).colors = [topColor.cgColor, bottomColor.cgColor];
    }
}

有了这个新类,现在是时候返回到 Interface Builder 并将其添加到我们的布局中了。要做到这一点,请绘制另一个 UIView,但要确保这次它从边缘延伸到边缘,并添加一些自动布局规则,以确保它保持边缘。最后,进入 Editor 菜单,选择 Arrange > Send To Back,确保新视图位于卡片容器后面。

对于采用长方形屏幕的 iPhone,我们所做的已经足够好了--该渐变视图现在将充满屏幕。但 iPhone X 的屏幕边缘是圆形的,因此安全区域的镶边会自动启动,将渐变视图从边缘推开。这不是我们想要的,我们需要在 IB 中解决这个问题。

因此,选择视图控制器的主视图--包含渐变视图的视图--并在尺寸检查器中取消选中安全区域相对边距和安全区域布局指南。这样一来,渐变视图就能很好地在边缘与边缘之间运行了。

我们希望这个新视图是一个 GradientView,通过改变它的类来实现。 按 Alt+Cmd+3 键调出右侧的 Identity Inspector,然后看最上面的类的下拉列表,你可以为新视图使用。在那里寻找 GradientView,你会看到 "Designables: Updating "出现。

几秒钟后,你应该会看到在 Interface Builder 中出现一个从白色到黑色的渐变,它显示的是我们设置的默认颜色。但是我们让这些颜色可以检查,所以如果你按 Alt+Cmd+4 进入 Attributes Inspector,你应该会看到 "Top Color "和 "Bottom Color "供你选择--是的,由于我们的属性命名约定,Xcode 已经正确地将 topColor 转换为 "Top Color"。

我们将分别将红色和蓝色应用到渐变中,所以请将 "Top Color "设置为 "Dark Gray Color","Bottom Color "设置为 "Black Color"。最后,将渐变视图的 alpha 值设置为 0.9,这样背景视图就会有一点显示出来。

在我们完成 Interface Builder 之前(这次是真的!),请使用辅助编辑器为这个新的渐变视图创建一个名为gradientView 的 outlet。我们现在不需要这个,但它在下一章很重要。

如果一切正确,你的界面应该像下面的截图一样。和之前一样,我已经给我的容器视图涂上了颜色,所以你可以看到它,但是你的容器视图的背景色应该是 Clear Color。

有了所有这些界面的改变,我们只需要几行代码就可以对主视图的背景颜色进行动画处理。为了实现这个功能,我们将使用三个动画选项:.allowUserInteraction(让用户可以点击卡片),.autoreverse(自动反转)让视图回到原来的颜色,.repeat(重复)让动画永远循环往复。

把这段动画代码放在 viewDidLoad() 的某个地方。

swift 复制代码
view.backgroundColor = UIColor.red

UIView.animate(withDuration: 20, delay: 0, options: [.allowUserInteraction, .autoreverse, .repeat], animations: {
    self.view.backgroundColor = UIColor.blue
})

需要注意的是,我们需要给视图一个初始的红色,以使动画流畅,但如果你喜欢,你可以把它放在 Interface Builder 中。

相关推荐
老白讲技术6 小时前
2026年国内APP开发与软件定制服务商能力观察:从AI应用到行业系统开发
大数据·人工智能·ai·app·软件需求·app开发
私人珍藏库8 小时前
[Android] 一木百宝箱-万能百宝箱+抖音去水印等几百种功能
android·人工智能·app·软件·多功能
_瑞1 天前
深入理解灵动岛
前端·ios·app
私人珍藏库2 天前
[Android] BBLL 开源第三方B哩电视TV端
android·app·生活·工具·多功能
私人珍藏库3 天前
[Android] zip解压缩管理-全格式压缩包一键解压+打包
android·app·生活·工具·多功能
Fansi6 天前
iOS 实时活动(Live Activity)开发指南
app
duanze7 天前
从零开始Android商业项目Vibe coding完全指南(八)
app·vibecoding
Bigger12 天前
Tauri (26)——托盘图标总对不上系统主题?一行 Template Image 搞定
前端·rust·app
duanze16 天前
从零开始Android商业项目Vibe coding完全指南(七)
app·vibecoding
方白羽22 天前
一份 AGENTS.md,让 Android AI 代码规范率飙升
android·app·客户端