¿Cómo mantener una ronda round imageView usando el diseño automático?

¿Cómo convierto una vista de imagen rectangular en una vista de imagen circular que puede mantener la forma en el diseño automático sin establecer restricciones de ancho y alto? De este modo, permite que imageView defina su tamaño y su tamaño sea más grande y más pequeño en relación con los objetos que lo rodean con restricciones iniciales, finales, superiores e inferiores.

Hice una pregunta similar el otro día, pero creo que esto podría plantearse de una manera más concisa. ¡Muchas gracias!

EDITAR

Ok, comencé a hacer esto lo más simple posible. Tengo una vista llamada “Célula” y un UIImageView llamado “perro” dentro de la celda, y eso es todo. Ya no tengo “incapaz de satisfacer restricciones simultáneamente” en la consola, solo dos vistas simples usando el diseño automático. Todavía estoy tratando de usar este código para redondear el UIImageView:

profileImageView.layer.cornerRadius = profileImageView.frame.size.width / 2 profileImageView.clipsToBounds = true 

Aquí está la configuración de restricción de celda:

captura de pantalla 1

Aquí está la configuración de restricción de pic de perfil:

captura de pantalla 2

Aquí está el resultado sin el código, sin redondeo, pero bonito y cuadrado:

captura de pantalla 3

Aquí está el resultado con el código para redondear:

captura de pantalla 4

Esto no tiene sentido para mí, porque sin el código de redondeo la imagen es cuadrada, y con el código tiene forma de diamante. Si es cuadrado, ¿no debería ser un círculo sin problemas?

EDIT 2

Esto es lo que sucede cuando elimino la restricción inferior y agrego un multiplicador de .637 para la misma altura a la supervista.

captura de pantalla 5

Desafortunadamente no puedes hacer esto usando cornerRadius y autolayout – CGLayer no se ve afectado por el autodiseño, por lo que cualquier cambio en el tamaño de la vista no cambiará el radio que se ha establecido una vez, lo que hace que el círculo pierda su forma .

Puede crear una subclase personalizada de UIImageView y anular las layoutSubviews de layoutSubviews para establecer el cornerRadius cada vez que cornerRadius los límites de la vista de imagen.

EDITAR

Un ejemplo podría verse más o menos así:

 class Foo: UIImageView { override func layoutSubviews() { super.layoutSubviews() let radius: CGFloat = self.bounds.size.width / 2.0 self.layer.cornerRadius = radius } } 

Y, obviamente, tendrías que restringir el ancho de la instancia de Foobar para que sea igual a la altura (para mantener un círculo). Probablemente también desee establecer el modo de contentMode la instancia de Foobar en UIViewContentMode.ScaleAspectFill para que sepa cómo dibujar la imagen (esto significa que es probable que la imagen se recorta).

Establecer el radio en viewWillLayoutSubviews resolverá el problema

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() profileImageView.layer.cornerRadius = profileImageView.frame.height / 2.0 } 

crea una nueva interfaz en tu archivo .h como

 @interface CornerClip : UIImageView @end 

y la implementación en el archivo .m como

 @implementation cornerClip -(void)layoutSubviews { [super layoutSubviews]; CGFloat radius = self.bounds.size.width / 2.0; self.layer.cornerRadius = radius; } @end 

ahora solo da clase como “CornerClip” a tu imagen. 100% trabajando … Disfruta

Al agregar una vista como subvista de otra, parece que la vista en red no necesariamente tendrá la misma altura que su supervista. Eso es lo que parece el problema. La solución es no agregar su imageView como una subvista, pero tenerla en la parte superior de su backgroundView. En la imagen de abajo estoy usando un UILabel como mi backgroundView.

captura de pantalla

También en tu caso, cuando estás configurando la esquina, usa este let radius: CGFloat = self.bounds.size.height / 2.0 .

Con mi solución hacky obtendrá animación de radio de esquina suave junto con el cambio de tamaño de fotogtwig.

Digamos que tienes ViewSubclass: UIView. Debe contener el siguiente código:

 class ViewSubclass: UIView { var animationDuration : TimeInterval? let imageView = UIImageView() //some imageView setup code override func layoutSubviews() { super.layoutSubviews() if let duration = animationDuration { let anim = CABasicAnimation(keyPath: "cornerRadius") anim.fromValue = self.imageView.cornerRadius let radius = self.imageView.frame.size.width / 2 anim.toValue = radius anim.duration = duration self.imageView.layer.cornerRadius = radius self.imageView.layer.add(anim, forKey: "cornerRadius") } else { imageView.cornerRadius = imageView.frame.size.width / 2 } animationDuration = nil } } 

Entonces, tendrás que hacer esto:

 let duration = 0.4 //For example instanceOfViewSubclass.animationDuration = duration UIView.animate(withDuration: duration, animations: { //Your animation instanceOfViewSubclass.layoutIfNeeded() }) 

No es hermoso, y podría no funcionar para multi-animaciones complejas, pero responde la pregunta.

Tengo el mismo problema, y ​​ahora entiendo lo que sucedió aquí, espero que algunas ideas te ayuden: hay algo diferente entre los remolques:

  1. su perfilImageView en guión gráfico
  2. su perfilImageViewView en viewDidLoad

el tamaño de bound y frame es diferente cuando viewDidLoad y en el guión gráfico, simplemente porque la vista viewDidLoad tamaño para diferentes tamaños de dispositivo. Puedes probarlo print(profileImageView.bounds.size) en viewDidLoad y viewDidAppear encontrarás el tamaño en viewDidLoad que estableces. cornerRadius no es el tamaño real de “ejecución”.

un consejo para usted: puede usar una subclase de ImageView para evitarlo, o no lo use en el guión gráfico,

Si ha subclasificado el UIImageView. Entonces solo agrega esta pieza de código mágico.

Escrito en: Swift 3

 override func layoutSubviews() { super.layoutSubviews() if self.isCircular! { self.layer.cornerRadius = self.bounds.size.width * 0.50 } } 

Swift 4+ solución limpia basada en la respuesta de omaralbeik

 import UIKit extension UIImageView { func setRounded(borderWidth: CGFloat = 0.0, borderColor: UIColor = UIColor.clear) { layer.cornerRadius = frame.width / 2 layer.masksToBounds = true layer.borderWidth = borderWidth layer.borderColor = borderColor.cgColor } } 

Uso de muestra en UIViewController

1. UIImageView simplemente redondeado

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() imageView.setRounded() } 

2.Rounded UIImageView con ancho y color de borde

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() imageView.setRounded(borderWidth: 1.0, borderColor: UIColor.red) } 

Agregue una restricción de relación de aspecto 1: 1 a la imageView de imageView para que permanezca circular, a pesar de los cambios de altura o ancho.

Se puede hacer fácilmente creando una IBOutlet para la restricción que debe modificarse en el tiempo de ejecución. A continuación está el código:

  1. Cree un IBOutlet para la restricción que debe modificarse en tiempo de ejecución.

     @IBOutlet var widthConstraint: NSLayoutConstraint! 
  2. Agregue el código siguiente en viewDidLoad() :

     self.widthConstraint.constant = imageWidthConstraintConstant() 

Debajo de la función determina para los tipos de dispositivo cambiar la restricción de ancho en consecuencia.

 func imageWidthConstraintConstant() -> CGFloat { switch(self.screenWidth()) { case 375: return 100 case 414: return 120 case 320: return 77 default: return 77 } }