ios - hoja - volver a dibujar una vista personalizada al cambiar la orientación de un dispositivo
vistas de excel 2013 (7)
- Si dibujo mi gráfico dentro de
- (void)drawRect:(CGRect)rect
es suficiente para configurar [_chartView setContentMode:UIViewContentModeRedraw]
y este método se activará cuando el dispositivo cambie su orientación y es posible calcular el nuevo punto central de mi gráfico . - Si creo una vista como una subvista utilizando
- (id)initWithFrame:(CGRect)frame
y luego lo agrego en el controlador de vista como[self.view addSubview:chartView];
. ¿Cómo en este caso puedo manejar la rotación para volver a dibujar mi gráfico?
Desafortunadamente, algunas respuestas sugieren anular los métodos del controlador, pero tengo algunas UITableViewCells
personalizadas con una sombra alrededor y al girar el dispositivo estira las celdas pero no vuelve a dibujar la sombra. Así que no quiero poner mi código dentro de un controlador para (re) dibujar una subvista. La solución para mí es escuchar una notificación de UIDeviceOrientationDidChange
dentro de mi UITableViewCell
personalizado y luego llamar a setNeedsDisplay()
como se sugiere.
Ejemplo de código Swift 4.0 en uno de mis UITableViewCells personalizados
override func awakeFromNib() {
super.awakeFromNib()
NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChangeNotification), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
@objc func deviceOrientationDidChangeNotification(_ notification: Any) {
Logger.info("Orientation changed: /(notification)")
setNeedsLayout()
}
BTW: Logger
es una typealias
de SwiftyBeaver
. Gracias a @Aderis apuntándome en la dirección correcta.
El código que agregará a su controlador de vista:
- (void)updateViewConstraints
{
[super updateViewConstraints];
[_chartView setNeedsDisplay];
}
Gracias Keenle, por la solución ObjC anterior. Estuve jugando con la creación de restricciones programadas toda la mañana, matando mi cerebro, sin entender por qué no volverían a compilar / realinear la vista. Supongo que debido a que había creado el UIView mediante programación utilizando CGRect ... esto tenía prioridad.
Sin embargo, aquí estaba mi solución en veloz:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
myUIView.center = CGPoint(x: (UIScreen.mainScreen().bounds.width / 2), y: (UIScreen.mainScreen().bounds.height / 2))
}
¡Tan aliviado! :)
Intenté "setNeedsDisplay" en una docena de formas y no funcionó para ajustar la sombra de una vista que estaba animando a una nueva posición.
Aunque resolví mi problema con esto. Si su sombra no parece querer cooperar / actualizar, podría intentar simplemente establecer la sombra en cero, y luego volver a configurarla:
UIView.animateKeyframes(withDuration: 0.2 /*Total*/, delay: 0.0, options: UIViewKeyframeAnimationOptions(), animations: {
UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 10/10, animations:{
// Other things to animate
//Set shadow to nil
self.viewWithShadow.layer.shadowPath = nil
})
}, completion: { finished in
if (!finished) { return }
// When the view is moved, set the shadow again
self.viewWithShadow.layer.shadowPath = UIBezierPath(rect: self.descTextView.bounds).cgPath
})
Si aún no tienes una sombra y necesitas ese código, esto es lo siguiente:
func addShadowTo (view: UIView) {
view.layer.masksToBounds = false
view.layer.shadowColor = UIColor.gray.cgColor
view.layer.shadowOffset = CGSize( width: 1.0, height: 1.0)
view.layer.shadowOpacity = 0.5
view.layer.shadowRadius = 6.0
view.layer.shadowPath = UIBezierPath(rect: view.bounds).cgPath
view.layer.shouldRasterize = true
}
Para hacer que su gráfico se represente correctamente cuando cambie la orientación del dispositivo, necesita actualizar el diseño del gráfico, aquí está el código que debe agregar a su controlador de vista:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
_chartView.frame = self.view.bounds;
[_chartView strokeChart];
}
Vaya here para aprender cómo recibir notificaciones sobre cuándo cambia la orientación del dispositivo. Cuando la orientación cambie, solo llame a [chartView setNeedsDisplay];
para hacer drawRect:
recibe una llamada para que puedas actualizar tu vista. ¡Espero que esto ayude!
Utilizando .Redraw
La invocación programática de myView.contentMode = .Redraw
cuando se crea la vista personalizada debería ser suficiente. Es una sola bandera en IB y, como tal, las 0 líneas de código preferidas. Consulte Desbordamiento de pila Cómo activar drawRect en la subclase UIView .
Usando setNeedsDisplay()
Si debe desencadenar un redibujado, hágalo en setNeedsDisplay
, que a su vez invoca drawRect
.
No es necesario escuchar las notificaciones ni refactorizar el código.
Rápido
override func layoutSubviews() {
super.layoutSubviews()
self.setNeedsDisplay()
}
C objetivo
- (void)layoutSubviews {
[super layoutSubviews];
[self setNeedsDisplay];
}
Nota:
layoutSubviews
es un método UIView
, no un método UIViewController
.