Элемент массива не может быть подключен к Objective-C
У меня есть этот код, который создает представление и применяет к нему градиент.
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
На самом деле я ожидал, что он рухнет там, потому что я не уверен, как создать массив CGColors в Swift. Удивительно, что Xcode упоминает Objective-C. На мой взгляд, я создавал CGColorRef в быстром...
Любые подсказки? Почему он упоминает Objective-C и как это решить?
Ответы
Ответ 1
Причина Objective-C упоминается в том, что UIKit и QuartzCore являются Objective-C фреймами. В частности, gradient.colors = arrayColors
вызывает метод Objective-C, который ожидает NSArray
.
Это похоже на ошибку, так как в документации Apple звучит так, что массив должен автомостеризоваться до NSArray
, пока элементы в массиве можно считать AnyObject
:
Когда вы переходите из массива Swift в объект NSArray, элементы в массиве Swift должен быть совместим AnyObject. Например, Swift массив типа Int [] содержит элементы структуры Int. Тип Int - это не экземпляр класса, а потому, что мосты типа Int Класс NSNumber, тип Int совместим с AnyObject. Поэтому вы может связать массив Swift типа Int [] с объектом NSArray. Если элемент в массиве Swift не совместим с AnyObject, ошибка времени выполнения возникает, когда вы соединяетесь с объектом NSArray.
Вы также можете создать объект NSArray непосредственно из литерала массива Swift, следуя тем же правилам моста, описанным выше. Когда ты явно введите константу или переменную в качестве объекта NSArray и назначьте это литерал массива, Swift создает объект NSArray вместо Swift.
В настоящее время работа должна состоять в том, чтобы объявить arrayColors
как NSArray
:
let arrayColors: NSArray = [cor1.CGColor, cor2.CGColor]
Или объявить его как принятие AnyObject
:
let arrayColors: Array <AnyObject> = [cor1.CGColor, cor2.CGColor]
Ответ 2
Эта ошибка времени выполнения также может быть запущена, если она пытается связать массив типа [MySwiftProtocol]
с Objective-C.
Решение состоит в том, чтобы пометить ваш протокол @objc
:
@objc protocol MySwiftProtocol {
// ...
}
Ответ 3
Я обнаружил, что могу исправить проблему, явно используя 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 в объявлениях типов для цветов, я получаю ошибку "элемент массива не может быть связан с ошибкой Objective-C".
Ответ 4
С помощью массивов Swift вы можете называть bridgeToObjectiveC()
на них, и они превратятся в NSArrays. То же самое относится к словарям Swift.
Ответ 5
Для тех, кто пытается заставить это работать в Swift, вы можете сделать следующее:
let arrayColors: NSArray = [UIColor.blackColor().CGColor as AnyObject, UIColor.clearColor().CGColor as AnyObject]
Я заметил, что в моем коде Objective-C я использовал типы CGColorRef для id. Не знаю, почему. Если у кого есть причина, почему это было бы здорово!