Autlo Layout issue - swift

Set programatacally autlo layout to UIView but not set height constraint. I can't identify what is issue.
let viewSep = UIView()
viewSep.backgroundColor = UIColor.red
viewSep.translatesAutoresizingMaskIntoConstraints = false
viewInner.addSubview(viewSep)
viewSep.leftAnchor.constraint(equalTo: viewInner.leftAnchor, constant: 10).isActive = true
viewSep.topAnchor.constraint(equalTo: lblDate.bottomAnchor, constant: 5).isActive = true
viewSep.rightAnchor.constraint(equalTo: viewInner.rightAnchor, constant: -10).isActive = true
viewSep.heightAnchor.constraint(equalToConstant: 21)

Related

Can't set specific spacing when using UICollectionViewFlowLayout.automaticSize

I'm trying to recreate pinterest UI, basically auto height for cell base on photo height.
I'm already able to make it height dynamic but the spacing for each cell is weird, it keeps auto set my cell spacing like this:
This is the code I used for collectionView:
func setupCollectionView() {
let layout2: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
let width = view.frame.size.width * 0.9
collectionViewParent = UICollectionView(frame: .zero, collectionViewLayout: layout2)
collectionViewParent.backgroundColor = .red
view.addSubview(collectionViewParent)
collectionViewParent.translatesAutoresizingMaskIntoConstraints = false
collectionViewParent.dataSource = self
collectionViewParent.delegate = self
collectionViewParent.register(LoansCell.self, forCellWithReuseIdentifier: "cellLoan")
collectionViewParent.register(FirstRowCollectionViewCell.self, forCellWithReuseIdentifier: "cellFirst")
collectionViewParent.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
collectionViewParent.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -20).isActive = true
collectionViewParent.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
collectionViewParent.widthAnchor.constraint(equalToConstant: width).isActive = true
if let flowLayout = collectionViewParent.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
flowLayout.minimumLineSpacing = 5
flowLayout.minimumInteritemSpacing = 5
flowLayout.scrollDirection = .vertical
}
}
For the cell, I just put everything in a UIView:
addSubview(view) //view is a uiview
view.translatesAutoresizingMaskIntoConstraints = false
view.topAnchor.constraint(equalTo: topAnchor).isActive = true
view.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
view.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
view.widthAnchor.constraint(equalToConstant: ((UIScreen.main.bounds.width * 0.8)/2)).isActive = true
view.addSubview(labelEligible)
labelEligible.topAnchor.constraint(equalTo: view.topAnchor, constant: 10).isActive = true
labelEligible.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
view.addSubview(imageView)
imageView.topAnchor.constraint(equalTo: labelEligible.bottomAnchor, constant: 20).isActive = true
imageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
imageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
imageView.heightAnchor.constraint(equalToConstant: 100).isActive = true
imageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
addSubview(labelPrice)
labelPrice.topAnchor.constraint(equalTo: imageView.bottomAnchor, constant: 20).isActive = true
labelPrice.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
view.addSubview(labelDescription)
labelDescription.topAnchor.constraint(equalTo: labelPrice.bottomAnchor, constant: 20).isActive = true
labelDescription.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
labelDescription.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10).isActive = true
view.addSubview(labelPayUpTo)
labelPayUpTo.topAnchor.constraint(equalTo: labelDescription.bottomAnchor, constant: 20).isActive = true
labelPayUpTo.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -10).isActive = true
labelPayUpTo.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
let finalConstraint = labelPayUpTo.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10)
finalConstraint.isActive = true
finalConstraint.priority = UILayoutPriority(rawValue: 999)

Creating scrollview with 20 labels with programmatically in Swift

I am pretty new in Programming Swift so I am trying to achieve a scrollable task includes 20 labels inside. I made it with storyboard but programmatically I failed..
Thanks in advance, a green view background and 20 labels orange. Can anyone show me how ?
So i am not very fond of advertising, but raywenderlich has an awesome tutorial on how to do this. It is quite easy, but it comes down to a scrollable view and a tableview with navigation links.
https://www.raywenderlich.com/5662524-your-second-ios-and-swiftui-app
Again, i am not advertising, just sharing some videos that really helped me understand Swift!
And for answering your question:
Use
Scrollview { put here your to-do code
} end of body
There is your scrollable view with all the labels!
Below code will print your label 20 times with scrollview.
import UIKit
class ViewController: UIViewController {
let scrollView = UIScrollView()
var a = 0
var COnstant: CGFloat = 20
override func viewDidLoad() {
super.viewDidLoad()
scrollView.translatesAutoresizingMaskIntoConstraints = false
scrollView.backgroundColor = .green
self.view.addSubview(scrollView)
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
while a<20 {
let label = UILabel()
label.backgroundColor = .orange
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
label.text = "I'm label \(a)"
label.textAlignment = .center
scrollView.addSubview(label)
label.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0).isActive = true
label.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor, constant: 0).isActive = true
label.widthAnchor.constraint(equalTo: scrollView.widthAnchor, constant: 0).isActive = true
label.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: COnstant).isActive = true
COnstant += 40
a = a+1
if a >= 20 { // if bottomanchor is not set then our scroll view doesnot work
label.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0).isActive = true
}
}
}
}

Trying to get frame.height of one of the 2 views, that filled equally inside of a stackview

I have 2 views inside a vertical stackview(bothalf and tophalf). Their constraints dependent on that stackview.I have a horizontal stackview(containerStackView3) inside the botHalfView. Its constraints leading,trailing and height dependent on botHalfView. In debugging window i can see also on console, height of the bothalfview.frame.height=0 which i added as a constraint for horizontalstackview. Therefore horizontalstackview inside the bothalfview not showing any dimension. To which constraint i should assign the horizontalstackview's height? Or any other solution to this?
let containerStackView3 = UIStackView()
containerStackView3.translatesAutoresizingMaskIntoConstraints = false
containerStackView3.axis = .vertical
containerStackView3.distribution = .fillEqually
containerStackView3.spacing = 1
//adding views
containerStackView1.addArrangedSubview(botHalfView2)
botHalfView2.addSubview(containerStackView3)
//constraints bothalfview
botHalfView2.bottomAnchor.constraint(equalTo:
containerStackView1.bottomAnchor, constant: 0).isActive = true
botHalfView2.leadingAnchor.constraint(equalTo:
containerStackView1.leadingAnchor, constant: 0).isActive = true
botHalfView2.trailingAnchor.constraint(equalTo:
containerStackView1.trailingAnchor, constant: 0).isActive = true
// Constraints of the stack view inside the bothalfview
containerStackView3.leadingAnchor.constraint(equalTo:
botHalfView2.leadingAnchor, constant: 0).isActive = true
containerStackView3.trailingAnchor.constraint(equalTo:
botHalfView2.trailingAnchor, constant: 0).isActive = true
containerStackView3.bottomAnchor.constraint(equalTo:
botHalfView2.bottomAnchor, constant: 0).isActive = true
containerStackView3.heightAnchor.constraint(equalToConstant:botHalfView2.frame.height).isActive = true
If you need container heigh same as bot half then do this
// Constraints of the stack view inside the bothalfview
containerStackView3.leadingAnchor.constraint(equalTo:
botHalfView2.leadingAnchor, constant: 0).isActive = true
containerStackView3.trailingAnchor.constraint(equalTo:
botHalfView2.trailingAnchor, constant: 0).isActive = true
containerStackView3.bottomAnchor.constraint(equalTo:
botHalfView2.bottomAnchor, constant: 0).isActive = true
containerStackView3.topAnchor(equalTo:
botHalfView2.topAnchor, constant: 0).isActive = true

UIImage Aspect Fill and clipsToBounds

I want to set an image to a UIImage, but as soon as I set it it the UIImageView gets bigger and goes over other elements.
There is a solution provided here:
Crop UIImage to fit a frame image
But I can not get it to work, I set the properties like in the solution provided.
Maybe somebody can have a look and help me:
Without setting the image:
After setting the image:
class Cell: UICollectionViewCell, CollectionViewCellConfigurable {
var image = UIImageView()
var dateDay = UILabel()
var dateMonth = UILabel()
var title = UILabel()
lazy private var dateContainer: UIView = {
let v = UIView()
v.sv(dateDay, dateMonth)
dateDay.heightAnchor.constraint(equalTo: self.dateMonth.heightAnchor, multiplier: 1).isActive = true
dateDay.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 5).isActive = true
dateDay.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -5).isActive = true
dateDay.topAnchor.constraint(equalTo: v.topAnchor, constant: 15).isActive = true
dateDay.bottomAnchor.constraint(equalTo: dateMonth.topAnchor, constant: -5).isActive = true
dateMonth.heightAnchor.constraint(equalTo: self.dateDay.heightAnchor, multiplier: 1).isActive = true
dateMonth.leadingAnchor.constraint(equalTo: v.leadingAnchor, constant: 5).isActive = true
dateMonth.trailingAnchor.constraint(equalTo: v.trailingAnchor, constant: -5).isActive = true
dateMonth.topAnchor.constraint(equalTo: dateDay.bottomAnchor, constant: 5).isActive = true
// dateMonth.bottomAnchor.constraint(greaterThanOrEqualTo: v.bottomAnchor, constant: -5).isActive = true
return v
}()
lazy private var container: UIView = {
return UIView()
}()
func configureCellAtIndexPath(item: Journaling) {
self.image.image = UIImage.baliBeach
self.image.backgroundColor = .green
self.dateDay.text = "16"
self.dateMonth.text = "May"
self.title.text = "Text visible"
}
override init(frame: CGRect) {
super.init(frame:frame)
setUpLayout()
additionalSetUp()
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func additionalSetUp() {
backgroundColor = .clear
let colorText: UIColor = .grau
dateDay.textColor = colorText
dateMonth.textColor = colorText
title.textColor = colorText
dateDay.textAlignment = .center
dateMonth.textAlignment = .center
title.textAlignment = .center
image.contentMode = .scaleAspectFill
image.clipsToBounds = true
image.autoresizesSubviews = true
}
func setUpLayout() {
sv(dateContainer, container)
container.sv(image,title)
dateContainer.widthAnchor.constraint(equalToConstant: 45).isActive = true
// dateContainer.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.15).isActive = true
dateContainer.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 0).isActive = true
dateContainer.trailingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
dateContainer.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
dateContainer.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
// container.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.5).isActive = true
container.leadingAnchor.constraint(equalTo: dateContainer.trailingAnchor, constant: 0).isActive = true
container.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 0).isActive = true
container.topAnchor.constraint(equalTo: self.topAnchor, constant: 0).isActive = true
container.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: 0).isActive = true
image.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 5).isActive = true
image.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: -5).isActive = true
image.topAnchor.constraint(equalTo: self.topAnchor, constant: 15).isActive = true
image.bottomAnchor.constraint(equalTo: title.topAnchor, constant: -5).isActive = true
title.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true
title.trailingAnchor.constraint(equalTo: container.trailingAnchor, constant: 0).isActive = true
title.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 5).isActive = true
title.bottomAnchor.constraint(equalTo: container.bottomAnchor, constant: 0).isActive = true
}
}
You need to higher vertical compression priority of the title label as the imageView is equal it = 750 , so it occupies the space
title.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 751), for: .vertical)

How to constrain an object to full screen

I want to know how to code an imageview to the full screen programmatically. Right now I know how to code an object to a specific size and position programmatically but I want to know how to get this object in the full screen no matter what device is being used.
FIRE.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
FIRE.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
FIRE.widthAnchor.constraint(equalToConstant: 400).isActive = true
FIRE.heightAnchor.constraint(equalToConstant: 700).isActive = true
FIRE.translatesAutoresizingMaskIntoConstraints = false
I'm assuming your object is FIRE and the parent view is view. You can do it with constraints as follows.
FIRE.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
FIRE.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true
FIRE.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
FIRE.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
FIRE.translatesAutoresizingMaskIntoConstraints = false
Or you could do it using the auto-resizing mask
FIRE.frame = view.bounds
FIRE.autoresizingMask = [.flexibleWidth, .flexibleHeight]
Goal is to set leading, trailing, top and bottom constraints of your UIView equal to leading, trailing, top and bottom constraints of its superview
FIRE.translatesAutoresizingMaskIntoConstraints = false
FIRE.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 0).isActive = true
FIRE.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 0).isActive = true
FIRE.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true
FIRE.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0).isActive = true