vistas vista personalizada hoja definicion ios uiview core-graphics quartz-core

ios - hoja - volver a dibujar una vista personalizada al cambiar la orientación de un dispositivo



vistas de excel 2013 (7)

  1. 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 .
  2. 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 .