Swift- unable to align stack elements with different font sizes - swift

I have 2 UILabels as follows:
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.textColor = Constants.mainFontColor.withAlphaComponent(0.7)
label.translatesAutoresizingMaskIntoConstraints = false
label.isUserInteractionEnabled = false
label.sizeToFit()
return label
}()
private lazy var valueLabel: UILabel = {
let label = UILabel()
label.textColor = Constants.mainFontColor
label.translatesAutoresizingMaskIntoConstraints = false
label.isUserInteractionEnabled = false
label.sizeToFit()
return label
}()
These labels are then placed into a UIStackView:
private lazy var stackView: UIStackView = {
let stack = UIStackView(arrangedSubviews: [titleLabel, valueLabel])
stack.translatesAutoresizingMaskIntoConstraints = false
stack.axis = .horizontal
stack.spacing = 5
stack.alignment = .firstBaseline
addSubview(stack)
return stack
}()
I then create several instances of these e.g.:
private lazy var flightNumber: FuelSheetHeaderField = {
return FuelSheetHeaderField(title: FuelSheetStringsField.flightNumber.title.localized,
value: viewModel.flightNumber, titleFontSize: 17, valueFontSize: 24)
}()
These are then placed into a separate stack view:
private lazy var flightData: UIStackView = {
let stack = UIStackView(arrangedSubviews: [flightNumber, aircraftReg, dateTime, origin])
stack.axis = .horizontal
stack.distribution = .equalSpacing
stack.spacing = Constants.standardHorizontalStackSpacing
return stack
}()
The title labels have font size of 12 and the values have font size 17. Except for one which is customised to have font size 17 and 2 accordingly. I am trying to get all the elements to align along the same base line. I added the following constraint:
titleLabel.firstBaselineAnchor.constraint(equalTo: valueLabel.firstBaselineAnchor),
However the effect is as follows:
Most of the stack elements are aligning but as you can see the first element with the larger font is sitting higher than the second. This is driving me a little crazy. How can I fix it so that all elements in the stack align along the same baseline.

I think you're going to have trouble trying to use baselines across stack views.
One option - not sure if it will work for you - is to put all the labels in a single horizontal stack view, and use .setCustomSpacing() to adjust the spaces between labels.
As an example:
and with Debug -> View Debugging -> Show View Frames:
Here's the code I used to generate that:
class AlignedStackViewController: UIViewController {
let detailsStack: UIStackView = {
let v = UIStackView()
v.axis = .vertical
v.alignment = .leading
v.distribution = .fill
v.spacing = 12
return v
}()
let dataStack: UIStackView = {
let v = UIStackView()
v.axis = .horizontal
v.alignment = .firstBaseline
v.distribution = .fill
v.spacing = 5
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 0.928, green: 0.973, blue: 1.0, alpha: 1.0)
let fdLabel = UILabel()
fdLabel.text = "FLIGHT DETAILS"
detailsStack.addArrangedSubview(fdLabel)
detailsStack.addArrangedSubview(dataStack)
detailsStack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(detailsStack)
// respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// position stack view at 40, 100
detailsStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
detailsStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
])
addLabelPair(with: "#", value: "VS0105", titleFontSize: 17, valueFontSize: 24)
addLabelPair(with: "Reg:", value: "GAAAA", titleFontSize: 12, valueFontSize: 17)
addLabelPair(with: "Departure:", value: "09 Sep 2020", titleFontSize: 12, valueFontSize: 17)
addLabelPair(with: "at", value: "08:34", titleFontSize: 12, valueFontSize: 17)
updateStackSpacing()
}
func updateStackSpacing() -> Void {
// make sure stack has been filled
guard dataStack.arrangedSubviews.count == 8 else {
return
}
// verbose for clarity
let flightNumberLabel = dataStack.arrangedSubviews[1]
let aircraftRegLabel = dataStack.arrangedSubviews[3]
dataStack.setCustomSpacing(12, after: flightNumberLabel)
dataStack.setCustomSpacing(12, after: aircraftRegLabel)
}
func addLabelPair(with title: String, value: String, titleFontSize: CGFloat, valueFontSize: CGFloat) -> Void {
let tLabel = UILabel()
let vLabel = UILabel()
tLabel.font = UIFont.systemFont(ofSize: titleFontSize)
vLabel.font = UIFont.systemFont(ofSize: valueFontSize)
tLabel.textColor = UIColor.black.withAlphaComponent(0.7)
vLabel.textColor = UIColor.black
tLabel.text = title
vLabel.text = value
dataStack.addArrangedSubview(tLabel)
dataStack.addArrangedSubview(vLabel)
}
}

I think, It seems that uiLabel has default padding
And the default padding value depends on the font size.
In spite of sizeToFit, the result is the same

Related

How to make vertical labels bar in Swift?

I would like to make such layout via swift:
I tried to make it in such way:
var buttonArray = [UILabel]()
for (myKey,myValue) in colorDictionary{
buttonArray += [colorButton(withColor: myValue, title: myKey)]
}
let horizontalStack = UIStackView(arrangedSubviews: buttonArray)
horizontalStack.axis = .horizontal
horizontalStack.distribution = .fillEqually
horizontalStack.alignment = .fill
horizontalStack.translatesAutoresizingMaskIntoConstraints = false
horizontalStack.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
let label2 = UILabel()
label2.text = "Label"
label2.backgroundColor = .red
label2.textColor = .white
label2.textAlignment = .center
label2.lineBreakMode = .byCharWrapping
label2.numberOfLines = 0
label2.translatesAutoresizingMaskIntoConstraints = false
label2.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
let mainStackView = UIStackView()
mainStackView.axis = .horizontal
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.addArrangedSubview(label2)
mainStackView.addArrangedSubview(horizontalStack)
mainContainer.addSubview(mainStackView)
NSLayoutConstraint.activate([
mainStackView.topAnchor.constraint(equalTo: mainContainer.topAnchor, constant: 5),
mainStackView.leftAnchor.constraint(equalTo: mainContainer.leftAnchor,
constant: 20),
mainStackView.rightAnchor.constraint(equalTo: mainContainer.rightAnchor,
constant: -20),
mainStackView.heightAnchor.constraint(equalToConstant: 270),
])
where colorButton is:
func colorButton(withColor color:UIColor, title:String) -> UILabel{
let newButton = UILabel()
newButton.backgroundColor = color
newButton.text = title
newButton.textAlignment = .center
newButton.textColor = UIColor.white
return newButton
}
and here is the result which I got:
How I can make all these labels look like the desired image? And also I'm not sure whether label rotation can be done by my method.
What I would do is first get it working without any transformations so it appears as a normal, not rotated setup. Once that is working, you only need to apply a single transformation to the main stack view to get the whole thing rotated. Then finally you can tweak the constraints to get it positioned correctly.
Here is code that works:
let horizontalStack = UIStackView(arrangedSubviews: buttonArray)
horizontalStack.axis = .horizontal
horizontalStack.distribution = .fillEqually
horizontalStack.alignment = .fill
horizontalStack.translatesAutoresizingMaskIntoConstraints = false
let label2 = UILabel()
label2.text = "Label"
label2.backgroundColor = .red
label2.textColor = .white
label2.textAlignment = .center
label2.lineBreakMode = .byCharWrapping
label2.numberOfLines = 0
label2.translatesAutoresizingMaskIntoConstraints = false
let mainStackView = UIStackView()
mainStackView.axis = .vertical
mainStackView.distribution = .equalSpacing
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.addArrangedSubview(label2)
mainStackView.addArrangedSubview(horizontalStack)
mainStackView.transform = CGAffineTransform(rotationAngle: -CGFloat.pi / 2)
mainContainer.addSubview(mainStackView)
NSLayoutConstraint.activate([
mainStackView.centerYAnchor.constraint(equalTo: mainContainer.centerYAnchor),
mainStackView.centerXAnchor.constraint(equalTo: mainContainer.leftAnchor, constant: 40),
// Set the "width", not the "height"
mainStackView.widthAnchor.constraint(equalToConstant: 270),
])
Changes:
I removed the transformation you had for the horizontal stack view and the big label.
I added a single transformation to the main stack view.
I used a vertical, not horizontal, stack view for the main stack.
Updated the properties of the main stack view so the main label fills the area above the other labels.
Updated the constraints. Adjust those to suit your needs.
Note that you need to set the width of the main stack view since the constraint is relative to the untransformed main stack view.

Cell not displaying elements when being reused on a stack that adds a LinkPresentation view

I had this custom view who worked like a charm before i introduce a LinkView for a Metadata
After i introduce a LinkView, since it was inside a stackView i had to remove linkView from superview when preparing for reusable (not sure why tried to redraw layout, but seems this not work with LinkView) the problems shows up when scrolling down elements, seems the data get lost at certain point, curious thing is that it only happens with the reusable element that contains the linkView item, is there any reason for this ? How can i fix it ?
Here is the code i use for the cell
final class TimeLineTableViewCell: UITableViewCell {
var cornerRadius: CGFloat = 6
var shadowOffsetWidth = 0
var shadowOffsetHeight = 3
var shadowColor: UIColor = .gray
var shadowOpacity: Float = 0.3
lazy var containerView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
view.addSubview(stackViewContainer)
let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius)
view.layer.cornerRadius = cornerRadius
view.clipsToBounds = true
view.layer.masksToBounds = false
view.layer.shadowColor = shadowColor.cgColor
view.layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight);
view.layer.shadowOpacity = shadowOpacity
view.layer.shadowPath = shadowPath.cgPath
return view
}()
lazy var stackViewContainer: UIStackView = {
let stack = UIStackView()
stack.axis = .horizontal
stack.alignment = .center
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
stack.spacing = 10.0
stack.addArrangedSubview(profileImage)
stack.addArrangedSubview(stackViewDataHolder)
return stack
}()
lazy var profileImage: UIImageView = {
let image = UIImage()
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
return imageView
}()
lazy var userName: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var tweetInfo: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var tweetText: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
}()
lazy var linkView: LPLinkView = {
let viewer = LPLinkView(frame: CGRect(origin: .zero, size: .init(width: 200, height: 20)))
viewer.translatesAutoresizingMaskIntoConstraints = false
return viewer
}()
lazy var stackViewDataHolder: UIStackView = {
let stack = UIStackView()
stack.axis = .vertical
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fillProportionally
stack.addArrangedSubview(userName)
stack.addArrangedSubview(tweetInfo)
stack.addArrangedSubview(tweetText)
return stack
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override func prepareForReuse() {
linkView.removeFromSuperview()
}
func configure(viewModel: ProfileTweetViewModel) {
tweetInfo.configure(model: viewModel.tweetInfo)
userName.configure(model: viewModel.name)
tweetText.configure(model: viewModel.tweet)
if let metadata = viewModel.linkData {
linkView = LPLinkView(metadata: metadata)
stackViewDataHolder.addArrangedSubview(linkView)
//Tried almost all layoyt options but seems a previous view can't be updated since frame is wrong
}
if let url = viewModel.profilePic {
profileImage.downloadImage(from: url)
}
}
}
private extension TimeLineTableViewCell {
struct Metrics {
static let lateralPadding: CGFloat = 8
}
func constraints() {
NSLayoutConstraint.activate([
stackViewContainer.topAnchor.constraint(equalTo: containerView.topAnchor, constant: Metrics.lateralPadding),
stackViewContainer.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -Metrics.lateralPadding),
stackViewContainer.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: Metrics.lateralPadding),
stackViewContainer.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -Metrics.lateralPadding),
profileImage.heightAnchor.constraint(equalTo: profileImage.widthAnchor, multiplier: 1.0),
profileImage.widthAnchor.constraint(equalToConstant: 50.0),
])
}
func commonInit() {
addSubview(containerView)
backgroundColor = .clear
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -4),
containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -4),
])
constraints()
}
}
Thank you for your time.
The issue was related to .fillProportionally in stackView
since the linkView sometimes renders with 0 height, i just had to use .fill property in stackView in order to show it fully

Can't figure out why my stackviews are not arranging vertically

I have done this many times but this time for some reason won't work the way it usually does. Am I doing something wrong here? I am just trying to get two views into my UIstackView and distribute them vertically. It seems to keep overlapping and going all over the place. At one point it was only even showing one view.
My viewdidload():
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red
view.addSubview(headerView)
view.addSubview(contentView)
contentView.addSubview(contentStack)
headerView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.30).isActive = true
headerView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
headerView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
headerView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
contentView.heightAnchor.constraint(equalTo: self.view.heightAnchor, multiplier: 0.70).isActive = true
contentView.widthAnchor.constraint(equalTo: self.view.widthAnchor,multiplier: 0.90).isActive = true
contentView.topAnchor.constraint(equalTo: headerView.bottomAnchor,constant: 20).isActive = true
contentView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
}
My Views and Labels:
fileprivate lazy var headerView : UIView = {
var view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .black
return view
}()
fileprivate lazy var contentView : UIView = {
var view = UIView()
view.backgroundColor = .lightGray
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
fileprivate lazy var contentStack : UIStackView = {
var stack = UIStackView(arrangedSubviews: [EarningsView,ListingsView,])
stack.translatesAutoresizingMaskIntoConstraints = true
stack.distribution = .fillEqually
stack.alignment = .fill
stack.axis = .vertical
// stack.spacing = 5
return stack
}()
fileprivate lazy var EarningsView : UIView = {
let EarningsView = UIView()
EarningsView.translatesAutoresizingMaskIntoConstraints = false
EarningsView.backgroundColor = .blue
EarningsView.addSubview(EarningsLabel)
EarningsView.addViewBorder(borderColor: UIColor.black.cgColor, borderWith: 0.5, borderCornerRadius: 0.0)
return EarningsView
}()
fileprivate lazy var EarningsLabel : UILabel = {
let EarningsLabel = UILabel()
EarningsLabel.translatesAutoresizingMaskIntoConstraints = false
let earningsText = NSAttributedString(string: "My Earnings", attributes: self.stringAttrib)
EarningsLabel.attributedText = earningsText
EarningsLabel.textColor = .black
EarningsLabel.backgroundColor = .white
EarningsLabel.textAlignment = .center
return EarningsLabel
}()
fileprivate lazy var ListingsView : UIView = {
let ListingsView = UIView()
ListingsView.translatesAutoresizingMaskIntoConstraints = false
ListingsView.addSubview(ListingLabel)
ListingsView.addViewBorder(borderColor: UIColor.black.cgColor, borderWith: 0.5, borderCornerRadius: 0.0)
ListingsView.backgroundColor = .red
return ListingsView
}()
fileprivate lazy var ListingLabel : UILabel = {
let ListingLabel = UILabel()
ListingLabel.translatesAutoresizingMaskIntoConstraints = false
let listingText = NSAttributedString(string: "My Listing", attributes: self.stringAttrib)
ListingLabel.attributedText = listingText
return ListingLabel
}()
This is driving me crazy because I have done it so many times before and now I have spent atleast 6 hours on this little part trying to figure it out. Of course I could just create a whole new viewcontroller but I just want to figure this out.
EarningsView, EarningsLabel, ListingsView, ListingLabel have
translatesAutoresizingMaskIntoConstraints = false
But they have no constraints added to replace the Autoresizing constraints, so they just act goofy and go up to the top left. I've seen stuff like this before. On my stuff. Either autosize or put in constraints.

Altered column width in horizontal UIStackview

I have a 4 x 1 UILabel matrix in a horizontal stackview I would like columns 1 and 3 to be the same width BUT narrower than columns 2 and 4. I have tried .fillproportionally, and others. I understood that this was possible... however, a solution evades me and Google hasn't turned anything up. Any help or a point in the right direction would be helpful. Thank you. I am not using Storyboards.
You can create your grid:
as you described:
C1-w == 1/3 of C2-w
C3-w == C1-w
C4-w == C2-w
pretty much with that description:
with the stack view .distribution = .fill
Here's a complete example:
class ColumnStackViewController: UIViewController {
let outerStack: UIStackView = {
let v = UIStackView()
v.translatesAutoresizingMaskIntoConstraints = false
v.axis = .vertical
v.alignment = .fill
v.distribution = .fill
v.spacing = 8
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
// create "header row" stack view
let headerRowStack = UIStackView()
headerRowStack.axis = .horizontal
headerRowStack.spacing = 4
// create 4 labels for header row
let headerC1 = UILabel()
let headerC2 = UILabel()
let headerC3 = UILabel()
let headerC4 = UILabel()
headerC1.text = "C1"
headerC2.text = "C2"
headerC3.text = "C3"
headerC4.text = "C4"
[headerC1, headerC2, headerC3, headerC4].forEach { v in
// give each "header" label a background color, so we can see the frames
v.backgroundColor = .yellow
v.textAlignment = .center
headerRowStack.addArrangedSubview(v)
}
NSLayoutConstraint.activate([
// constrain c1 width to 1/3 of c2 width
headerC1.widthAnchor.constraint(equalTo: headerC2.widthAnchor, multiplier: 1.0 / 3.0),
// constrain c3 width equal to c1 width
headerC3.widthAnchor.constraint(equalTo: headerC1.widthAnchor),
// constrain c4 width equal to c2 width
headerC4.widthAnchor.constraint(equalTo: headerC2.widthAnchor),
])
outerStack.addArrangedSubview(headerRowStack)
let c1Vals = ["HOLDING", "BOOK", "P/L"]
let c3Vals = ["PAID", "MARKET", "WEIGHT"]
for i in 0..<c1Vals.count {
// create a "row" stack view
let rowStack = UIStackView()
rowStack.axis = .horizontal
rowStack.spacing = headerRowStack.spacing
// add it to outer stack view
outerStack.addArrangedSubview(rowStack)
let rowC1 = UILabel()
let rowC2 = UILabel()
let rowC3 = UILabel()
let rowC4 = UILabel()
rowC1.text = c1Vals[i]
rowC3.text = c3Vals[i]
rowC2.text = "row \(i+1) c2 data"
rowC4.text = "row \(i+1) c4 data"
[rowC1, rowC2, rowC3, rowC4].forEach { v in
// give each row-label a border
v.layer.borderColor = UIColor.red.cgColor
v.layer.borderWidth = 0.5
// set the font
v.font = UIFont.systemFont(ofSize: 14.0, weight: .light)
// add it to the row stack view
rowStack.addArrangedSubview(v)
}
// constrain each row-label width to the header-row label width
for (hLabel, rowLabel) in zip([headerC1, headerC2, headerC3, headerC4], [rowC1, rowC2, rowC3, rowC4]) {
rowLabel.widthAnchor.constraint(equalTo: hLabel.widthAnchor).isActive = true
}
}
view.addSubview(outerStack)
// respect safe area
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain outer stack view to Top / Leading / Trailing with 20-pt "padding"
outerStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
outerStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
outerStack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
])
}
}
which produces this result:
Note: you'll have to use a pretty small font to fit that layout on a small device:
This is all i ended needing v1.widthAnchor.constraint(equalTo: v2.widthAnchor, multiplier: 0.5, constant: 0).isActive = true v3.widthAnchor.constraint(equalTo: v1.widthAnchor ).isActive = true v4.widthAnchor.constraint(equalTo: v2.widthAnchor ).isActive = true

Programmatically create stack view

I am trying to create a date component by using a stack view programmatically. If user enters wrong date an error label will display message accordingly.Its working fine if I create it through storyboard, but when I use my programmatically created component which has added all elements in a stack view. I am not able to see error label.
I verified the autolayout I've added in storyboard and in my component class, both look similar. Here is code for my component.
class CustomDateView: UIView {
// MARK: - Variable
private let dayTextField: UITextField = {
let inputField = UITextField()
inputField.borderStyle = .none
inputField.layer.cornerRadius = 8.0
inputField.layer.borderColor = UIColor.darkGray.cgColor
inputField.backgroundColor = UIColor.blue
inputField.textAlignment = .center
inputField.tag = 0
inputField.translatesAutoresizingMaskIntoConstraints = false
return inputField
}()
private let monthTextField: UITextField = {
let inputField = UITextField()
inputField.borderStyle = .none
inputField.layer.cornerRadius = 8.0
inputField.layer.borderColor = UIColor.darkGray.cgColor
inputField.backgroundColor = UIColor.blue
inputField.textAlignment = .center
inputField.tag = 1
inputField.translatesAutoresizingMaskIntoConstraints = false
return inputField
}()
private let yearTextField: UITextField = {
let inputField = UITextField()
inputField.borderStyle = .none
inputField.layer.cornerRadius = 8.0
inputField.layer.borderColor = UIColor.darkGray.cgColor
inputField.backgroundColor = UIColor.blue
inputField.textAlignment = .center
inputField.tag = 2
inputField.translatesAutoresizingMaskIntoConstraints = false
return inputField
}()
private let errorLabel: UILabel = {
let errorLabel = UILabel()
errorLabel.textColor = .red
errorLabel.textAlignment = .center
errorLabel.numberOfLines = 0
errorLabel.translatesAutoresizingMaskIntoConstraints = false
return errorLabel
}()
private let monthSeparator: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let yearSeparator: UILabel = {
let label = UILabel()
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private let horizontalStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 16.0
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
private let verticalStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fillProportionally
stackView.spacing = 8.0
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
// MARK: - Initialisers
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
// MARK: - Private Functions
private func setup() {
self.horizontalStackView.addArrangedSubview(self.dayTextField)
self.horizontalStackView.addArrangedSubview(self.monthSeparator)
self.horizontalStackView.addArrangedSubview(self.monthTextField)
self.horizontalStackView.addArrangedSubview(self.yearSeparator)
self.horizontalStackView.addArrangedSubview(self.yearTextField)
self.verticalStackView.addArrangedSubview(self.horizontalStackView)
self.verticalStackView.addArrangedSubview(self.errorLabel)
self.addSubview(self.verticalStackView)
self.translatesAutoresizingMaskIntoConstraints = false
let selfType = type(of: self)
NSLayoutConstraint.activate([
self.dayTextField.heightAnchor.constraint(equalToConstant: 48.0),
self.dayTextField.widthAnchor.constraint(equalToConstant: 62.0),
self.monthTextField.widthAnchor.constraint(equalToConstant: 62.0),
self.monthSeparator.widthAnchor.constraint(equalToConstant: 14.0),
self.yearSeparator.widthAnchor.constraint(equalToConstant: 14.0)
])
NSLayoutConstraint.activate([
self.verticalStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0.0),
self.verticalStackView.topAnchor.constraint(equalTo: self.topAnchor, constant: 0.0),
self.bottomAnchor.constraint(equalTo: self.verticalStackView.bottomAnchor),
self.trailingAnchor.constraint(equalTo: self.verticalStackView.trailingAnchor)
])
}
}
It render view correctly but after setting error label stack view won't grow to display the text.I have given fixed width to my separators and textfield's cause I want them to be of that exact width and height.
Is there any mistakes I'm making while applying autolayout in here.