Catch-22 с созданием распознавателя жестов панорамирования как константы?

У меня есть собственный подкласс UIView. У него есть распознаватель жестов панорамирования, который я установил как обязательную константу:

let dragger: UIPanGestureRecognizer

Это константа, потому что она создается один раз при инициализации представления и сохраняется в течение всего времени существования представления.

В назначенном инициализаторе представления init(coder) я хочу создать распознаватель жестов панорамирования и подключить его. Однако в Xcode 6.3 мне кажется, что я не могу этого сделать, если распознаватель жестов является константой. (Это кажется проблемой только в бета-версии Xcode 6.3. Код позволяет мне установить инициализатор жестов панорамирования после вызова super.init(coder))

Поскольку переменная является обязательной константой, ее необходимо настроить, прежде чем я вызову суперкласс init(coder). Однако единственный инициализатор для распознавателя жестов панорамирования принимает в качестве параметра себя. Я не доступен, пока я не позвоню super.init(coder).

Итак, я не могу создать распознаватель жестов с вызовом UIPanGestureRecognizer(target:action:) перед вызовом super.init(coder), потому что мне нужно передать себя этому инициализатору жестов панорамирования,

... и я не могу вызвать UIPanGestureRecognizer(target:action:) ПОСЛЕ вызова super.init(coder), потому что я должен установить значения для всех необходимых констант / переменных перед вызовом инициализатора суперкласса.

Единственное решение, которое я могу придумать, - сделать мой распознаватель жестов необязательной переменной var, чего я бы предпочел не делать. Он всегда будет иметь значение после завершения инициализатора, и необходимость разворачивать необязательный элемент каждый раз, когда я его использую, раздражает.

Я что-то упустил?


person Duncan C    schedule 06.04.2015    source источник
comment
Я не тестировал до конца, но компилятор при этом не выдает ошибку: let dragger = UIPanGestureRecognizer ()   -  person Thomas    schedule 06.04.2015
comment
И что потом? Добавить цель / действие в распознаватель жестов после вызова super.init(coder)? Я предполагаю, что это сработает, но в документации для распознавателей жестов указано, что UIPanGestureRecognizer(target:action:) является назначенным инициализатором, и вы должны вызывать назначенный инициализатор.   -  person Duncan C    schedule 06.04.2015
comment
Что-нибудь мешает вам сделать его лениво вычисляемым свойством?   -  person Nikita Kukushkin    schedule 06.04.2015
comment
Я мог бы сделать его ленивым, но моей целью было сделать его обязательной константой. lazy работает только со свойствами var.   -  person Duncan C    schedule 06.04.2015
comment
@Thomas, ваше решение использования простого инициализатора UIPanGestureRecognizer() с последующим добавлением цели / действия после вызова инициализатора суперкласса - единственное, что я нашел, что позволяет мне сохранить его как требуемую константу (let). Разместите свое предложение в качестве ответа, и я его приму.   -  person Duncan C    schedule 06.04.2015


Ответы (2)


Если решение aahrens не работает (возможно, из-за ошибки), вот что я бы сделал, даже если, как вы указали, в документации говорится, что это не указанный способ:

В вашем init:

dragger = UIPanGestureRecognizer()
super.init(coder)
dragger.target = self
dragger.action = <actionHandler>
person Thomas    schedule 06.04.2015
comment
Это более или менее то, чем я закончил. (Я использовал метод addTarget(_, action:) - person Duncan C; 06.04.2015

Что бы вы могли сделать, это неявно развернуть его. Подобно тому, как обозначаются IBOutlets, поскольку в вашем случае вы знаете, что у вас будет настроен действительный жест. Поэтому я бы объявил это как

class ViewController: UIViewController {
    let dragger: UIPanGestureRecognizer!
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        dragger = UIPanGestureRecognizer(target: self, action: "mySelector:")
    }
}
person aahrens    schedule 06.04.2015
comment
Это по-прежнему не решает проблему 22, заключающуюся в необходимости назначать его перед вызовом инициализатора суперкласса. - person Duncan C; 06.04.2015
comment
Интересно, это ошибка в Xcode 6.3? Код в моем ответе работал у меня в Xcode 6.2 - person aahrens; 06.04.2015
comment
В документации Apple говорится, что они сделали спецификацию Swift более строгой в версии 1.2. Это может быть примером, а не ошибкой. - person Duncan C; 09.04.2015