我有这个代码创建一个视图并对其应用渐变。
import UIKit
import QuartzCore
let rect : CGRect = CGRectMake(0,0,320,100)
var vista : UIView = UIView(frame: rect)
let gradient : CAGradientLayer = CAGradientLayer()
gradient.frame = vista.bounds
let cor1 = UIColor.blackColor()
let cor2 = UIColor.whiteColor()
let arrayColors = [cor1.CGColor, cor2.CGColor]
gradient.colors = arrayColors
view.layer.insertSublayer(gradient, atIndex:0)
Xcode没有给我编译错误,但代码崩溃了
let arrayColors = [cor1.CGColor, cor2.CGColor]
消息数组元素无法桥接到Objective-C
事实上我期待它在那里崩溃,因为我不知道如何在Swift上创建一个CGColors数组。令人惊讶的是Xcode提到了Objective-C。在我看来,我正在迅速创建一个CGColorRef ......
任何线索?为什么提到Objective-C以及如何解决这个问题?
答案 0 :(得分:29)
提到Objective-C的原因是因为UIKit和QuartzCore是Objective-C框架。特别是,gradient.colors = arrayColors
正在调用期望NSArray
的Objective-C方法。
这似乎是一个错误,因为Apple的文档听起来像是数组应该自动桥接到NSArray
,只要数组中的项目可以被视为AnyObject
:
当您从Swift数组桥接到NSArray对象时,元素 在Swift数组中必须与AnyObject兼容。例如,一个Swift Int []类型的数组包含Int结构元素。 Int类型是 不是类的实例,而是因为Int类型桥接到 NSNumber类,Int类型与AnyObject兼容。所以,你 可以将Int []类型的Swift数组桥接到NSArray对象。如果 Swift数组中的元素与AnyObject不兼容,这是一个运行时错误 桥接到NSArray对象时发生。
您也可以按照上面列出的相同桥接规则直接从Swift数组文字创建NSArray对象。当你 显式地将常量或变量键入为NSArray对象并赋值 它是一个数组文字,Swift创建一个NSArray对象而不是一个 Swift数组。
目前,解决方法是将arrayColors
声明为NSArray
:
let arrayColors: NSArray = [cor1.CGColor, cor2.CGColor]
或者宣布它为AnyObject
:
let arrayColors: Array <AnyObject> = [cor1.CGColor, cor2.CGColor]
答案 1 :(得分:19)
如果尝试将类型[MySwiftProtocol]
的数组桥接到Objective-C,也可以触发此运行时错误。
解决方案是使用@objc
标记您的协议:
@objc protocol MySwiftProtocol {
// ...
}
答案 2 :(得分:4)
我发现我可以通过明确使用CGColorRef而不是CGColor来解决问题,例如:
var bottomColour:CGColorRef = UIColor.redColor().CGColor
var topColour:CGColorRef = UIColor(red: 255.0/255.0, green: 123.0/255.0, blue: 37.0/255.0, alpha: 1.0).CGColor
gradientLayer.colors = [bottomColour, topColour]
...工作正常,没有任何NSArray或AnyObject投射。如果我在颜色的类型声明中取出显式的CGColorRef,我得到的&#34;数组元素不能桥接到Objective-C&#34;错误。
答案 3 :(得分:3)
使用Swift数组,您可以在它们上面调用bridgeToObjectiveC()
,然后它们就会变成NSArrays。 Swift词典也是如此。
答案 4 :(得分:2)
对于任何试图让它在Swift中工作的人,您可以执行以下操作:
let arrayColors: NSArray = [UIColor.blackColor().CGColor as AnyObject, UIColor.clearColor().CGColor as AnyObject]
我注意到在我的Objective-C代码中我将CGColorRef类型转换为id。不知道为什么。如果有人有理由说这会很棒!