How to position rotated UILabels inside a UIStackView with no gap? - ios

I'm trying to create a UIStackView containing UILabels that have been rotated. The UIStackView is positioning the UILabels based on their non-rotated widths, such that there is a large gap when I would expect the UILabels to be directly adjacent. How can I correctly reposition these elements?
Code:
let stackView = UIStackView(frame: canvas.bounds)
stackView.translatesAutoresizingMaskIntoConstraints = false
canvas.addSubview(stackView)
stackView.axis = .horizontal
stackView.topAnchor.constraint(equalTo: canvas.topAnchor, constant: 0).isActive = true
stackView.bottomAnchor.constraint(equalTo: canvas.bottomAnchor, constant: 0).isActive = true
stackView.leftAnchor.constraint(equalTo: canvas.leftAnchor, constant: 0).isActive = true
let label1 = UILabel()
label1.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
label1.text = "THREEEEEEEE"
stackView.addArrangedSubview(label1)
let label2 = UILabel()
label2.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
label2.text = "FOUR"
stackView.addArrangedSubview(label2)
What I'm Seeing:
UI Inspector View:
What I Expect:

Why don't you try to add the views to the stack view first, and then rotate the stack view?
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
view.addSubview(label)
self.view = view
let label1 = UILabel()
label1.text = "THREEEEEEEE"
let label2 = UILabel()
label2.text = "FOUR"
let stackView = UIStackView(arrangedSubviews: [label1, label2])
stackView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.axis = .vertical
stackView.topAnchor.constraint(equalTo: label.bottomAnchor, constant: 100).isActive = true
I used the view instead of the canvas.

Related

I want to set label & Imageview in centre of myView but App crashing after adding some constraints

Error:-
Thread 1: "Unable to activate constraint with anchors <NSLayoutXAxisAnchor:0x280af8500 \"UILabel:0x103dc4fa0.centerX\"> and <NSLayoutXAxisAnchor:0x280af89c0 \"UIView:0x103dc49d0.centerX\"> because they have no common ancestor. Does the constraint or its anchors reference items in different view hierarchies? That's illegal."
I've created a function programmatical in Base view controller which returns a view & I've added some constraints to its
Function:-
func getMarker (lbl:String, img:UIImage) -> UIView {
let myView = UIView(frame: CGRect.zero)
myView.center = CGPoint(x: 50, y: 160)
myView.backgroundColor = UIColor.clear
let imageView = UIImageView(image: img)
imageView.frame = CGRect(x: 0, y: 0, width: 20, height: 40)
myView.addSubview(imageView)
let label = UILabel(frame: CGRect(x: 0, y: 45, width: 120, height: 30))
label.text = lbl
label.textAlignment = .center
label.adjustsFontSizeToFitWidth = true
label.textColor = UIColor.black
label.backgroundColor = UIColor.white
label.layer.borderColor = UIColor.lightGray.cgColor
label.layer.borderWidth = 0.5
label.layer.cornerRadius = 5
label.layer.masksToBounds = true
label.sizeToFit()
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
imageView.centerXAnchor.constraint(equalTo: myView.centerXAnchor)
])
myView.addSubview(label)
return myView
}
calling function in another controller but it crashing and showing me the error which I mentioned above
Calling function:-
getMarker(lbl: device.name ?? "", img: (UIImage(named: icfile) ?? UIImage(named: "truck_1_orange")!))
U need to add subview first, then activate layout. Label is not in myView subviews in your code. It is not in any hierarchy at the moment of layout constraint activation.
myView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
imageView.centerXAnchor.constraint(equalTo: myView.centerXAnchor)
])
You need to configure the layout of your subviews (imageView and label) in order to have them sized and positioned where you want them.
Take a look at this example code:
class MarkerVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
guard let img = UIImage(named: "img80x80")
else {
fatalError("Could not load sample image!!!")
}
let markerView1 = getMarker(lbl: "Testing", img: img)
let markerView2 = getMarkerAutoSized(lbl: "Testing", img: img)
markerView1.translatesAutoresizingMaskIntoConstraints = false
markerView2.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(markerView1)
view.addSubview(markerView2)
// respect safe area
let safeG = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// we have to set both Position and Size constraints
// for markerView1
markerView1.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 20.0),
markerView1.widthAnchor.constraint(equalToConstant: 240.0),
markerView1.heightAnchor.constraint(equalToConstant: 100.0),
markerView1.centerXAnchor.constraint(equalTo: view.centerXAnchor),
// markerView2 uses its subviews to set its own size
// so we only need position constraints
markerView2.topAnchor.constraint(equalTo: markerView1.bottomAnchor, constant: 20.0),
markerView2.centerXAnchor.constraint(equalTo: view.centerXAnchor),
])
// so we can see the view frames
markerView1.backgroundColor = .systemRed
markerView2.backgroundColor = .systemRed
}
func getMarker (lbl:String, img:UIImage) -> UIView {
let myView = UIView()
myView.backgroundColor = UIColor.clear
let imageView = UIImageView(image: img)
let label = UILabel()
label.text = lbl
label.textAlignment = .center
label.adjustsFontSizeToFitWidth = true
label.textColor = UIColor.black
label.backgroundColor = UIColor.white
label.layer.borderColor = UIColor.lightGray.cgColor
label.layer.borderWidth = 0.5
label.layer.cornerRadius = 5
label.layer.masksToBounds = true
imageView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
myView.addSubview(imageView)
myView.addSubview(label)
NSLayoutConstraint.activate([
// image view Width and Height
imageView.widthAnchor.constraint(equalToConstant: 20.0),
imageView.heightAnchor.constraint(equalToConstant: 40.0),
// labe Width and Height
label.widthAnchor.constraint(equalToConstant: 120.0),
label.heightAnchor.constraint(equalToConstant: 30.0),
// image view aligned to Top
imageView.topAnchor.constraint(equalTo: myView.topAnchor),
// centered Horizontally
imageView.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
// label 5-pts below image view
label.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 5.0),
// centered Horizontally
label.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
])
return myView
}
func getMarkerAutoSized (lbl:String, img:UIImage) -> UIView {
let myView = UIView()
myView.backgroundColor = UIColor.clear
let imageView = UIImageView(image: img)
let label = UILabel()
label.text = lbl
label.textAlignment = .center
label.adjustsFontSizeToFitWidth = true
label.textColor = UIColor.black
label.backgroundColor = UIColor.white
label.layer.borderColor = UIColor.lightGray.cgColor
label.layer.borderWidth = 0.5
label.layer.cornerRadius = 5
label.layer.masksToBounds = true
imageView.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
myView.addSubview(imageView)
myView.addSubview(label)
NSLayoutConstraint.activate([
// image view Width and Height
imageView.widthAnchor.constraint(equalToConstant: 20.0),
imageView.heightAnchor.constraint(equalToConstant: 40.0),
// labe Width and Height
label.widthAnchor.constraint(equalToConstant: 120.0),
label.heightAnchor.constraint(equalToConstant: 30.0),
// image view aligned to Top
imageView.topAnchor.constraint(equalTo: myView.topAnchor),
// centered Horizontally
imageView.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
// label 5-pts below image view
label.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 5.0),
// centered Horizontally
label.centerXAnchor.constraint(equalTo: myView.centerXAnchor),
// to auto-size myView
label.leadingAnchor.constraint(equalTo: myView.leadingAnchor),
label.trailingAnchor.constraint(equalTo: myView.trailingAnchor),
label.bottomAnchor.constraint(equalTo: myView.bottomAnchor),
])
return myView
}
}
I modified your getMarker(...) func to size and position the subviews.
I also added a very similar getMarkerAutoSized(...) func that uses a couple additional constraints on the subviews.
For the first version, we must set both the Position and Size of the generated view.
For the second version, we only need to set the generated view's Position because it sizes itself to fit its subviews.
Here's how they look:

Swift: Programmatic Autolayout broken by UNavigationController

I have inherited a UIKit app where my predecessor has written all the interface code by hand. I have a view controller, a simple login screen that works just fine, but when I add it to a UINavigationController it is oddly stretched. This doesn't make a lot of sense to me.
I feel like I must be missing some simple flag, or what do I need to do to make the Navcontroller play nice with this programmatic autolayout (which is hopefully my last ever)
// this a view controller extension
func apply(constraints: [NSLayoutConstraint]) {
translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate(constraints)
}
There's my handy dandy, seemingly sane utility for applying constraints. As an example, the nice little oval thing making my password textfield looks nice has these constraints set up.
// these constraints are being setup in the view controller
emailCapsuleView.apply(constraints: [
emailCapsuleView.topAnchor.constraint(equalTo: subBigTitle.bottomAnchor, constant: 24.0),
emailCapsuleView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
emailCapsuleView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8),
emailCapsuleView.heightAnchor.constraint(equalToConstant: Dimensions.inputFieldHeight)
])
Outside of a UINavigationController everything is fine,
but in a UINavigationController everythhing is super wide and broken (simulator shot)
The width is not the problem here - if I use a constant for the width, my subview is still off center despite having it's centerX sets to the view controller's view's center X.
Configure your navigation controller and after that try like this:
set your objects:
let emailTextfield: UITextField = {
let tf = UITextField()
tf.backgroundColor = .white
tf.layer.borderWidth = 1
tf.layer.borderColor = UIColor.lightGray.cgColor
tf.setPadding(left: 10, right: 10)// use my extension below
tf.attributedPlaceholder = NSAttributedString(string: "Email address", attributes: [.foregroundColor: UIColor.lightGray])
tf.layer.cornerRadius = 14
tf.clipsToBounds = true
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
let passTextfield: UITextField = {
let tf = UITextField()
tf.backgroundColor = .white
tf.layer.borderWidth = 1
tf.layer.borderColor = UIColor.lightGray.cgColor
tf.setPadding(left: 10, right: 10)// use my extension below
tf.attributedPlaceholder = NSAttributedString(string: "Password", attributes: [.foregroundColor: UIColor.lightGray])
tf.layer.cornerRadius = 14
tf.clipsToBounds = true
tf.translatesAutoresizingMaskIntoConstraints = false
return tf
}()
let loginButton: UIButton = {
let b = UIButton(type: .system)
b.backgroundColor = .black
b.setTitle("Save Image", for: .normal)
b.titleLabel?.font = .systemFont(ofSize: 16, weight: .semibold)
b.setTitleColor(.white, for: .normal)
b.layer.cornerRadius = 14
b.clipsToBounds = true
b.translatesAutoresizingMaskIntoConstraints = false
return b
}()
let subBigTitle: UILabel = {
let l = UILabel()
l.text = "Your Big Title"
l.font = .systemFont(ofSize: 30, weight: .regular)
l.textColor = .black
l.textAlignment = .center
l.translatesAutoresizingMaskIntoConstraints = false
return l
}()
Now in viewDidLoad set stackView, bigTitle label and constraints:
view.addSubview(subBigTitle)
subBigTitle.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
subBigTitle.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
subBigTitle.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
subBigTitle.heightAnchor.constraint(equalToConstant: 60).isActive = true
let stackView = UIStackView(arrangedSubviews: [emailTextfield, passTextfield, loginButton])
stackView.axis = .vertical
stackView.distribution = .fillEqually
stackView.spacing = 10
stackView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stackView)
stackView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.8).isActive = true
stackView.heightAnchor.constraint(equalToConstant: 170).isActive = true
stackView.topAnchor.constraint(equalTo: subBigTitle.bottomAnchor, constant: 24).isActive = true
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
to add text padding to your textfield use my extension:
extension UITextField {
func setPadding(left: CGFloat, right: CGFloat){
let paddingView = UIView(frame: CGRect(x: 0, y: 0, width: left, height: self.frame.size.height))
self.leftView = paddingView
self.leftViewMode = .always
let paddingViewRight = UIView(frame: CGRect(x: 0, y: 0, width: right, height: self.frame.size.height))
self.rightView = paddingViewRight
self.rightViewMode = .always
}
}
and this is the result:

ScrollView not scrolling when label text is big string

I'm trying to create a scroll view programatically, but it is not working as expected. Here is my code.
let scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.leadingAnchor(equalTo: view.leadingAnchor)
scrollView.trailingAnchor(equalTo: view.trailingAnchor)
scrollView.topAnchor(equalTo: view.topAnchor)
scrollView.bottomAnchor(equalTo: view.bottomAnchor)
let imageview = UIImageView()
scrollView.addSubview(imageview)
let contentLabel = UILabel()
scrollView.addSubview(contentLabel)
imageview.leadingAnchor(equalTo: view.leadingAnchor)
imageview.trailingAnchor(equalTo: view.trailingAnchor)
imageview.topAnchor(equalTo: view.topAnchor)
imageview.heightAnchor(equalTo: 300)
imageview.backgroundColor = .cyan
contentLabel.numberOfLines = 0
contentLabel.leadingAnchor(equalTo: view.leadingAnchor)
contentLabel.trailingAnchor(equalTo: view.trailingAnchor)
contentLabel.topAnchor(equalTo: imageview.bottomAnchor, constant: 16)
contentLabel.bottomAnchor(equalTo: scrollView.bottomAnchor, constant: -16)
contentLabel.text = BIG_TEXT
I'm trying to add an image view and text below that. When the text content is more I should make it scrollable. Thanks in advance.!!
Try to add a UIStackView as the first child of your UIScrollView and add your subviews to it with the addArrangedSubview method:
let scrollView = UIScrollView()
view.addSubview(scrollView)
scrollView.leadingAnchor(equalTo: view.leadingAnchor)
scrollView.trailingAnchor(equalTo: view.trailingAnchor)
scrollView.topAnchor(equalTo: view.topAnchor)
scrollView.bottomAnchor(equalTo: view.bottomAnchor)
let stackView = UIStackView()
stackView.axis = .vertical
stackView.leadingAnchor(equalTo: scrollView.leadingAnchor)
stackView.trailingAnchor(equalTo: scrollView.trailingAnchor)
stackView.topAnchor(equalTo: scrollView.topAnchor)
stackView.bottomAnchor(equalTo: scrollView.bottomAnchor)
stackView.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)
let imageview = UIImageView()
imageview.heightAnchor(equalTo: 300)
imageview.backgroundColor = .cyan
stackView.addArrangedSubview(imageview)
let contentLabel = UILabel()
contentLabel.text = BIG_TEXT
contentLabel.numberOfLines = 0
stackView.addArrangedSubview(contentLabel)
stackView.layoutIfNeeded()

Adding Separator View for Horizontal StackView with Equal Width Labels

I am trying to get fixed width labels to be set in stackview and have a separator in between the label.
However, I have tried many variations but can't get to have it exactly placed.
Below is the code and screenshot I have used, but wanted to know if there is something much better? I tried using compression and resistance but it didn't worked the way I wanted, or maybe I am just not setting it right?
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .fill // .Leading .FirstBaseline .Center .Trailing .LastBaseline
stackView.distribution = .fill // .FillEqually .FillProportionally .EqualSpacing .EqualCentering
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.backgroundColor = .green
//label.setContentHuggingPriority(UILayoutPriority(999), for: .horizontal)
//label.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.3).isActive = true
//label.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 998), for: .horizontal)
label.text = "Label, Label, Label Label Label Label Label Label Label Label Label"
let label2 = UILabel(frame: .zero)
label2.numberOfLines = 0
label2.backgroundColor = .red
//label2.setContentHuggingPriority(UILayoutPriority(998), for: .horizontal)
//label2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 750), for: .horizontal)
label2.text = "Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2"
let label3 = UILabel(frame: .zero)
label3.numberOfLines = 0
label3.backgroundColor = .blue
//label3.setContentHuggingPriority(UILayoutPriority(998), for: .horizontal)
//label3.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 750), for: .horizontal)
label3.text = "Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2"
let separator = UIView()
separator.widthAnchor.constraint(equalToConstant: 1).isActive = true
separator.backgroundColor = .black
//separator.setContentHuggingPriority(UILayoutPriority(249), for: .horizontal)
//separator.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 749), for: .horizontal)
//stackView.addArrangedSubview(separator)
//separator.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: 0.6).isActive = true
let separator2 = UIView()
separator2.widthAnchor.constraint(equalToConstant: 1).isActive = true
separator2.backgroundColor = .black
stackView.addArrangedSubview(label)
label.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.333).isActive = true
stackView.addArrangedSubview(separator)
stackView.addArrangedSubview(label2)
label2.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.333).isActive = true
stackView.addArrangedSubview(separator2)
stackView.addArrangedSubview(label3)
label3.widthAnchor.constraint(equalTo: stackView.widthAnchor, multiplier: 0.333).isActive = true
separator.heightAnchor.constraint(equalTo: stackView.heightAnchor).isActive = true
self.view.addSubview(stackView)
stackView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 30).isActive = true
stackView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 30).isActive = true
Hey I'd propose to use UIKitPlus library
The trick is to use equal width for all three labels and for that you should link label#2 and label#3 widths to width of label#1. This is because you want a black separator view between them.
import UIKitPlus
class ThreeLabelsViewController: ViewController {
var loremIpsumText: String { "Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups." }
lazy var text1 = Text(loremIpsumText)
override func buildUI() {
super.buildUI()
body {
HStack {
text1.background(.green).multiline()
HSpace(10).background(.black)
Text(loremIpsumText).background(.red).multiline().width(to: text1)
HSpace(10).background(.black)
Text(loremIpsumText).background(.blue).multiline().width(to: text1)
}
.edgesToSuperview()
}
}
}
Because without that separator view you can use StackView's spacing and distribution properties to do the same easily.
import UIKitPlus
class ThreeLabelsViewController: ViewController {
var loremIpsumText: String { "Lorem ipsum is placeholder text commonly used in the graphic, print, and publishing industries for previewing layouts and visual mockups." }
override func buildUI() {
super.buildUI()
view.backgroundColor = .black
body {
HStack {
Text(loremIpsumText).background(.green).multiline()
Text(loremIpsumText).background(.red).multiline()
Text(loremIpsumText).background(.blue).multiline()
}
.spacing(10)
.distribution(.fillEqually)
.edgesToSuperview()
}
}
}
And visible result is the same
This code is your solution?
StackView can auto resize width, you must be set separator width.
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .horizontal
stackView.alignment = .fill // .Leading .FirstBaseline .Center .Trailing .LastBaseline
stackView.distribution = .fill // .FillEqually .FillProportionally .EqualSpacing .EqualCentering
let label = UILabel(frame: .zero)
label.numberOfLines = 0
label.backgroundColor = .green
label.text = "Label, Label, Label Label Label Label Label Label Label Label Label"
let label2 = UILabel(frame: .zero)
label2.numberOfLines = 0
label2.backgroundColor = .red
label2.text = "Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2"
let label3 = UILabel(frame: .zero)
label3.numberOfLines = 0
label3.backgroundColor = .blue
label3.text = "Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2 Label2"
let separatorWidth: CGFloat = 10
let separator = UIView()
separator.widthAnchor.constraint(equalToConstant: separatorWidth).isActive = true
separator.backgroundColor = .black
let separator2 = UIView()
separator2.widthAnchor.constraint(equalToConstant: separatorWidth).isActive = true
separator2.backgroundColor = .black
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(separator)
stackView.addArrangedSubview(label2)
stackView.addArrangedSubview(separator2)
stackView.addArrangedSubview(label3)
label2.widthAnchor.constraint(equalTo: label.widthAnchor).isActive = true
label3.widthAnchor.constraint(equalTo: label2.widthAnchor).isActive = true
self.view.addSubview(stackView)
stackView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
stackView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 30).isActive = true
stackView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 30).isActive = true

Snapkit and UILabel's rotation

I have:
UIView (container)
UIView. subview of (1) - Dark blue in the image below
UIView. subview of (1) - Purple in the image below
UILabel. edges.equalToSuperview()
What I'm trying to accomplish:
The thing is, I want the UILabel to be rotated 3pi/2 (270°). Once I've done the rotation, it isn't placed correctly.
This is how it looks like by setting edges.equalToSuperview() and the 270°rotation:
I've tried this (but it leads to a crash):
myLabel.makeConstraints { make in
make.top.equalTo(containerView.snp.left)
make.right.equalTo(containerView.snp.top)
make.left.equalTo(containerView.snp.bottom)
make.bottom.equalTo(containerView.snp.right)
}
The crash description:
*** Terminating app due to uncaught exception 'NSInvalidLayoutConstraintException', reason: 'Constraint improperly relates anchors of incompatible types: <SnapKit.LayoutConstraint:0x6100000ad8c0#MyClass.swift#250 MyProject.MyLabel:0x7fcc2201ca80.top == UIView:0x7fcc2201bd30.left>'
Any ideas what I could do here?
I have done it using default autolayout and i like that much too. :)
Here is the function.
func makeLabel() {
//Creating stackview
let stackView = UIStackView()
view.addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.alignment = .fill
stackView.distribution = .fillEqually
stackView.axis = .vertical
//Creating blueView
let blueView = UIView()
blueView.backgroundColor = UIColor.darkGray
blueView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(blueView)
blueView.widthAnchor.constraint(equalToConstant: 100).isActive = true
//Creating purpleView
let purpleView = UIView()
purpleView.backgroundColor = UIColor.purple
purpleView.translatesAutoresizingMaskIntoConstraints = false
stackView.addArrangedSubview(purpleView)
stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
stackView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
//Creating rotated label
let label = UILabel()
view.addSubview(label)
label.transform = CGAffineTransform.init(rotationAngle: -CGFloat.pi/2)
label.textColor = UIColor.white
label.text = "This is my Rotated Text"
label.font = UIFont.systemFont(ofSize: 25)
label.translatesAutoresizingMaskIntoConstraints = false
label.centerXAnchor.constraint(equalTo: stackView.centerXAnchor, constant: 0).isActive = true
label.centerYAnchor.constraint(equalTo: stackView.centerYAnchor, constant: 0).isActive = true
}
And here is the output.
Portrait:
Landscape
For anyone interested in elk_cloner's answer using Snapkit:
myLabel.snp.makeConstraints { make in
make.centerX.equalTo(containerView.snp.centerX)
make.centerY.equalTo(containerView.snp.centerY)
}

Resources