使用 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 中。

相关推荐
SuperherRo6 天前
基础入门-APP应用&微信小程序&原生态开发&H5+Vue技术&WEB封装打包&反编译抓包点
小程序·app·反编译·原生态·web封装·h5+vue
kim56597 天前
数独游戏app制作拆解(之三)——数字候选区实现
游戏·app·数独·android stufio
什么都什么1 个月前
YonBuilder移动开发鸿蒙版本编译教程
javascript·app·移动开发·harmonyos·yonbuilder·纯血鸿蒙·apicloud
applebomb1 个月前
【uni-app多端】修复stmopjs下plus-websocket无心跳的问题
websocket·uni-app·app·心跳·stomp·plus-websocket
图王大胜1 个月前
Android Framework AMS(17)APP 异常Crash处理流程解读
android·app·异常处理·ams·crash·binderdied·讣告
veteranJayBrother2 个月前
uniapp实现书架
微信小程序·uni-app·app·书架
胡西风_foxww2 个月前
高考相关 APP 案例分享
算法·app·志愿·高考
YesPMP252 个月前
短剧小程序,打造专属短剧观看平台
小程序·app·html5·平台·短剧·影视
飞飞_圆代码2 个月前
iOS安卓渠道归因分析在App推广矩阵中的场景应用
android·ios·app
Amd7942 个月前
Nuxt.js 应用中的 app:resolve 事件钩子详解
中间件·app·生命周期·nuxt·插件·resolve·钩子