Horizontal Align labels [duplicate] - swift

This question already has an answer here:
Generate labels and align in middle
(1 answer)
Closed 7 years ago.
How can i generate a random amount of labels and align them next to each other in the middle?
I have this code to generate an label:
var label = UILabel(frame: CGRectMake(5, 196, 35,45 ))
label.textAlignment = NSTextAlignment.Center
label.backgroundColor = UIColor.redColor()
label.text = "1";
label.tag = 5;
self.view.addSubview(label);
This work perfect, but how can i generate more than 1 label and set them next to each other in the middle?
like this:
Or if i generate 3 labels it must looks like this:
Is this possible to do it programmaticly?

This will do it:
var lastLabel : UILabel?
var count = 1
#IBAction func addlabel(sender: AnyObject) {
var label = UILabel()
label.textAlignment = NSTextAlignment.Center
label.backgroundColor = UIColor.redColor()
label.text = count.description;
count++
label.tag = 5;
var centerX = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
centerX.priority = 999
//This if you want to center it vertically also
var centerY = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
var height = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 35)
var width = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 45)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(label);
if let prevlabel = lastLabel {
var align = NSLayoutConstraint(item: prevlabel, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: label, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: -20)
//Here just add the NSLayoutConstraint you want to apply, if its only horizontal then not add centerY
NSLayoutConstraint.activateConstraints([align, centerY, height, width, centerX])
}else {
NSLayoutConstraint.activateConstraints([centerX, centerY, height, width])
}
lastLabel = label
}

Related

How do I add constraints programmatically to my UILabel

Is there a way in swift to have a label and make constraints for it programmatically. For example on all devices to 'Pin to the top' or 'Pin to the right side' so that on all devices it just pins to whatever device is being used.
It's because I've created a label programmatically, so I want to make constraints for it.
If you need more info, just let me know. Thanks :)
override func viewDidLoad() {
super.viewDidLoad()
let label = UILabel()
self.view.addSubview(label)
label.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
}
This will bind the item to all the edges, making it as big as the screen. Anchor is used to refer to an point in game. which is either its superview or some view on the same level as your current view. You can use references as i did self.view.trailingAnchor, and you can also add offsets and insets view.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 8).isActive = true. Or you can name the direct size of something label.heightAnchor.constraint(equalToConstant: CGFloat).isActive = true. Good luck
You can easily add Constraints programatically using NSLayoutConstraints. Below is the code sample for it. I have used centering constraint , you can use leading and top constraints with height and width.
func addLabel(){
let newView =UILabel()
self.view.addSubview(newView)
newView.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0)
let verticalConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0)
let widthConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)
let heightConstraint = NSLayoutConstraint(item: newView, attribute: NSLayoutAttribute.height, relatedBy: NSLayoutRelation.equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1, constant: 100)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint, widthConstraint, heightConstraint])
}
the code below, will stick your label to top-right as you want, on all d devices,
let aLabel = UILabel()
self.view.addSubview(aLabel)
aLabel.backgroundColor = UIColor.gray
aLabel.text = " i am a label"
aLabel.textAlignment = .center
aLabel.translatesAutoresizingMaskIntoConstraints = false
let horizontalConstraint = NSLayoutConstraint(item: aLabel, attribute: NSLayoutAttribute.trailing, relatedBy: NSLayoutRelation.equal, toItem: view, attribute:NSLayoutAttribute.trailing, multiplier: 1, constant: 0)
let verticalConstraint = NSLayoutConstraint(item: aLabel, attribute: NSLayoutAttribute.top, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.top, multiplier: 1, constant: 0)
NSLayoutConstraint.activate([horizontalConstraint, verticalConstraint])
self.view.layoutIfNeeded()

Setting 2 label in header programatically - not label seen

I'm trying to set 2 labels, one under other with different font size in the header. The function is called like this:
viewController.navigationItem.titleView = self.setHeader()
And code responsible for generating label is :
private func setHeader(agentName: String = "", isTyping: Bool = false) -> UIView {
let headerLabel: UILabel = {
let label = UILabel()
label.text = self.title
label.font = UIFont.systemFont(ofSize: 21)
label.textColor = UIColor.white
return label
}()
let subheaderLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 10)
return label
}()
let headerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(headerLabel)
view.addConstraints([
NSLayoutConstraint(item: headerLabel, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1.0, constant: 0),
NSLayoutConstraint(item: headerLabel, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0),
NSLayoutConstraint(item: headerLabel, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 16),
NSLayoutConstraint(item: headerLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 16)
])
return view
}()
if (!agentName.isEmpty) {
if (isTyping) {
subheaderLabel.text = agentName + " is typing ..."
} else {
subheaderLabel.text = agentName
}
headerView.addSubview(subheaderLabel)
}
return headerView
}
When I running IOS app there is nothing shown in the header. What is a reason?
I think you need to set the frame for the headerView. So in the initialization code for the headerView, use initializer with frame:
let headerView: UIView = {
// initialize the view with frame
let view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 35))
// you want to call this on the headerLabel, not on view
headerLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(headerLabel)
view.addConstraints([
NSLayoutConstraint(item: headerLabel, attribute: .centerY, relatedBy: .equal, toItem: view, attribute: .centerY, multiplier: 1.0, constant: 0),
NSLayoutConstraint(item: headerLabel, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1.0, constant: 0),
NSLayoutConstraint(item: headerLabel, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 16),
NSLayoutConstraint(item: headerLabel, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 16)
])
return view
}()
Moreover, I believe headerLabel you want to set translatesAutoresizingMaskIntoConstraints on headerLabel rather than on headerView (headerView is positioned through frame and not Autolayout).
Also, notice that you add subheaderLabel to the view, but you never position it, don't forget about it either (although this should cause only subheaderLabel not to be rendered properly).

Positioning miltiple views programmatically in swift

With your last help my loop is functioning well. But only once. If I try to reload it I get the following mistake: "Index out of range" in the following line:
let cardOnTop = cards[index-8]
Could somebody help me?
Here is my code:
func layoutCards() {
// create cards array with several elements
var cards = (1...64).map { _ in UIView() }// array with several cards
//Loop through each card in the array
for index in 0...cards.count-1 {
// place the card in the view and turn off translateAutoresizingMask
let thisCard = cards[index]
thisCard.layer.borderWidth = 1
thisCard.layer.borderColor = UIColor.blackColor().CGColor
thisCard.backgroundColor = UIColor.greenColor()
thisCard.translatesAutoresizingMaskIntoConstraints = false
midView.addSubview(thisCard)
//set the height and width constraints
let widthConstraint = NSLayoutConstraint(item: thisCard, attribute: .Width, relatedBy: .Equal, toItem: midView, attribute: .Width, multiplier: 0.125, constant: 0)
let heightConstraint = NSLayoutConstraint(item: thisCard, attribute: .Height, relatedBy: .Equal, toItem: midView, attribute: .Height, multiplier: 0.125, constant: 0)
midView.addConstraints([heightConstraint, widthConstraint])
//set the horizontal position
if (columnCounter > 0) {
// card is not in the first column
let cardOnTheLeft = cards[index-1]
let leftSideConstraint = NSLayoutConstraint(item: thisCard, attribute: .Left, relatedBy: .Equal, toItem: cardOnTheLeft, attribute: .Right, multiplier: 1, constant: 0)
//add constraint to the contentView
midView.addConstraint(leftSideConstraint)
} else {
//card is in the first column
let leftSideConstraint = NSLayoutConstraint(item: thisCard, attribute: .Left, relatedBy: .Equal, toItem: midView, attribute: .Left, multiplier: 1, constant: 0)
//add constraint to the contentView
midView.addConstraint(leftSideConstraint)
}
//set the vertical position
if (rowCounter > 0) {
// card is not in the first row
let cardOnTop = cards[index-8]
let topConstraint = NSLayoutConstraint(item: thisCard, attribute: .Top, relatedBy: .Equal, toItem: cardOnTop, attribute: .Bottom, multiplier: 1, constant: 0)
// add constraint to the contentView
midView.addConstraint(topConstraint)
} else {
//card is in the first row
let topConstraint = NSLayoutConstraint(item: thisCard, attribute: .Top, relatedBy: .Equal, toItem: midView, attribute: .Top, multiplier: 1, constant: 0)
//add constraint to the contentView
midView.addConstraint(topConstraint)
}
//increment the column counter
columnCounter = columnCounter+1
//if the column counter reaches the fifth column reset it and increase the row counter
if (columnCounter >= 8) {
columnCounter = 0
rowCounter = rowCounter+1
}
} // end of the loop
}
You say this is failing when you run it a second time. That is because you apparently have rowCounter and columnCounter declared as properties and you are not setting rowCounter and columnCounter back to 0 each time layoutCards() is called.
Make rowCounter and columnCounter be local variables to layoutCards():
func layoutCards() {
var rowCounter = 0
var columnCounter = 0
// create cards array with several elements
var cards = (1...64).map { _ in UIView() }// array with several cards

Swift : Adding Constraints to UILabel Programmatically

So I had a break from iOS dev for 4 months and its seems I have forgotten everything. All I am trying to do is place a Label programmatically at 0,0, size 200,50. I hear there is a few changes in iOS8 which I don't remember
let x : CGFloat = 0.0
let y : CGFloat = 0.0
let width : CGFloat = 200.0
let height : CGFloat = 50.0
self.label = UILabel(frame: CGRect(x: x, y: y, width: width, height: height))
self.label.text = "SIMON"
self.label.textColor = UIColor.whiteColor()
self.label.font = UIFont(name: "HelveticaNeue-UltraLight", size: 24)
self.label.textAlignment = NSTextAlignment.Center
self.label.backgroundColor = UIColor.redColor()
self.label.layer.masksToBounds = true;
self.label.layer.cornerRadius = 8.0;
self.label.adjustsFontSizeToFitWidth = true;
self.label.translatesAutoresizingMaskIntoConstraints = false
widthConstraint = NSLayoutConstraint(item: self.label, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: width)
heightConstraint = NSLayoutConstraint(item: self.label, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: height)
leftConstraint = NSLayoutConstraint(item: self.label, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: x)
topConstraint = NSLayoutConstraint(item: self.label, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.TopMargin, multiplier: 1, constant: y)
self.view.addSubview(self.label)
NSLayoutConstraint.activateConstraints([leftConstraint,topConstraint, widthConstraint, heightConstraint] )
It appears I was being dump!
It was the event I was calling it from, not the code. Moved to viewWillAppear

Generate labels and align in middle

How can i generate a random amount of labels and align them next to each other in the middle?
I have this code to generate an label:
var label = UILabel(frame: CGRectMake(5, 196, 35,45 ))
label.textAlignment = NSTextAlignment.Center
label.backgroundColor = UIColor.redColor()
label.text = "1";
label.tag = 5;
self.view.addSubview(label);
This work perfect, but how can i generate more than 1 label and set them next to each other in the middle?
like this:
The green things are my labels, and are align horizontally. How can i do this programmatically?
This will do it:
var lastLabel : UILabel?
var count = 1
#IBAction func addlabel(sender: AnyObject) {
var label = UILabel()
label.textAlignment = NSTextAlignment.Center
label.backgroundColor = UIColor.redColor()
label.text = count.description;
count++
label.tag = 5;
var centerX = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0)
centerX.priority = 999
//This if you want to center it vertically also
var centerY = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self.view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0)
var height = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 35)
var width = NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 45)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(label);
if let prevlabel = lastLabel {
var align = NSLayoutConstraint(item: prevlabel, attribute: NSLayoutAttribute.TrailingMargin, relatedBy: NSLayoutRelation.Equal, toItem: label, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1, constant: -20)
//Here just add the NSLayoutConstraint you want to apply, if its only horizontal then not add centerY
NSLayoutConstraint.activateConstraints([align, centerY, height, width, centerX])
}else {
NSLayoutConstraint.activateConstraints([centerX, centerY, height, width])
}
lastLabel = label
}