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

bounds, not itsframe, when determining the placement of the subview/sublayerUIButtonsubclass?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.