AutoLayout failing when setting height of UIImageView - ios

I'm trying to create a auto-sizing UITableViewCell with an image and a label, using constraints. When I define a height for the image, the height for the label isn't set correctly for some cells, why is that?
The image below shows a cell with a label that has an incorrect height and one which has a correct height.
The code for my custom cell with the contraints is:
import UIKit
class NewsItemCell : UITableViewCell {
var msg: UILabel
var img: UIImageView!
required init(coder aDecoder: NSCoder) {
msg = UILabel()
msg.numberOfLines = 0
msg.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody)
msg.lineBreakMode = .ByWordWrapping
img = UIImageView()
img.contentMode = .ScaleAspectFill
img.clipsToBounds = true
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
addSubview(msg)
addSubview(img)
contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
msg.setTranslatesAutoresizingMaskIntoConstraints(false)
img.setTranslatesAutoresizingMaskIntoConstraints(false)
let c0 = NSLayoutConstraint(item: img, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0);
let c1 = NSLayoutConstraint(item: img, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant: 0)
let c2 = NSLayoutConstraint(item: img, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant: 0)
let c3 = NSLayoutConstraint(item: msg, attribute: .Top, relatedBy: .Equal, toItem: img, attribute: .Bottom, multiplier: 1, constant: 5)
let c4 = NSLayoutConstraint(item: msg, attribute: .Bottom, relatedBy: .Equal, toItem: self, attribute: .Bottom, multiplier: 1, constant: -5)
let c5 = NSLayoutConstraint(item: img, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 120)
let c6 = NSLayoutConstraint(item: msg, attribute: .Trailing, relatedBy: .Equal, toItem: self, attribute: .Trailing, multiplier: 1, constant:-5)
let c7 = NSLayoutConstraint(item: msg, attribute: .Leading, relatedBy: .Equal, toItem: self, attribute: .Leading, multiplier: 1, constant:5)
addConstraint(c0)
addConstraint(c1)
addConstraint(c2)
addConstraint(c3)
addConstraint(c4)
addConstraint(c5)
addConstraint(c6)
addConstraint(c7)
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}

Ah! Well there you see, asking if half the solution ^.^
It turned out that I was updating the msg.text value in the wrong delegate function. I was setting the msg.text in willDisplayCell but I had to set it in cellForRowAtIndexPath.

Related

Programmatically made constraints are not working

As I want to move away from xib and make my layout programmatically, I found that using the same exact constraints doesn't work as I would expect.
I want to make this UITableViewCell
It's a quite simple cell with a small icon to its right as well as an Activity Indicator so I can toggle which one I want to see. They are inside a View and to their left is a label
Those are my constraints in the outline view
And it works perfectly. However when I'm removing the XIB and doing all of the code myself, nothing works anymore
So here's my code:
class StandardRow: UITableViewCell {
private var initialWidth: CGFloat = 20
public var fetching: Bool = false {
didSet {
if (fetching) {
activityIndicator?.startAnimating()
} else {
activityIndicator?.stopAnimating()
}
changeImageWidth()
}
}
public var rightImage: UIImage? = nil {
didSet {
rightImageView?.image = rightImage
changeImageWidth()
}
}
private func changeImageWidth() {
if (activityIndicator?.isAnimating) ?? false || rightImage != nil {
imageWidth?.constant = initialWidth
} else {
imageWidth?.constant = 0
}
}
override func prepareForReuse() {
valueLabel?.text = ""
imageView?.image = nil
rightImage = nil
fetching = false
textLabel?.text = ""
accessoryType = .none
}
//Views
private var imageContainer = UIView()
private var rightImageView = UIImageView()
private var activityIndicator: UIActivityIndicatorView? = UIActivityIndicatorView()
public var valueLabel: UILabel? = UILabel()
private var imageWidth: NSLayoutConstraint? = nil
override init(style: UITableViewCell.CellStyle = .default, reuseIdentifier: String? = nil) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
buildView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
buildView()
}
func buildView() {
contentView.addSubview(valueLabel!)
imageContainer.addSubview(rightImageView)
imageContainer.addSubview(activityIndicator!)
contentView.addSubview(imageContainer)
imageContainer.backgroundColor = .red
}
override func layoutSubviews() {
super.layoutSubviews()
//IMAGE CONTAINER CONSTRAINTS
imageWidth = NSLayoutConstraint(item: imageContainer, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: initialWidth)
imageWidth?.priority = UILayoutPriority(rawValue: 999)
imageWidth?.isActive = true
let bottomImageContainerConstraint = NSLayoutConstraint(item: imageContainer, attribute: .bottom, relatedBy: .equal, toItem: contentView, attribute: .bottom, multiplier: 1, constant: 0)
bottomImageContainerConstraint.isActive = true
bottomImageContainerConstraint.priority = UILayoutPriority(rawValue: 999)
let topImageContainerConstraint = NSLayoutConstraint(item: imageContainer, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: 0)
topImageContainerConstraint.isActive = true
topImageContainerConstraint.priority = UILayoutPriority(rawValue: 999)
let trailingImageContainerConstraint = NSLayoutConstraint(item: imageContainer, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1, constant: 5)
trailingImageContainerConstraint.priority = UILayoutPriority(rawValue: 999)
trailingImageContainerConstraint.isActive = true
let centerYImageContainerConstraint = NSLayoutConstraint(item: imageContainer, attribute: .centerY, relatedBy: .equal, toItem: contentView, attribute: .centerY, multiplier: 1, constant: 0)
centerYImageContainerConstraint.isActive = true
centerYImageContainerConstraint.priority = UILayoutPriority(rawValue: 999)
//VALUE LABEL CONSTRAINTS
let trailingValueLabelConstraint = NSLayoutConstraint(item: valueLabel!, attribute: .trailing, relatedBy: .equal, toItem: imageContainer, attribute: .leading, multiplier: 1, constant: 5)
trailingValueLabelConstraint.isActive = true
trailingValueLabelConstraint.priority = UILayoutPriority(rawValue: 999)
let centerYValueLabelConstraint = NSLayoutConstraint(item: valueLabel!, attribute: .centerY, relatedBy: .equal, toItem: contentView, attribute: .centerY, multiplier: 1, constant: 0)
centerYValueLabelConstraint.isActive = true
centerYValueLabelConstraint.priority = UILayoutPriority(rawValue: 999)
//ACTIVITY INDICATOR CONSTRAINGS
NSLayoutConstraint(item: activityIndicator!, attribute: .trailing, relatedBy: .equal, toItem: imageContainer, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: activityIndicator!, attribute: .leading, relatedBy: .equal, toItem: imageContainer, attribute: .leading, multiplier: 1, constant: 11).isActive = false
NSLayoutConstraint(item: activityIndicator!, attribute: .bottom, relatedBy: .equal, toItem: imageContainer, attribute: .bottom, multiplier: 1, constant: 11).isActive = false
NSLayoutConstraint(item: activityIndicator!, attribute: .top, relatedBy: .equal, toItem: imageContainer, attribute: .top, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: activityIndicator!, attribute: .centerY, relatedBy: .equal, toItem: imageContainer, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
//RIGHT IMAGE VIEW CONSTRAINTS
NSLayoutConstraint(item: rightImageView, attribute: .trailing, relatedBy: .equal, toItem: activityIndicator!, attribute: .trailing, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: rightImageView, attribute: .leading, relatedBy: .equal, toItem: rightImageView, attribute: .leading, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: rightImageView, attribute: .bottom, relatedBy: .equal, toItem: activityIndicator!, attribute: .bottom, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: rightImageView, attribute: .top, relatedBy: .equal, toItem: activityIndicator!, attribute: .top, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: rightImageView, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator!, attribute: .centerY, multiplier: 1, constant: 0).isActive = true
//changeImageWidth()
}}
So I have a few ideas to where it can come from, firstly being "translatesAutoresizingMaskIntoConstraints" set to true by default, but when I'm setting it to false in the superview then my cell doesn't show anymore and in the contentView, Xcode tells me I shouldn't do that because of an undefined behaviour
I'm also using Reveal to debug my UI and then I found those peculiar values:
Which is not what I want, Reveal is reporting that those constraints are translating the autoresizing mask of the view to autolayout so it would confirm the previous theory. I did set the priority to 999 to some of the constraints because otherwise they would be broken.
I'm actually at a dead end and I think I'm missing something but I can't pinpoint what as I don't have enough experience with non-interface builder constraints
Try Anchors, it's much easier.
Example
var redView = UIView()
redView.backgroundColor = .red
anyView.addsubView(redView)
redView.translatesAutoresizingMaskIntoConstraints = false
redView.centerXAnchor.constraint(equalTo: self.parentView.centerXAnchor).isActive = true
redView.centerYAnchor.constraint(equalTo: self.parentView.centerYAnchor).isActive = true
redView.heightAnchor.constraint(equalToConstant: 100).isActive = true
redView.widthAnchor.constraint(equalToConstant: 100).isActive = true
You can add the same method to your UIView extension
func constrainToEdges(_ subview: UIView, top: CGFloat = 0, bottom: CGFloat = 0, leading: CGFloat = 0, trailing: CGFloat = 0) {
subview.translatesAutoresizingMaskIntoConstraints = false
let topContraint = NSLayoutConstraint(
item: subview,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: top)
let bottomConstraint = NSLayoutConstraint(
item: subview,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: bottom)
let leadingContraint = NSLayoutConstraint(
item: subview,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1.0,
constant: leading)
let trailingContraint = NSLayoutConstraint(
item: subview,
attribute: .trailing,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1.0,
constant: trailing)
addConstraints([
topContraint,
bottomConstraint,
leadingContraint,
trailingContraint])
}
I recommend using this framework for building constraint based layouts programmatically, it makes the process straightforward and faster. Take the setup for the contentView of this cell for example:
contentView.addSubview(descriptionLabel)
contentView.addSubview(amountLabel)
contentView.addSubview(dateLabel)
contentView.addSubview(bottomRightLabel)
constrain(descriptionLabel, amountLabel, dateLabel, bottomRightLabel) { desc, amount, date, bottomRight in
desc.top == desc.superview!.top + 16
desc.left == desc.superview!.left + 16
desc.right <= amount.left + 12
desc.bottom == date.top - 12
amount.centerY == desc.centerY
amount.right == amount.superview!.right - 12
date.left == date.superview!.left + 16
date.right <= bottomRight.left - 12
date.bottom == date.superview!.bottom - 16
bottomRight.centerY == date.centerY
bottomRight.right == bottomRight.superview!.right - 12
}

how to add constraints programmatically for rangeslider?

Here I used a GZRangeSlider for having a range slider and here i need to give constraints programmatically so that in order to have support for landscape mode can anyone help me how to give programmatically in table view cell ?
class SliderCell : UITableViewCell {
var rangeSlider = GZRangeSlider()
override func awakeFromNib() {
super.awakeFromNib()
rangeSlider = GZRangeSlider(frame: CGRect(x:8,y: 60 ,width: self.contentView.bounds.width - 32,height: 30))
self.addSubview(rangeSlider)
}
let rangeSliderLeadingConstraint = NSLayoutConstraint(
item: rangeSlider,
attribute: .leading,
relatedBy: .equal,
toItem: self,
attribute: .leading,
multiplier: 1.0,
constant: 0)
let rangeSliderTrailingConstriant = NSLayoutConstraint(
item: rangeSlider,
attribute: .trailing ,
relatedBy: .equal,
toItem: self,
attribute: .trailing,
multiplier: 1.0,
constant: 0)
let rangeSliderBottomConstriant = NSLayoutConstraint(
item:,
attribute: .bottom ,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1.0,
constant: 0)
let rangeSliderTopConstriant = NSLayoutConstraint(
item: rangeSlider,
attribute: .top ,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1.0,
constant: 0)
self.addConstraints([rangeSliderTopConstriant,rangeSliderBottomConstriant,rangeSliderTrailingConstriant,rangeSliderLeadingConstraint])

Dynamically positioning UILabel to bottom of content view with Swift?

I was trying to position my dynamically created UILabels to my contentView's bottom. I'm using HTML Parser called Fuzi to catch HTML tags and creating UILabels based on them;
func stringFromHTML( _ string: String?)
{
do{
let doc = try HTMLDocument(string: string!, encoding: String.Encoding.utf8)
if let root = doc.body {
for element in root.children {
if element.tag == "h2" {
// Create new label
let label = UILabel()
label.text = element.stringValue
label.numberOfLines = 0
label.font = UIFont(name: "Avenir Next", size: 17)
label.textColor = UIColor.black
self.contentView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
// Label constraints
let labelLeading = NSLayoutConstraint(item: label, attribute: .leading, relatedBy: .equal, toItem: contentView, attribute: .leading, multiplier: 1, constant: 20)
let labelTrailing = NSLayoutConstraint(item: label, attribute: .trailing, relatedBy: .equal, toItem: contentView, attribute: .trailing, multiplier: 1, constant: -20)
let labelTop = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: self.contentView.frame.origin.y)
self.contentView.addConstraints([labelLeading, labelTrailing, labelTop])
}
updateContentViewHeight()
}
}
}
catch{
print("html error\n",error)
}
}
func updateContentViewHeight(){
var totalContentHeight:CGFloat = 0.0
for i in self.contentView.subviews {
totalContentHeight += i.frame.height
}
let contentViewHeight:NSLayoutConstraint = NSLayoutConstraint(item: self.contentView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: totalContentHeight-29)
self.contentView.addConstraint(contentViewHeight)
}
I tried calling my stringFromHTML function in viewDidAppear. But it positions my UILabels to far far away (they don't seem).
I want to position my labels to the bottom of the last label, see the image below;
Anyone can help? Thanks in advance!
Change
let labelTop = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: self.contentView.frame.origin.y)
To
if label != nil {
let labelTop = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: label[index], attribute: .top, multiplier: 1, constant: 2)
} else {
let labelTop = NSLayoutConstraint(item: label, attribute: .top, relatedBy: .equal, toItem: contentView, attribute: .top, multiplier: 1, constant: self.contentView.frame.origin.y)
}
Because you are basically forcing each label to be at the same y position.

Auto layout completes animation in much less than the time provided

I want to animate a container width in 10 seconds (for example). I have two views and I assign size constraints to both of them, and call the empty init() method. The problem I'm having - the "animation" is over before you know it, even though I have 10 seconds in for the duration. What gives?
This is a reproducible example of the issue.
class ContainerView: UIView {}
class ChildView: UIView {}
class ViewController: UIViewController {
var containerView: ContainerView!
var childView: ChildView!
var widthConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
containerView = ContainerView()
containerView.backgroundColor = UIColor.blueColor()
childView = ChildView()
childView.backgroundColor = UIColor.redColor()
containerView.translatesAutoresizingMaskIntoConstraints = false
childView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(childView)
view.addSubview(containerView)
// Constraints
let containerWidthNumber: CGFloat = 200
let childWidthNumber: CGFloat = 100
let containerWidth = NSLayoutConstraint(item: containerView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: containerWidthNumber)
let containerHeight = NSLayoutConstraint(item: containerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: containerWidthNumber)
containerView.addConstraints([
containerWidth,
containerHeight,
NSLayoutConstraint(item: childView, attribute: .CenterX, relatedBy: .Equal, toItem: containerView, attribute: .CenterX, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childView, attribute: .Top, relatedBy: .Equal, toItem: containerView, attribute: .Top, multiplier: 1, constant: 0)
])
widthConstraint = NSLayoutConstraint(item: childView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: childWidthNumber)
let childHeight = NSLayoutConstraint(item: childView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: childWidthNumber)
childView.addConstraints([
widthConstraint,
childHeight,
])
view.addConstraints([
NSLayoutConstraint(item: containerView, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0),
NSLayoutConstraint(item: containerView, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1, constant: 0),
])
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
super.touchesBegan(touches, withEvent: event)
self.widthConstraint.constant = 50
UIView.animateWithDuration(10, animations: {
self.childView.layoutIfNeeded()
}, completion: { (success: Bool) in
if success {
print("good")
}
})
}
}

Have view centered and fill available height without going offscreen

I've got a situation where I would like a view to be centered in its superview, remain square, but fill as much height as possible without going off the edge, i.e., it should look at the available vertical and horizontal space, choosing the smallest between the 2.
There are 2 other views, one below and one above, that will both be either a button or label. The bottom/top of these views should be attached to the top/bottom of the central view. I can get this to work, to an extent, but I'll explain my issue below, and what I've got so far:
Top label has:
.Top >= TopLayoutGuide.Bottom
.Top = TopLayoutGuide.Bottom (priority 250)
.Right = CentralView.Right
Central view has:
Center X and Y = Superview Center X and Y
.Height <= Superview.Width * 0.9
.Width = self.Height
.Top = TopLabel.Bottom
Bottom button has:
.Right = CentralView.Right
.Top = CentralView.Bottom
.Bottom <= (BottomLayoutGuide.Top - 16)
Running this seems fine, and produces the desired results:
However, if I make the view an instance of my custom class and add a UIButton subview, it all goes wrong. In this class I perform:
self.topLeftButton = CustomButtonClass()
self.topLeftButton.setTranslatesAutoresizingMaskIntoConstraints(false)
self.addSubview(self.topLeftButton)
self.addConstraints([
NSLayoutConstraint(item: self.topLeftButton, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.topLeftButton, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1, constant: 0),
NSLayoutConstraint(item: self.topLeftButton, attribute: .Height, relatedBy: .Equal, toItem: self, attribute: .Height, multiplier: 0.5, constant: 0),
NSLayoutConstraint(item: self.topLeftButton, attribute: .Width, relatedBy: .Equal, toItem: self.topLeftButton, attribute: .Width, multiplier: 1, constant: 0)
])
Using this code the view collapses down to the following:
I can't figure out why this is. I've made a few small tweaks here and there, but not managed to get it to work as desired. If I add the same button in IB the view wants to collapse again, and it's as if the button will not grow in height.
In real life I wouldn't subclass UIButton, but have done in my answer, as that is what the question indicated. UIButton works best through composition. So maybe better to create a UIButton, then modify its properties.
class FooViewController: UIViewController {
override func viewDidLoad() {
var view = CustomView()
view.backgroundColor = UIColor.darkGrayColor()
var label = UILabel()
label.text = "Label"
var button = UIButton.buttonWithType(.System) as UIButton
button.setTitle("Button", forState: .Normal)
view.setTranslatesAutoresizingMaskIntoConstraints(false)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
button.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(view)
self.view.addSubview(label)
self.view.addSubview(button)
// The width should be as big as possible...
var maxWidthConstraint = NSLayoutConstraint(item: view, attribute: .Width, relatedBy: .Equal, toItem: view.superview, attribute: .Width, multiplier: 1, constant: 0);
// ... but not at the expense of other constraints
maxWidthConstraint.priority = 1
self.view.addConstraints([
// Max width, if possible
maxWidthConstraint,
// Width and height can't be bigger than the container
NSLayoutConstraint(item: view, attribute: .Width, relatedBy: .LessThanOrEqual, toItem: view.superview, attribute: .Width, multiplier: 1, constant: 0),
NSLayoutConstraint(item: view, attribute: .Width, relatedBy: .LessThanOrEqual, toItem: view.superview, attribute: .Height, multiplier: 1, constant: 0),
// Width and height are equal
NSLayoutConstraint(item: view, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Width, multiplier: 1, constant: 0),
// View is centered
NSLayoutConstraint(item: view, attribute: .CenterX, relatedBy: .Equal, toItem: view.superview, attribute: .CenterX, multiplier: 1, constant: 0),
NSLayoutConstraint(item: view, attribute: .CenterY, relatedBy: .Equal, toItem: view.superview, attribute: .CenterY, multiplier: 1, constant: 0),
])
// Label above view
self.view.addConstraints([
NSLayoutConstraint(item: label, attribute: .Top, relatedBy: .GreaterThanOrEqual, toItem: label.superview, attribute: .Top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: label, attribute: .Bottom, relatedBy: .Equal, toItem: view, attribute: .Top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: label, attribute: .Right, relatedBy: .LessThanOrEqual, toItem: view, attribute: .Right, multiplier: 1, constant: 0),
])
// Button below view
self.view.addConstraints([
NSLayoutConstraint(item: button, attribute: .Bottom, relatedBy: .LessThanOrEqual, toItem: button.superview, attribute: .Bottom, multiplier: 1, constant: 0),
NSLayoutConstraint(item: button, attribute: .Top, relatedBy: .Equal, toItem: view, attribute: .Bottom, multiplier: 1, constant: 0),
NSLayoutConstraint(item: button, attribute: .Right, relatedBy: .LessThanOrEqual, toItem: view, attribute: .Right, multiplier: 1, constant: 0),
])
}
}
class CustomView: UIView {
required init(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override init() {
super.init()
var button = CustomButton()
button.setTitle("Custom Button", forState: UIControlState.Normal)
button.setTranslatesAutoresizingMaskIntoConstraints(false)
self.addSubview(button)
// Custom button in the top left
self.addConstraints([
NSLayoutConstraint(item: button, attribute: .Top, relatedBy: .Equal, toItem: self, attribute: .Top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: button, attribute: .Left, relatedBy: .Equal, toItem: self, attribute: .Left, multiplier: 1, constant: 0),
])
}
}
class CustomButton: UIButton {
required init(coder: NSCoder) {
super.init(coder: coder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override init() {
super.init()
self.backgroundColor = UIColor.greenColor()
}
}

Resources