How to keep a round imageView round using auto layout?

后端 未结 15 1375
悲&欢浪女
悲&欢浪女 2020-12-01 06:22

How do I turn a rectangular image view into a circular image view that can hold shape in auto layout without setting width and height restraints? Thereby allowing the imageV

相关标签:
15条回答
  • 2020-12-01 06:41

    I am quite new to iOS native development, but I had the same problem and found a solution.

    So the green background has this constraints:

    backgroundView.translatesAutoresizingMaskIntoConstraints = false
    backgroundView.topAnchor.constraint(equalTo: superview!.safeAreaLayoutGuide.topAnchor).isActive = true
    backgroundView.leftAnchor.constraint(equalTo: superview!.leftAnchor).isActive = true
    backgroundView.widthAnchor.constraint(equalTo: superview!.widthAnchor).isActive = true
    backgroundView.heightAnchor.constraint(equalTo: superview!.heightAnchor, multiplier: 0.2).isActive = true
    

    The image constraints:

    avatar.translatesAutoresizingMaskIntoConstraints = false
    avatar.heightAnchor.constraint(equalTo: backgroundView.heightAnchor, multiplier: 0.8).isActive = true
    avatar.widthAnchor.constraint(equalTo: backgroundView.heightAnchor, multiplier: 0.8).isActive = true
    avatar.centerYAnchor.constraint(equalTo: backgroundView.centerYAnchor, constant: 0).isActive = true
    avatar.leadingAnchor.constraint(equalTo: backgroundView.leadingAnchor, constant: 20).isActive = true
    

    on viewWillLayoutSubviews() method I set the corner radius to

    avatar.layer.cornerRadius = (self.frame.height * 0.2 * 0.8) / 2
    

    Basically, I am simply calculating the height of the image and then divide it by 2. 0.2 is the backgroungView height constraint multiplier and 0.8 the image width/height constraint multiplier.

    0 讨论(0)
  • 2020-12-01 06:41

    Solution: Crop the image

    [imageView setImage:[[imageView image] imageWithRoundedCorners:imageView.image.size.width/2]];
    imageView.contentMode = UIViewContentModeScaleAspectFill;
    

    I was looking for the same solution for profile pictures. After some hit and try and going through available functions, I came across something which works and is a nice way to ensure its safe. You can use the following function to crop out a round image from the original image and then you need not worry about the corner radius.

    Post this even if your view size changes the image remains round and looks good.

    0 讨论(0)
  • 2020-12-01 06:43

    First of all, I should mention that u can get a circle shape for your UIView/UIImageView only if the width and height will be equal. It's important to understand. In all other cases (when width != height), you won't get a circle shape because the initial shape of your UI instance was a rectangle.

    OK, with this so UIKit SDK provides for developers a mechanism to manipulate the UIview's layer instance to change somehow any of layer's parameters, including setting up a mask to replace the initial shape of UIView element with the custom one. Those instruments are IBDesignable/IBInspectable. The goal is to preview our custom views directly through Interface Builder.

    So using those keywords we can write our custom class, which will deal only with the single condition whether we need to round corners for our UI element or not.

    For example, let's create the class extended from the UIImageView.

    @IBDesignable
    class UIRoundedImageView: UIImageView {
    
        @IBInspectable var isRoundedCorners: Bool = false {
            didSet { setNeedsLayout() }
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
    
            if isRoundedCorners {
                let shapeLayer = CAShapeLayer()
                shapeLayer.path = UIBezierPath(ovalIn:
                    CGRect(x: bounds.origin.x, y: bounds.origin.y, width: bounds.width, height: bounds.height
                )).cgPath
                layer.mask = shapeLayer
            }
            else {
                layer.mask = nil
            }
    
        }
    
    }
    

    After setting the class name for your UIImageView element (where the dog picture is), in your storyboard, you will get a new option, appeared in the Attributes Inspector menu (details at the screenshot).

    The final result should be like this one.

    0 讨论(0)
  • 2020-12-01 06:44

    write this code

    override viewDidLayoutSubViews() {
    profileImageView.layer.cornerRadius = profileImageView.frame.size.width / 2
    profileImageView.clipsToBounds = true
    
    }
    

    in this case it will called after calculating the autolayout calculations in the first code you called the cornerradius code before calculating the actual size of the view cuz it's dynamically calculated using aspect ratio , the actual corner radius is calculated before equaling the width and the height of the view

    0 讨论(0)
  • 2020-12-01 06:44

    I added custom IBInspectable cornerRadiusPercent, so you can do it without any code.

    class RoundButton: UIButton {
    
        override var bounds: CGRect {
            didSet {
                updateCornerRadius()
            }
        }
    
    
        //private var cornerRadiusWatcher : CornerRadiusPercent?
        @IBInspectable var cornerRadiusPercent: CGFloat = 0 {
    
            didSet {
                updateCornerRadius()
            }
        }
    
        func updateCornerRadius()
        {
            layer.cornerRadius = bounds.height * cornerRadiusPercent
        }
    
    }
    
    0 讨论(0)
  • 2020-12-01 06:45

    Swift 4+ clean solution based on omaralbeik's answer

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

    Sample usage in UIViewController

    1.Simply rounded UIImageView

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

    2.Rounded UIImageView with border width and color

    override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            imageView.setRounded(borderWidth: 1.0, borderColor: UIColor.red)
        }
    
    0 讨论(0)
提交回复
热议问题