How do I make the following image in swift programmatically - swift

How do I make the this image in swift programmatically, when I tried it myself, I was able to do the following
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.sectionInset = UIEdgeInsets(top: 30, left: 30, bottom: 10, right: 30)
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 15
collectionViews = UICollectionView(frame: .zero, collectionViewLayout: layout)
guard let collectionView = collectionViews else { return }
scrollView.addSubview(collectionView)
collectionView.dataSource = self
collectionView.delegate = self
collectionView.delaysContentTouches = true
collectionView.isScrollEnabled = false
collectionView.showsHorizontalScrollIndicator = false
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(MenusCell.self, forCellWithReuseIdentifier: MenusCell.identifier)
collectionView.backgroundColor = .red
collectionView.top(collectionViewTop?.bottomAnchor ?? scrollView.topAnchor, 2)
collectionView.left(view.leftAnchor, 0)
collectionView.right(view.rightAnchor, 0)
collectionView.bottom(view.bottomAnchor, -50)
please help me, thank you

Related

Swift CollectionView items do not scroll

my CollectionView's items do not scroll, when I scroll down the first items stay at their place, without any change, you can see what I mean on the image: collectionview
Here is the code of the collectionView:
func setUpCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 20, left: 15, bottom: 20, right: 15)
layout.itemSize = CGSize(width: 100, height: 100)
myCollectionView = UICollectionView(frame: self.contentView.frame, collectionViewLayout: layout)
myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
myCollectionView?.backgroundColor = UIColor.clear
myCollectionView?.allowsSelection = true
myCollectionView?.dataSource = self
myCollectionView?.delegate = self
contentView.addSubview(myCollectionView ?? UICollectionView())
myCollectionView?.register(SpendingCell.self, forCellWithReuseIdentifier: "Spending")
myCollectionView?.translatesAutoresizingMaskIntoConstraints = false
myCollectionView?.topAnchor.constraint(equalTo: contentView.safeAreaLayoutGuide.topAnchor, constant: 10).isActive = true
myCollectionView?.widthAnchor.constraint(equalTo: contentView.widthAnchor).isActive = true
myCollectionView?.heightAnchor.constraint(equalToConstant: 350).isActive = true
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Spending", for: indexPath) as! SpendingCell
cell.setUpSpending(cost: categories[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 23
}
and the collectionView cell:
class SpendingCell: UICollectionViewCell {
let stackView = UIStackView()
let SpendingButton = UIImageView()
let nameLabel = UILabel()
let sumLabel = UILabel()
override init(frame: CGRect) {
super.init(frame: frame)
contentView.addSubview(stackView)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setUpSpending(cost: Spending) {
stackView.alignment = .center
stackView.axis = .vertical
stackView.distribution = .fillProportionally
stackView.spacing = 5
stackView.addArrangedSubview(SpendingButton)
stackView.addArrangedSubview(nameLabel)
//Constraints
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
stackView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
stackView.widthAnchor.constraint(equalToConstant: 100).isActive = true
stackView.heightAnchor.constraint(equalToConstant: 100).isActive = true
SpendingButton.image = cost.image
SpendingButton.contentMode = .scaleAspectFit
SpendingButton.layer.cornerRadius = 40
SpendingButton.layer.masksToBounds = true
SpendingButton.translatesAutoresizingMaskIntoConstraints = false
SpendingButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
SpendingButton.heightAnchor.constraint(equalToConstant: 80).isActive = true
nameLabel.text = cost.title
nameLabel.textAlignment = .center
nameLabel.textColor = .black
nameLabel.font = UIFont.boldSystemFont(ofSize: 10)
nameLabel.translatesAutoresizingMaskIntoConstraints = false
nameLabel.widthAnchor.constraint(equalToConstant: 100).isActive = true
nameLabel.heightAnchor.constraint(equalToConstant: 15).isActive = true
}
}
Could someone please help me how to change that? Thanks in advance!
func makeKeyboardCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
layout.itemSize = CGSize(width: 70, height: 40)
layout.scrollDirection = .vertical
keyboardCollectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
contentView.addSubview(keyboardCollectionView)
keyboardCollectionView.snp.makeConstraints({ make in
make.top.equalTo(vocabularyLabel.snp.bottom).inset(-5)
make.left.equalToSuperview().inset(40)
make.right.equalToSuperview().inset(50)
make.height.equalTo(210)
})
keyboardCollectionView.backgroundColor = .clear
keyboardCollectionView.showsVerticalScrollIndicator = false
keyboardCollectionView.register(KeyboardCollectionViewCell.self, forCellWithReuseIdentifier: KeyboardCollectionViewCell.identifier)
keyboardCollectionView.dataSource = self
keyboardCollectionView.delegate = self
}

Is it possible to change y position of a view for smaller screen size?

I am working on a UICollectionview and setting my collectionView as below,
var isListView = false
var collectionView: UICollectionView?
func collectionViewSetUp() {
collectionView?.showsVerticalScrollIndicator = false
collectionView?.showsHorizontalScrollIndicator = false
collectionView = UICollectionView(frame: .zero,collectionViewLayout: gridLayout)
collectionView?.translatesAutoresizingMaskIntoConstraints = false
collectionView?.dataSource = self
collectionView?.delegate = self
collectionView?.allowsMultipleSelection = true
collectionView?.allowsSelection = true
collectionView?.isUserInteractionEnabled = true
collectionView?.register(collectionViewListLayoutCell.self, forCellWithReuseIdentifier: "collectionViewListLayoutCell")
collectionView?.register(collectionViewCell.self, forCellWithReuseIdentifier: "collectionViewCell")
And i have two layouts as,
lazy var listLayout: UICollectionViewFlowLayout = {
//Assign a new cell for list view
let listLayout = UICollectionViewFlowLayout()
listLayout.scrollDirection = .vertical
listLayout.sectionInset = UIEdgeInsets(top: 4, left: 12, bottom: 4, right: 12)
listLayout.itemSize = CGSize(width: view.frame.size.width/1.12, height: 98)
listLayout.minimumInteritemSpacing = 1
listLayout.minimumLineSpacing = 1
folderCollectionView = UICollectionView(frame: .zero,collectionViewLayout: listLayout)
view.addSubview(collectionView!)
isListView = true
return listLayout
}()
and for Grid-
lazy var gridLayout: UICollectionViewFlowLayout = {
let gridLayout = UICollectionViewFlowLayout()
gridLayout.scrollDirection = .vertical
gridLayout.sectionInset = UIEdgeInsets(top: 5, left: 10, bottom: 15, right: 10)
gridLayout.itemSize = CGSize(width: view.frame.size.width/3.5, height: view.frame.size.width/2.3)
gridLayout.minimumInteritemSpacing = 3
gridLayout.minimumLineSpacing = 9
folderCollectionView = UICollectionView(frame: .zero,collectionViewLayout: gridLayout)
view.addSubview(folderCollectionView!)
isListView = false
return gridLayout
}()
Here Setting viewDidLayoutSubViews,
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView?.translatesAutoresizingMaskIntoConstraints = false
collectionView?.backgroundColor = appBackgroundColor
collectionView?.dataSource = self
collectionView?.delegate = self
collectionView?.frame = CGRect(x: 11, y: 162, width: self.view.frame.width-20, height: self.view.frame.height-165)
}
On the UIButton action i am just switching my layouts and refreshing my collectionView.
Now as I have set x and y position there, the space above UICollectionview is looking too much for older devices like iphone-8 and older. But in devices like iphone x and newer it is looking fine.
So how can i adjust it for older devices, not having top notch like newer?
Is it possible to do that?
Here i am not setting NSLayoutConstraints for collectionView.
Problem that i am facing with setting constraints to my collectioView is that my collectionView is not changing the layout from grid to list.

CollectionView Cell Changing Size when screen reloads

I am creating a screen where the user can search for films and the results load in a collection View, everything loads perfectly but in the simulator when I clicked "command, shift, A" to change to light mode to make sure the colours would adapt correctly the Cells randomly changed size to full screen instead of what I have set.
This also happens when I leave the application for the home page and then click back into the app. I am creating everything programmatically so would need answer this way please.
Below is the code from my custom cell:
import UIKit
class FavouritesCell: UICollectionViewCell {
static let identifier = "FavouritesCell"
let movieTitle: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.lineBreakMode = .byWordWrapping
label.textColor = .secondaryLabel
//label.text = "Title"
label.adjustsFontSizeToFitWidth = true
label.textAlignment = .center
label.font = label.font.withSize(12)
label.minimumScaleFactor = 0.75
return label
}()
let image : UIImageView = {
let image = UIImageView()
image.clipsToBounds = true
image.translatesAutoresizingMaskIntoConstraints = false
//image.backgroundColor = .yellow
image.layer.cornerRadius = 10.0
return image
}()
let cancelItem : UILabel = {
let label = UILabel()
label.layer.borderWidth = 2.0
label.layer.borderColor = UIColor.systemGray.cgColor
label.text = "X"
label.textAlignment = .center
label.layer.cornerRadius = 15
//label.isHidden = true
return label
}()
override init(frame: CGRect) {
super.init(frame: .zero)
contentView.addSubview(image)
contentView.addSubview(movieTitle)
contentView.addSubview(cancelItem)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
image.frame = CGRect(x: 0, y: 25, width: contentView.width, height: contentView.height - 30 )
movieTitle.frame = CGRect(x: 0, y: 0, width: contentView.width, height: 25)
cancelItem.frame = CGRect(x: image.right - 25, y: image.top , width: 25, height: 25)
}
}
Here is the code from the view controller in relation to the collectionView:
private let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumLineSpacing = 2
layout.minimumInteritemSpacing = 2
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
collectionView.translatesAutoresizingMaskIntoConstraints = false
collectionView.register(FavouritesCell.self, forCellWithReuseIdentifier: FavouritesCell.identifier)
collectionView.clipsToBounds = true
collectionView.backgroundColor = UIColor.systemBackground
return collectionView
}()
NSLayoutConstraint.activate([
searchText.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
searchText.heightAnchor.constraint(equalToConstant: 50),
searchText.leadingAnchor.constraint(equalTo: view.leadingAnchor),
searchText.trailingAnchor.constraint(equalTo: view.trailingAnchor),
collectionView.topAnchor.constraint(equalTo: searchText.bottomAnchor),
collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (view.width / 3) - 4, height: (view.width / 2) - 2 )
}
image of CollectionView working normally
After the screen has been reloaded
Try to give your imageView a fixed height and fixed width and try it again, It will work

How do I make a UICollectionView transparent?

I have tried virtually (literally?) everything to make a horizontal collection view transparent which is overlaid on a map view.
This is my collection view:
fileprivate let restaurantCollection : UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
let restaurant = UICollectionView(frame: .zero, collectionViewLayout: layout)
restaurant.decelerationRate = .fast
restaurant.backgroundView = nil
restaurant.layer.backgroundColor = UIColor.clear.cgColor
restaurant.backgroundColor = .clear
restaurant.translatesAutoresizingMaskIntoConstraints = false
restaurant.register(MapCell.self, forCellWithReuseIdentifier: "Cell")
return restaurant
}()
As you can see it has a clear background, clear layer and the background view is nil.
And the cell is transparent as well:
func setupView() {
contentView.backgroundColor = UIColor.clear.withAlphaComponent(0)
contentView.addSubview(cellBackground)
cellBackground.translatesAutoresizingMaskIntoConstraints = false
cellBackground.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
cellBackground.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
cellBackground.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
cellBackground.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
}
I also added a view to the cell "backgroundView" that's pinned with constant 0 to all sides. And this too is clear.
lazy var cellBackground : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width, height: 220))
view.clipsToBounds = true
view.backgroundColor = .clear
view.layer.backgroundColor = UIColor.clear.cgColor
return view
}()
And after all that effort, the collection view still has a white background
View hierarchy: Here is the view that is still white
You need to make sure that you are setting backgroundColor to clear
self.collectionView.backgroundColor = UIColor.clear
self.collectionView.backgroundView = UIView.init(frame: CGRect.zero)
For Modern List Layout CollectionViews:
UICollectionLayoutListConfiguration.backgroundColor = .clear
UICollectionViewListCell.backgroundConfiguration = .clear()

UIStackView stretching out sub view aligning it

I'm trying to lay out a StackView programatically, the effect I would like to achieve is
but instead I am getting
I do not understand why the loadingDotView is stretching to fill up all the space?
let loadingDotView: UIView = {
let ldv = UIView()
ldv.backgroundColor = .white
ldv.alpha = 0
ldv.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
ldv.layer.cornerRadius = 10
ldv.layer.masksToBounds = true
ldv.translatesAutoresizingMaskIntoConstraints = false
return ldv
}()
let dotsStackView: UIStackView = {
let stackView = UIStackView()
stackView.axis = .horizontal
stackView.distribution = .equalSpacing
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
Setup code...
view.addSubview(dotsStackView)
NSLayoutConstraint.activate([
dotsStackView.heightAnchor.constraint(equalToConstant: 20),
dotsStackView.widthAnchor.constraint(equalToConstant: 100),
dotsStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
dotsStackView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
dotsStackView.addArrangedSubview(loadingDotView)
dotsStackView.addArrangedSubview(loadingDotView)
dotsStackView.addArrangedSubview(loadingDotView)
This ( closure )
let loadingDotView: UIView = {
let ldv = UIView()
ldv.backgroundColor = .white
ldv.alpha = 0
ldv.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
ldv.layer.cornerRadius = 10
ldv.layer.masksToBounds = true
ldv.translatesAutoresizingMaskIntoConstraints = false
return ldv
}()
returns same object every access so only one appears , make it ( computed property ) to create a new one every access
var loadingDotView: UIView {
let ldv = UIView()
ldv.backgroundColor = .white
ldv.alpha = 0
ldv.frame = CGRect(x: 0, y: 0, width: 20, height: 20)
ldv.layer.cornerRadius = 10
ldv.layer.masksToBounds = true
ldv.translatesAutoresizingMaskIntoConstraints = false
return ldv
}
And add
stackView.spacing = 20
stackView.distribution = .fillEqually