Search code examples
uiimageviewswift3constraintscenter

Swift 3 | Adding constraints programmatically doesn't center my subview


I try to write an UIImageView extension which display an ActivityIndicator in the middle of my ImageView, I tried the following, note that my ImageViews have a constraint on height (100) and width (100) :

public extension UIImageView {
    public func downloadedFrom(url: URL) {

        let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
    activityIndicator.startAnimating()

        let leftSpaceConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.left, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.left, multiplier: 1, constant: 40)

        let topSpaceConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 40)

        let widthConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)

        let heightConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)

        self.addSubview(activityIndicator)

        self.addConstraints([leftSpaceConstraint, topSpaceConstraint, widthConstraint, heightConstraint])
    }
}

I also tried to set leadingSpaceConstraint / trailingSpaceConstraint / horizontalConstraint / verticalConstraint but my code has no effect, every constraints I set doesn't do change anything. My activityIndicator stay at the top left like this :

enter image description here

I don't understand why ? The method "downloadedFrom" is called in the viewDidLoad like this :

myImageView.downloadedFrom(url: imageUrl)

Where did I go wrong ? TY


Solution

  • You are placing your imageView on the top of parent UIView from the left side. It needs to be depending on coordinates of the middle of parent UIImageView for x-axis and y-axis. And also, set translatesAutoresizingMaskIntoConstraints to false. Look at the code below:

         public extension UIImageView {
                public func downloadedFrom(url: URL) {
    
                let activityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
                activityIndicator.startAnimating()
                activityIndicator.translatesAutoresizingMaskIntoConstraints = false
    
                let leftSpaceConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
    
                let topSpaceConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
    
                let widthConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
    
                let heightConstraint = NSLayoutConstraint(item: activityIndicator, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 20)
    
                self.addSubview(activityIndicator)
    
                self.addConstraints([leftSpaceConstraint, topSpaceConstraint, widthConstraint, heightConstraint])
                }
            }