How to get all UICollectionViewCells to share the same height? - ios

I have a UICollectionView where the Cell's do not fill their vertical space. What adjustment should I make to ensure each cell fills up the entire cell area? Or at least all share the same height for the row they are on?
Here is the Storyboard
UICollectionViewFlowLayout
class AddServiceFlowLayout: UICollectionViewFlowLayout {
let cellsPerRow: Int
init(cellsPerRow: Int, minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
self.cellsPerRow = cellsPerRow
super.init()
self.minimumInteritemSpacing = minimumInteritemSpacing
self.minimumLineSpacing = minimumLineSpacing
self.sectionInset = sectionInset
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func prepare() {
super.prepare()
guard let collectionView = collectionView else { return }
let marginsAndInsets = sectionInset.left + sectionInset.right + collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1)
let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down)
itemSize = CGSize(width: itemWidth, height: itemWidth)
}
override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext {
let context = super.invalidationContext(forBoundsChange: newBounds) as! UICollectionViewFlowLayoutInvalidationContext
context.invalidateFlowLayoutDelegateMetrics = newBounds.size != collectionView?.bounds.size
return context
}
}
UICollectionViewCell
class AddServiceViewCell: UICollectionViewCell {
#IBOutlet weak var labelStackView: UIStackView!
#IBOutlet weak var tvServiceName: UILabel!
#IBOutlet weak var tvQuantityNeeded: UILabel!
public var onCellTapped: (() -> ())?
override func awakeFromNib() {
super.awakeFromNib()
self.layer.cornerRadius = 10.0
}
override func prepareForReuse() {
super.prepareForReuse()
self.tvServiceName.text = nil
self.tvQuantityNeeded.show()
}
public static func nib() -> UINib {
return UINib.init(nibName: identifier, bundle: Bundle(for: ServiceLineItemCell.self))
}
public func configure(with service: TowService){
self.tvServiceName.text = service.description
if(service.calculated){
self.tvQuantityNeeded.hide()
}
}
public func eventTriggered()
{
onCellTapped?()
}
}
UIViewController
class AddServiceViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView!
private let columnLayout = AddServiceFlowLayout(
cellsPerRow: 3,
minimumInteritemSpacing: 10,
minimumLineSpacing: 10,
sectionInset: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
)
override func viewDidLoad() {
super.viewDidLoad()
self.title = "Add Service"
// Register cell classes
self.collectionView!.delegate = self
self.collectionView!.dataSource = self
self.collectionView!.collectionViewLayout = columnLayout
self.collectionView!.contentInsetAdjustmentBehavior = .always
self.collectionView!.register(AddServiceViewCell.nib().self, forCellWithReuseIdentifier: AddServiceViewCell.identifier)
}
// removed for brevity ....
// MARK: UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout
extension AddServiceViewController : UICollectionViewDelegateFlowLayout, UICollectionViewDelegate, UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return allServices.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddServiceViewCell.identifier, for: indexPath) as! AddServiceViewCell
cell.configure(with: allServices[indexPath.row])
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.onConfirmAdd(allServices[indexPath.row])
}
}

Here is a road map
1- You need to implement sizeForItemAt
2- Consider you have 3 columns per row , create a function that that accepts 3 Items ( introduced with the current indexPath.item ) from your model and manually calculate maximum height for each string in that model
3- Return the maximum height and by this you will set that height for all cells of same row

Related

UILabel SizeToFit Not working in UICollectionViewCell

This is my code
class DescriptionsViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
let layout = TagFlowLayout()
layout.estimatedItemSize = CGSize(width: 140, height: 40)
collectionView.collectionViewLayout = layout
}
}
class Row {
var attributes = [UICollectionViewLayoutAttributes]()
var spacing: CGFloat = 0
init(spacing: CGFloat) {
self.spacing = spacing
}
func add(attribute: UICollectionViewLayoutAttributes) {
attributes.append(attribute)
}
func tagLayout(collectionViewWidth: CGFloat) {
let padding = 10
var offset = padding
for attribute in attributes {
attribute.frame.origin.x = CGFloat(offset)
offset += Int(attribute.frame.width + spacing)
}
}
}
class TagFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElements(in: rect) else {
return nil
}
var rows = [Row]()
var currentRowY: CGFloat = -1
for attribute in attributes {
if currentRowY != attribute.frame.origin.y {
currentRowY = attribute.frame.origin.y
rows.append(Row(spacing: 10))
}
rows.last?.add(attribute: attribute)
}
rows.forEach {
$0.tagLayout(collectionViewWidth: collectionView?.frame.width ?? 0)
}
return rows.flatMap { $0.attributes }
}
}
extension DescriptionsViewController : UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sourse.Ingredients.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell",for: indexPath) as? collectionViewCell else {
return collectionViewCell()
}
cell.label.text = sourse.Ingredients[indexPath.row] //[indexPath.section]
cell.label.preferredMaxLayoutWidth = collectionView.frame.width - 16
cell.label.sizeToFit()
return cell
}
} // uicollectionViewDatasourse,UICollectionViewDelegate
class collectionViewCell: UICollectionViewCell{
#IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.layer.cornerRadius = label.frame.size.height / 2.0
self.backgroundColor = #colorLiteral(red: 0.3647058904, green: 0.06666667014, blue: 0.9686274529, alpha: 1)
}
} //UICollectionViewCell
The text will beyond the background color and the background color can't adaptation the text length
I added some code and answered my question.
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: sourse.Ingredients[indexPath.item].size(withAttributes: [NSAttributedString.Key.font : UIFont.systemFont(ofSize: 17)]).width + 25, height: 30)
}
But I think it's not best answer because this source code can detection they just add .width + 25.
Obviously this code is not "dynamic", but it does work.
The problem exisit in your Xib constraints. When your label cannot get the right frame, sizeToFit will not work.
If you want the label adapt to your text length, you can try.
Snapkit
view.contentView.addSubview(label)
label.snp.makeConstraints {
$0.centerY.equalToSuperview()
$0.leading.trailing.equalToSuperview().inset(customOffset)
}
Xib
Juset set the same constraints, ___centeY, leading, trailing___, as by SnapKit(I am not familiar how to in Xib, so sorry about no cases)
Original Code
this may help
class tageCollectionViewCell: UICollectionViewCell{
var label: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupView() {
label = UILabel()
//... add your custom character
contentView.addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor)
]
NSLayoutConstraint.activate(constraints)
}
}

UICollectionView cell not resizing based on cell content with autoresize

I am trying to create UICollectionView with cells that adjust the width based on the content of the cell using layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize but it doesn't update. Bellow is two images of what am trying to achieve and the next is what I have achieved.
Here is what am trying to achieve.
Correct display
Here is what I have been able to achieve
What I have now
And here is my code
import UIKit
struct Model {
let name: String
let color: String
}
class DisplayTagsView: UIView {
// Collection View
var projectTagsCollectionView: UICollectionView!
var projectTagsCollectionViewHeightConstraint: NSLayoutConstraint!
private var tagsObjects = [Any]() // Object to allow add button
private var tags: [Model] = [] // Tags
// MARK: - Init
init() {
super.init(frame: .zero)
initViews()
initTags()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func initTags() {
self.tags.append(Model(name: "Some tag", color: "color"))
self.tags.append(Model(name: "Twotwo", color: "color"))
self.tags.append(Model(name: "Smartparking", color: "color"))
self.tags.append(Model(name: "Development", color: "color"))
self.tagsObjects = self.tags
self.tagsObjects.append(AddButtonCollectionViewCell.self)
}
// MARK: - Private
private func initViews() {
initTagCollectionView()
}
private func initTagCollectionView() {
let layout = UICollectionViewFlowLayout()
layout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
layout.minimumLineSpacing = 5
layout.minimumInteritemSpacing = 5
layout.scrollDirection = .vertical
projectTagsCollectionView = UICollectionView(frame: self.frame, collectionViewLayout: layout)
projectTagsCollectionView.delegate = self
projectTagsCollectionView.dataSource = self
projectTagsCollectionView.register(cell: ProjectCollectionViewCell.self)
projectTagsCollectionView.register(cell: AddButtonCollectionViewCell.self)
projectTagsCollectionView.isScrollEnabled = false
projectTagsCollectionView.backgroundColor = .clear
}
// set up views
func setupView() {
addSubview(projectTagsCollectionView)
setCollectionHeight()
}
// update height
func setCollectionHeight() {
projectTagsCollectionViewHeightConstraint = projectTagsCollectionView.heightAnchor.constraint(equalToConstant: 200)
projectTagsCollectionViewHeightConstraint.isActive = true
}
// Button button
func addButton() -> UIButton {
let addButton = UIButton()
addButton.setImage(#imageLiteral(resourceName: "settings"), for: .normal)
return addButton
}
}
// MARK: - UICollectionViewDelegateFlowLayout
extension DisplayTagsView : UICollectionViewDelegateFlowLayout {
// Auto resizing of the cell tags
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout
var newEdgeInsets = UIEdgeInsets(top: flowLayout!.sectionInset.top, left: flowLayout!.sectionInset.left, bottom: flowLayout!.sectionInset.bottom, right: flowLayout!.sectionInset.right)
if collectionView.numberOfItems(inSection: section) == 1 {
let edgeInset = newEdgeInsets.right + (collectionView.frame.width - flowLayout!.itemSize.width)
newEdgeInsets.right = edgeInset
}
return newEdgeInsets
}
}
// MARK: - UICollectionViewDelegate
extension DisplayTagsView: UICollectionViewDelegate {
}
// MARK: - UICollectionViewDataSource
extension DisplayTagsView: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return tagsObjects.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let tagObject = self.tagsObjects[indexPath.item]
if let tag = tagObject as? Model {
let cell: ProjectCollectionViewCell = projectTagsCollectionView.dequeueTypedCell(forIndexPath: indexPath)
cell.configureCell(tagName: tag.name, tagBackground: tag.color)
return cell
} else {
// Adding button to the UICollection
let cell: AddButtonCollectionViewCell = membersCollectionView.dequeueTypedCell(forIndexPath: indexPath)
let addButto = addButton()
cell.contentView.subviews.forEach({$0.removeFromSuperview()})
cell.contentView.addSubview(addButton)
settingButton.snp.makeConstraints { make in
make.size.equalTo(cell.contentView)
}
return cell
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print(indexPath)
}
}
Try Following library. TagList view.
https://github.com/ElaWorkshop/TagListView. It surely working ur conditions

Align the collectionviewcells center

I current have a collectionview attached to a array of strings. I want to align these cells center regardless of the number of things in the array. I am not sure how to do it, and where to do it.
import UIKit
class MyButtonCell: UICollectionViewCell{
#IBOutlet weak var buttonOne: UIButton!
#IBOutlet weak var targetButton: UIButton!
var callback: (() -> ())?
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() -> Void {
contentView.layer.borderWidth = 1
contentView.layer.borderColor = UIColor.black.cgColor
}
#IBAction func buttonTapped(_ sender: UIButton) {
callback?()
}
}
class StevenViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
let buttonTitles: [String] = [
"4", "6", "7", "8"
]
var targetButtonTitles: [String] = [
"", "", "", ""
]
var current:String = ""
#IBOutlet var collectionView: UICollectionView!
#IBOutlet var targetCollection: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
targetCollection.delegate = self
targetCollection.dataSource = self
collectionView.delegate = self
collectionView.dataSource = self
collectionView.tag = 1
targetCollection.tag = 2
}
func centerItemsInCollectionView(cellWidth: Double, numberOfItems: Double, spaceBetweenCell: Double, collectionView: UICollectionView) -> UIEdgeInsets {
let totalWidth = cellWidth * numberOfItems
let totalSpacingWidth = spaceBetweenCell * (numberOfItems - 1)
let leftInset = (collectionView.frame.width - CGFloat(totalWidth + totalSpacingWidth)) / 2
let rightInset = leftInset
return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if collectionView.tag == 1 {
return buttonTitles.count
} else {
return targetButtonTitles.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// set the button title (and any other properties)
if collectionView.tag == 1 {
// Setup here your cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "myCellID", for: indexPath) as! MyButtonCell
cell.callback = {
print("Button was tapped at \(indexPath)")
self.targetButtonTitles[indexPath.item] = self.buttonTitles[indexPath.item]
//print(self.targetButtonTitles)
self.current = self.buttonTitles[indexPath.item]
print(self.current)
//collectionView.reloadData()
// do what you want when the button is tapped
}
cell.buttonOne.setTitle(buttonTitles[indexPath.item], for: [])
return cell
} else {
// Setup here your targetCell
let targetCell = targetCollection.dequeueReusableCell(withReuseIdentifier: "myCellID", for: indexPath) as! MyButtonCell
targetCell.callback = {
if self.current != ""{
self.targetButtonTitles[indexPath.item] = self.current
print(self.targetButtonTitles)
targetCell.targetButton.setTitle(self.targetButtonTitles[indexPath.item], for: [])
self.current = ""
}else{
self.targetButtonTitles[indexPath.item] = ""
targetCell.targetButton.setTitle(self.targetButtonTitles[indexPath.item], for: [])
}
}
return targetCell
}
}
}
As you can see, right now they are just starting from the left. So, How should I align them in the middle.

cellForItemAt called only once in Swift collectionView

If I use flow layout with collectionView, then all my cells are visible with the data. If I use a custom layout, then cellForItemAt is only accessed for index (0,0), and correspondingly only a single cell is displayed.
I'm baffled why - please help!
Minimal example below:
ViewController:
import UIKit
private let reuseIdentifier = "customCell"
class customCollectionViewController: UICollectionViewController {
#IBOutlet var customCollectionView: UICollectionView!
let dwarfArray = ["dopey", "sneezy", "bashful", "grumpy", "doc", "happy", "sleepy"]
override func viewDidLoad() {
super.viewDidLoad()
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dwarfArray.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! customCollectionViewCell
let cellContentsIndex = indexPath.row
if cellContentsIndex <= dwarfArray.count
{
cell.displayContent(name: dwarfArray[cellContentsIndex])
}
return cell
}
}
Custom Cell
import UIKit
class customCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var nameLabel: UILabel!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect){
super.init(frame: frame)
}
public func displayContent(name: String){
nameLabel.text = name
}
func setup(){
self.layer.borderWidth = 1.0
self.layer.borderColor = UIColor.black.cgColor
}}
Custom Layout
If this is not here - I can see all the cells I expect (albeit without my preferred layout). When I use this, I only see one cell.
import UIKit
class customCollectionViewLayout: UICollectionViewLayout {
let CELL_SIZE = 100.0
var cellAttrsDictionary = Dictionary<NSIndexPath, UICollectionViewLayoutAttributes>()
//define the size of the area the user can move around in within the collection view
var contentSize = CGSize.zero
var dataSourceDidUpdate = true
func collectionViewContentSize() -> CGSize{
return self.contentSize
}
override func prepare() {
if (collectionView?.numberOfItems(inSection: 0))! > 0 {
/// cycle through each item of the section
for item in 0...(collectionView?.numberOfItems(inSection: 0))!-1{
/// build the collection attributes
let cellIndex = NSIndexPath(item: item, section: 0)
let xPos = Double(item)*CELL_SIZE
let yPos = 40.0
let cellAttributes = UICollectionViewLayoutAttributes(forCellWith: cellIndex as IndexPath)
cellAttributes.frame = CGRect(x: xPos, y:yPos, width: CELL_SIZE, height: CELL_SIZE)
// cellAttributes.frame = CGRect(x: xPos, y:yPos, width: CELL_WIDTH + 2*CELL_SPACING, height: CELL_HEIGHT)
cellAttributes.zIndex = 1
//save
cellAttrsDictionary[cellIndex] = cellAttributes
}
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
/// create array to hold all the elements in our current view
var attributesInRTect = [UICollectionViewLayoutAttributes]()
/// check each element to see if they should be returned
for cellAttributes in cellAttrsDictionary.values {
if rect.intersects(cellAttributes.frame)
{
attributesInRTect.append(cellAttributes)
}
}
return attributesInRTect
}
override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttrsDictionary[indexPath as NSIndexPath]!
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}}
Output
The problem is with contentSize value
func collectionViewContentSize() -> CGSize{
return self.contentSize
}
Just replace func collectionViewContentSize()... by something like this:
func lastLayoutAttributes() -> UICollectionViewLayoutAttributes? {
return cellAttrsDictionary.values.map { $0 }.sorted(by: { $0.frame.maxX < $1.frame.maxX }).last
}
override var collectionViewContentSize: CGSize {
guard let collectionView = collectionView else { return .zero }
guard collectionView.frame != .zero else { return .zero }
let width: CGFloat
let height: CGFloat = collectionView.frame.height
if let lastLayoutAttributes = lastLayoutAttributes() {
width = lastLayoutAttributes.frame.maxX
} else {
width = 0
}
return CGSize(width: width, height: height)
}
And you will see more than one cell.

CollectionView content height size doesn't properly update inside tableView cell

I have a collectionView inside a tableView cell. I'm using a custom flowLayout to customize collectionView cells (all have to be custom size and aligned to left) and update the collectionView height and fit all elements inside it.
The tableView cell is auto growing. So the collectionView have to adjust to the content, and the tableViewCell have to adjust to collectionView.
Here is my tableView cell class, with collectionView configuration inside:
import UIKit
class SearchStationsTableViewCell: UITableViewCell {
var delegate : SearchStationsTableViewCellProtocol?
static let heightForRow = 234
var servicos = [String]()
var serviceList = ServicesList()
var station : Station?
#IBOutlet weak var background: UIView!
#IBOutlet weak var nameLabel : UILabel!
#IBOutlet weak var seeOnMapButton : UIButton!
#IBOutlet weak var favoriteButton: UIButton!
#IBOutlet weak var addressLabel : UILabel!
#IBOutlet weak var distanceLabel : UILabel!
#IBOutlet weak var collectionView : UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
self.background.shadowWith(color: UIColor.black.cgColor, opacity: 0.1, size: CGSize(width: 0.0, height: 3.0), radius: 5.0)
self.collectionView.delegate = self
self.collectionView.dataSource = self
registerCells()
}
func registerCells() {
collectionView?.register(UINib(nibName: "StationFiltersCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "StationFiltersCollectionViewCell")
}
/// Configura células da tableView
///
/// - Parameter station:
func configure(station: Station){
// constraintCollectionHeight?.constant = 0.0
let columnLayout = FlowLayout(
minimumInteritemSpacing: 5,
minimumLineSpacing: 5,
sectionInset: UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1)
)
collectionView?.collectionViewLayout = columnLayout
collectionView.isScrollEnabled = false
self.station = station
self.nameLabel.text = station.nomeFantasia
self.addressLabel.text = station.endereco
if(station.isFavorite)!{
self.favoriteButton.setImage(UIImage(named: "icFavoriteMarked"), for: .normal)
self.favoriteButton.isUserInteractionEnabled = false
}else{
self.favoriteButton.setImage(UIImage(named:"icFavorite"), for: .normal)
self.favoriteButton.isUserInteractionEnabled = true
}
if let _servicos = station.servicos, _servicos.count > 0{
self.servicos = _servicos
self.collectionView?.reloadData()
let heightSize = self.collectionView.collectionViewLayout.collectionViewContentSize.height
self.collectionView?.heightAnchor.constraint(equalToConstant:heightSize).isActive = true
}
}
#IBAction func favoriteButton_action(sender: Any){
self.delegate?.favoriteButtonPressed(sender:self)
}
#IBAction func callButon_action(sender: Any){
self.delegate?.callButtonPressed(station: station!)
}
#IBAction func routeButton_action(sender: Any){
self.delegate?.routeButtonPressed(station: station!)
}
#IBAction func seeOnMap_action(sender: Any){
self.delegate?.seeOnMapButtonPressed(sender: sender,station: station!)
}
}
extension SearchStationsTableViewCell : UICollectionViewDelegate, UICollectionViewDataSource{
public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int{
return servicos.count
}
public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StationFiltersCollectionViewCell", for: indexPath) as! StationFiltersCollectionViewCell
if(ServicesList.haveImage(serviceName: serviceList.serviceName[indexPath.row])){
cell.filterImage?.image = UIImage(named: serviceList.getImage(serviceName: serviceList.serviceName[indexPath.row]))
cell.filterName?.text = ""
}else{
let title = serviceList.getFriendlyName(serviceName: serviceList.serviceName[indexPath.row])
cell.filterName?.text = title
cell.filterImage?.image = UIImage()
}
return cell
}
}
class FlowLayout: UICollectionViewFlowLayout {
required init(minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) {
super.init()
estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
self.minimumInteritemSpacing = minimumInteritemSpacing
self.minimumLineSpacing = minimumLineSpacing
self.sectionInset = sectionInset
//sectionInsetReference = .fromSafeArea
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let layoutAttributes = super.layoutAttributesForElements(in: rect)!.map { $0.copy() as! UICollectionViewLayoutAttributes }
guard scrollDirection == .vertical else { return layoutAttributes
}
// Filter attributes to compute only cell attributes
let cellAttributes = layoutAttributes.filter({ $0.representedElementCategory == .cell })
// Group cell attributes by row (cells with same vertical center) and loop on those groups
for (_, attributes) in Dictionary(grouping: cellAttributes, by: { ($0.center.y / 10).rounded(.up) * 10 }) {
// Set the initial left inset
var leftInset = sectionInset.left
// Loop on cells to adjust each cell's origin and prepare leftInset for the next cell
for attribute in attributes {
attribute.frame.origin.x = leftInset
leftInset = attribute.frame.maxX + minimumInteritemSpacing
}
}
return layoutAttributes
}
}

Resources