Подтвердить что ты не робот

IBDesignable View Время выдачи

Я работаю над приложением в течение нескольких месяцев, начиная с первой бета-версии XCode 6/iOS 8. Одна из моих любимых функций - живое рендеринг, сделанный с тегом @IBDesignable в Swift.

Я не смог получить ни одного живого рендеринга. Я полагал, что это, должно быть, потому, что это был бета-релиз, поэтому я решил дождаться выхода полной версии, чтобы повторить попытку. Он все еще провалился. Тогда я понял, что в моем коде могут быть артефакты из бета-релизов, поэтому я отказался от него и начал новый. Это все еще не работает. Конечно, ошибки теперь немного более описательны.

Вот мой код:

import UIKit

@IBDesignable class MyButton : UIButton {

    let UNPRESSED_COLOR = UIColor(red: 221.0/256.0, green: 249.0/256.0, blue: 14.0/256.0, alpha: 1.0)
    let PRESSED_COLOR = UIColor(red: 166.0/256.0, green: 187.0/156.0, blue: 11.0/256.0, alpha: 1.0)
    var buttonColorValue: UIColor

    let TEXT_COLOR = UIColor(red: 72.0/256.0, green: 160.0/256.0, blue: 5.0/256.0, alpha: 1.0)

    required init(coder: NSCoder) {
        self.buttonColorValue = UNPRESSED_COLOR
        super.init(coder: coder)
        // Initialization code
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Normal)
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Highlighted)
        self.setTitleColor(TEXT_COLOR, forState: UIControlState.Selected)
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        super.touchesBegan(touches, withEvent: event)
        buttonColorValue = PRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
        super.touchesEnded(touches, withEvent: event)
        buttonColorValue = UNPRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) {
        super.touchesCancelled(touches, withEvent: event)
        buttonColorValue = UNPRESSED_COLOR
        self.setNeedsDisplay()
    }

    override func drawRect(rect: CGRect) {
        buttonColorValue.setFill()
        let ctx = UIGraphicsGetCurrentContext()
        CGContextFillRect(ctx, rect)
        //UIBezierPath(roundedRect: rect, cornerRadius: 5.0).fill()
    }
}

Вот ошибки, которые я получаю, когда пытаюсь построить одну из этих кнопок в своем раскадровке:

IB Designables: Failed to update auto layout status: Interface Builder Cocoa Touch Tool crashed

IB Designables: Failed to render instance of MyButton: Rendering the view took longer than 200 ms. Your drawing code may suffer from slow performance.

Как вы можете видеть в моем коде, я изначально хотел, чтобы эта кнопка была закруглена. Я полагал, что это может быть причиной этой проблемы, хотя он удивил меня тем, что Apple разработает алгоритм скругленного прямоугольника, который неэффективен. Я переключился на просто настройку цвета и рисование прямоугольника как есть. Все еще были проблемы.

Я полагаю (надеюсь, так или иначе), что есть одна маленькая вещь, которую я делаю неправильно, потому что я googled, и нет никого другого, у которого, похоже, есть эта проблема. Похоже, это может быть какой-то бесконечный цикл?

Это не то, что мне нужно для продолжения, но получение живого рендеринга для работы сделает процесс намного быстрее и легче для меня, потому что я смогу увидеть свои интерфейсы и протестировать их без необходимости их запуска.

Заранее благодарим любого, у кого есть удаленная подсказка о том, как решить эту проблему.

4b9b3361

Ответ 1

По-видимому, мне нужно было переопределить init(frame: CGRect) вместе с init(code: NSCoder).

Сработало! Если кто-нибудь мог бы объяснить, почему это не работает, это было бы здорово. В противном случае, я в порядке.

Ответ 2

Хотя это может и не быть полезным ответом, я обнаружил, что после поиска решения для этого за полчаса простое закрытие и повторное открытие Xcode сделали трюк - если вы еще не пробовали это, a go!

Ответ 3

Убедитесь, что вы переопределили prepareForInterfaceBuilder, чтобы решить эту проблему.

@IBDesignable
class SomeView: UITableView {
 @IBInspectable var something: Int? { didSet { setup() } }

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setup()
}

override init(frame: CGRect, style: UITableViewStyle) {
    super.init(frame: frame, style: style)
    setup()
}

override func prepareForInterfaceBuilder() {
    super.prepareForInterfaceBuilder()
    setup()
}

func setup() {
    // do sth
}
}

Ответ 4

Имел ту же проблему, но взглянул на эту замечательную статью. Он решил мою проблему.

http://nshipster.com/ibinspectable-ibdesignable/

Короче

Чтобы получить эти параметры в xcode

введите описание изображения здесь

Сделайте свойство, подобное этому:

@IBInspectable var cornerRadius: CGFloat = 0 {
   didSet {
       layer.cornerRadius = cornerRadius
       layer.masksToBounds = cornerRadius > 0
   }
}

Ответ 5

Для меня эта ошибка была вызвана блокирующим вызовом базы данных sqlite (с использованием CoreData) в одном из моих свойств @IBInspectable.

Мой код первоначально запросил базу данных, а затем использовал dispatchAsync, чтобы установить значение метки на основе результатов запроса. Я изменил его так, чтобы запрос был также запущен в блоке dispatchAsync. Ошибка сразу же исчезла.

Если кто-то еще сталкивается с этой ошибкой, я предлагаю проверить код, который будет выполняться на этапе проектирования (конструкторы или вычисленные свойства, помеченные знаком @IBInspetable). Если есть какой-либо блокирующий код (сетевые операции, доступ к базе данных и т.д.), Это может вызвать ошибку таймаута. Надеюсь, это поможет.