0

I'm trying to center a UIActivityIndicatorView in a UIButton programmatically using constraints but it's not working.. Note: It's centered if you rotate the device!

enter image description here

The code i'm using is

func animateButton(shouldLoad: Bool, with message: String) {
    
    
    self.isUserInteractionEnabled = !shouldLoad
    
    // Should start loading
    if shouldLoad {

        self.setTitle("", for: .normal)
        
        UIView.animate(withDuration: 0.2, animations: { 
            self.layer.cornerRadius = self.frame.height / 2
            self.frame = CGRect(x: self.frame.midX - self.frame.height / 2, y: self.frame.origin.y, width: self.frame.height, height: self.frame.height)
        }, completion: { (done) in
            if done {
                self.showLoading()
                UIView.animate(withDuration: 0.2, animations: {
                    self.spinner.alpha = 1
                    self.layoutIfNeeded()
                })
            }
        })
        
    // Should end loading
    } else {
        
        self.setTitle(message, for: .normal)
        
        for subview in self.subviews {
            if subview == spinner {
                subview.removeFromSuperview()
            }
        }
        
        UIView.animate(withDuration: 0.2, animations: { 
            self.layer.cornerRadius = 5
            self.frame = self.originalFrame!
        })
        
    }
    
}

func showLoading() {
    if (spinner == nil) {
        spinner = createSpinner()
    }
    
    self.addSubview(spinner)
    centerActivityIndicatorInButton()
    spinner.startAnimating()
}

func hideLoading() {
    spinner.stopAnimating()
}

private func createSpinner() -> UIActivityIndicatorView {
    let activityIndicator = UIActivityIndicatorView()
    activityIndicator.activityIndicatorViewStyle = .whiteLarge
    activityIndicator.color = UIColor.darkGray
    activityIndicator.alpha = 0
    activityIndicator.hidesWhenStopped = true
    
    return activityIndicator
}

private func centerActivityIndicatorInButton() {
    spinner.translatesAutoresizingMaskIntoConstraints = false
    
    let xCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerX, relatedBy: .equal, toItem: spinner, attribute: .centerX, multiplier: 1, constant: 0)
    self.addConstraint(xCenterConstraint)
    
    let yCenterConstraint = NSLayoutConstraint(item: self, attribute: .centerY, relatedBy: .equal, toItem: spinner, attribute: .centerY, multiplier: 1, constant: 0)
    self.addConstraint(yCenterConstraint)
}

It works in case of calculating the center manually using this code.. But in case of rotation it's not working and it's not 100% accurate as we need to add 1point to width & height

let buttonHeight = self.bounds.size.height
let buttonWidth = self.bounds.size.width
spinner.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2)

Thanks in advance for your time

5
  • Use the superview’s bounds, not its frame, when determining the placement of the subview/sublayer Commented Jul 13, 2019 at 21:59
  • Is this code in a UIButton subclass? Commented Jul 14, 2019 at 0:04
  • @paulw11 Yes.. I'm trying to subclass UIButton with these functionalities Commented Jul 15, 2019 at 1:21
  • And is the button itself placed using constraints or are you manipulating its frame? I see you are animating the frame in animateButton - Generally you shouldn't mix frame manipulation and autolayout. If you want to change the size of the button, add & remove or modify size constraints. Commented Jul 15, 2019 at 2:56
  • Yes.. It's originally placed using constraints.. But i need to manipulate it's size but changing the frame.. Thanks for bringing this general issue to me but i still need to make a general subclass which will be used anytime later.. and there's no other way except manipulating the button's frame! Commented Jul 16, 2019 at 9:50

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.