How to keep round imageView round using auto layout?

How to convert a rectangular image into a circular image that can preserve shape in an automatic layout without setting width and height restrictions? Thus, allowing the imageView to determine its size and size larger and smaller in relation to the objects surrounding it with restrictions on the leading, final, upper and lower.

The other day I asked a similar question, but I think that this can be delivered in a more concise way. Thank!

EDIT

Ok, I started to make it as easy as possible. I have a view called "Cell" and a UIImageView called "dog" inside the cell, and it is. I no longer have the “ability to simultaneously satisfy constraints” in the console, just two simple views using the automatic layout. I'm still trying to use this code to round a UIImageView:

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

Here is the cell limit setting:

screenshot 1

Here is the profile pic limit setting:

screenshot 2

Here is the result without code, without rounding, but beautiful and square:

screenshot 3

Here is the result with code rounding:

screenshot 4

This makes no sense to me, because without a rounding code, the image is square, and with a code - a diamond. If it is square, is this a circle without problems?

EDIT 2

This is what happens when I remove the lower limit and add a factor of .373 for equal height for viewing.

screenshot 5

+33
ios xcode swift
02 Sep '15 at 20:54
source share
10 answers

Unfortunately, you cannot do this using cornerRadius and autostart - CGLayer not affected by automatic shutdown, so any change in the size of the view will not change the radius that was set once, because you noticed the circle will lose its shape.

You can create a custom subclass of UIImageView and override layoutSubviews to set cornerRadius every time the borders of the image change.

EDIT

An example might look something like this:

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

And, obviously, you will need to limit the width of the Foobar instance to equal height (to maintain the circle). You probably also want to set the Foobar instance of contentMode to UIViewContentMode.ScaleAspectFill so that it knows how to draw the image (this means that the image can be cropped).

+58
03 Sep '15 at 0:03
source share

Setting the radius in viewWillLayoutSubviews will solve the problem

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() profileImageView.layer.cornerRadius = profileImageView.frame.height / 2.0 } 
+28
Apr 17 '16 at 16:33
source share

create a new interface in the .h file, for example

 @interface CornerClip : UIImageView @end 

and implementation in .m file, for example

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

now just give the class "CornerClip" for your image. 100% works ... Enjoy

+10
May 16 '17 at 10:21
source share

It seems that when you add one view as a subtitle of another, the mesh view will not necessarily have the same height as its supervisor. That's the problem. The solution is not to add the image as a subtitle, but to have it on top of the background image. In the image below, I use UILabel as the background.

screenshot

Also in your case, when you install cornerRadius, use this: let radius: CGFloat = self.bounds.size.height / 2.0 .

+4
03 Sep '15 at 23:39
source share

Thanks to my hacker solution, you get a smooth animation of the radius radius along with resizing the frame.

Let's say you have ViewSubclass: UIView. It should contain the following code:

 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 } } 

Then you will need to do this:

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

This is not beautiful and may not work for complex multi-animations, but answers the question.

+1
Sep 28 '16 at 15:09
source share

I have the same problem and now I get what happened here, hope some ideas help you: there is something else between the tugs:

  • your storyboard profile image
  • your ImageView profile in viewDidLoad

the size of the linked and frame is different with viewDidLoad and in the storyboard, only because the size of the view changes for different sizes of the device. You can try print(profileImageView.bounds.size) in viewDidLoad and viewDidAppear , you will find that the size in viewDidLoad that you set cornerRadius is not a real "working" size.

tips for you: you can use subClass ImageView to avoid this, or not use it in the storyboard,

0
Dec 13 '15 at 14:20
source share

If you subclass UIImageView. Then just add this magic code to it.

Written In: Swift 3

 override func layoutSubviews() { super.layoutSubviews() if self.isCircular! { self.layer.cornerRadius = self.bounds.size.width * 0.50 } } 
0
Jan 31 '18 at 11:53
source share

Swift 4+ pure solution based on the answer of omarabek

 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 } } 

Using an Example in a UIViewController

1. Simply rounded UIImageView

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

2.Extended UIImageView with border width and color

 override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() imageView.setRounded(borderWidth: 1.0, borderColor: UIColor.red) } 
0
Aug 02 '18 at 10:22
source share

Add a 1: 1 aspect ratio constraint to the imageView so that it remains round despite any changes in height or width.

-one
Sep 02 '15 at 21:17
source share

Easy to do by creating an IBOutlet for a constraint that needs to be changed at runtime. Below is the code:

  • Create an IBOutlet for the constraint that needs to be changed at runtime.

     @IBOutlet var widthConstraint: NSLayoutConstraint! 
  • Add the code below to viewDidLoad() :

     self.widthConstraint.constant = imageWidthConstraintConstant() 

Below the function determines for the types of devices respectively change the width limit.

 func imageWidthConstraintConstant() -> CGFloat { switch(self.screenWidth()) { case 375: return 100 case 414: return 120 case 320: return 77 default: return 77 } } 
-5
Oct 17 '16 at 10:16
source share



All Articles