MickCrozier MickCrozier -4 years ago 186
Swift Question

UIView programatic constraints not working

As a simple starting point. I'm trying to create a custom button that has an activity indicator in the middle.
After a tap - it will indicate that it's thinking

I'm pretty much stuck at step 1 - adding the indicator to be centred in the surrounding view.
No matter want constraints I try it always appears in the top left corner.

What am I missing?

Button Fail

Here's my playground code.

//: Playground - noun: a place where people can play

import PlaygroundSupport
import UIKit

class ConnectButton : UIView {

fileprivate let activityIndicator: UIActivityIndicatorView = {
let activityIndicator = UIActivityIndicatorView()

activityIndicator.color = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
activityIndicator.hidesWhenStopped = true;
activityIndicator.stopAnimating();
activityIndicator.activityIndicatorViewStyle = .white;
return activityIndicator;
}()


private func initView() {
translatesAutoresizingMaskIntoConstraints = true;
addSubview(activityIndicator);

NSLayoutConstraint.activate([
activityIndicator.centerYAnchor.constraint(equalTo: self.centerYAnchor),
activityIndicator.leftAnchor.constraint(equalTo: self.centerXAnchor)
])
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
self.initView();
}

override init(frame: CGRect) {
super.init(frame: frame);
self.initView();
}

public func startAnimating() {
activityIndicator.startAnimating();
}

public func stopAnimating() {
activityIndicator.stopAnimating();
}
}

let dimensions = (width:200, height: 50);
let connectButton = ConnectButton(
frame: CGRect(
x: dimensions.width / 2,
y: dimensions.height / 2,
width: dimensions.width,
height: dimensions.height
)
)

connectButton.startAnimating();
connectButton.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1);

PlaygroundPage.current.liveView = connectButton

Answer Source

You want to set translatesAutoresizingMaskIntoConstraints to false onto UIActivityIndicatorView. Otherwise, UIKit will create constraints based on the resizing masks set on the, which will conflict with the ones you already added.

fileprivate let activityIndicator: UIActivityIndicatorView = {
    let activityIndicator = UIActivityIndicatorView()

    activityIndicator.color = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
    activityIndicator.hidesWhenStopped = true
    activityIndicator.stopAnimating()
    activityIndicator.activityIndicatorViewStyle = .white
    activityIndicator. translatesAutoresizingMaskIntoConstraints = false
    return activityIndicator
}()
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download