ios - create - IBDesignable View Rendering vence
ios ibdesignable (5)
Aparentemente necesitaba anular init(frame: CGRect)
junto con init(code: NSCoder)
.
¡Lo tengo funcionando! Si alguien pudiera explicar por qué esto no funcionó, sería genial. De lo contrario, estoy bien aquí.
He estado trabajando en una aplicación de forma intermitente durante algunos meses a partir de la primera versión beta de XCode 6 / iOS 8. Una de mis características favoritas agregadas es la renderización en vivo, que es posible con la etiqueta @IBDesignable
en Swift.
No he podido conseguir una sola cosa para renderizar en vivo. Pensé que debía haber sido porque era una versión beta, así que decidí esperar a que saliera el lanzamiento completo para volver a intentarlo. Todavía falló. Entonces me di cuenta de que podría haber artefactos de las versiones beta en mi código, así que lo deseché y comencé de nuevo. Todavía no funciona. Por supuesto, los errores son un poco más descriptivos ahora.
Aquí está mi código:
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()
}
}
Estos son los errores que recibo cuando intento construir con uno de estos botones en mi guión gráfico:
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.
Como puede ver en mi código, originalmente quería redondear este botón. Pensé que esta podría ser la razón de este problema, aunque me sorprendió que Apple diseñara un algoritmo de dibujo de rectángulo redondeado que fuera ineficiente. Cambié simplemente a establecer el color y dibujar el rectángulo como está. Todavía tenía problemas.
Me imagino (espero, de todos modos) que hay una pequeña cosa que estoy haciendo mal, porque he buscado en Google y no hay nadie más que parezca tener este problema. Parece que podría ser una especie de bucle infinito?
No es algo que sea necesario para que continúe, pero hacer funcionar el renderizado en vivo hará que el desarrollo sea mucho más rápido y más fácil para mí, porque podré ver mis interfaces y probarlas sin tener que ejecutarlas.
Gracias de antemano a cualquiera que tenga una pista remota sobre cómo resolver esto.
Asegúrese de anular prepareForInterfaceBuilder para resolver esto.
@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
}
}
Aunque puede que esta no sea realmente una respuesta útil, descubrí que después de buscar una solución para esto durante media hora, un simple cierre y una nueva apertura de Xcode hicieron el truco, ¡si no lo has probado todavía, pruébalo!
Para mí, este error se debió a una llamada de bloqueo a una base de datos sqlite (usando CoreData) en una de mis propiedades @IBInspectable.
Mi código originalmente consultó la base de datos y luego usó dispatchAsync
para establecer el valor de una etiqueta basada en los resultados de la consulta. Lo cambié para que la consulta también se iniciara en el bloque dispatchAsync
. El error desapareció de inmediato.
Si alguien más tiene problemas con este error, sugiero que revise cualquier código que se ejecutaría durante la fase de diseño (constructores o propiedades computadas marcadas con @IBInspetable). Si hay algún código de bloqueo (operaciones de red, acceso a la base de datos, etc.), podría estar causando el error de tiempo de espera. Espero que esto ayude.
Tenía el mismo problema pero a un vistazo a este gran artículo. Se solucionó mi problema.
http://nshipster.com/ibinspectable-ibdesignable/
En breve
Para obtener estas opciones en xcode
Hacer una propiedad como esta:
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}