iOS 8 Swift - Tableview with Embedded Collectionview

ios 8 Swift - TableView with embedded CollectionView

Create a usual UITableView and in your UITableViewCell create the UICollectionView. Your collectionView delegate and datasource should conform to that UITableViewCell.

Just go through this

In your ViewController

// Global Variable
var tableView: UITableView!

override func viewDidLoad() {
super.viewDidLoad()

tableView = UITableView(frame: self.view.bounds)
tableView.delegate = self
tableView.dataSource = self
self.view.addSubview(tableView)

tableView.registerClass(TableViewCell.self, forCellReuseIdentifier: "TableViewCell")
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "NormalCell")
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 3 {
var cell: TableViewCell = tableView.dequeueReusableCellWithIdentifier("TableViewCell", forIndexPath: indexPath) as! TableViewCell
cell.backgroundColor = UIColor.groupTableViewBackgroundColor()
return cell

} else {
var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("NormalCell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = "cell: \(indexPath.row)"

return cell
}
}

As you can see I've created two different cells, a custom TableViewCell which is returned only when the row index is 3 and a basic UITableViewCell in other indices.

The custom "TableViewCell" will have our UICollectionView. So Create a UITableViewCell subclass and write down the below code.

import UIKit

class TableViewCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate {

var collectionView: UICollectionView!

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

let layout = UICollectionViewFlowLayout()
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal

collectionView = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
collectionView.backgroundColor = UIColor.clearColor()

self.addSubview(collectionView)
}

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

// MARK: UICollectionViewDataSource
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}


func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell: UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! UICollectionViewCell
if indexPath.row%2 == 0 {
cell.backgroundColor = UIColor.redColor()
} else {
cell.backgroundColor = UIColor.yellowColor()
}

return cell
}
}

Hope it helps.

How to create collectionview in tableView Cell in swift 4?

If you want to show all images below username than you need to change the Layout. it's not possible in that layout.

so my suggestion is : You display only user details in HomeVC, once any row is tapped, move to new screen and show user details along with all images like instagram user profile.

Edit of your Demo : https://www.dropbox.com/s/v05k2udqa3pu1dd/Demp1.zip?dl=0

How to properly add an UICollectionView inside UITableViewCell using IOS 12

If you want the following output:

Sample Image

Code
ViewController:

class ViewController: UIViewController {
let list = [String](repeating: "Label", count: 10)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
tableView.reloadData()
}

public lazy var tableView: UITableView = { [unowned self] in
let v = UITableView.init(frame: .zero)
v.delegate = self
v.dataSource = self
v.estimatedRowHeight = 44
v.rowHeight = UITableViewAutomaticDimension
v.register(TableCell.self, forCellReuseIdentifier: "TableCell")
return v
}()
}
extension ViewController: UITableViewDelegate{

}
extension ViewController: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return list.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell", for: indexPath) as! TableCell
cell.label.text = "\(list[indexPath.row]) \(indexPath.row)"
return cell
}
}

TableCell:

class TableCell: UITableViewCell{

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}

override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
}

func commonInit(){
contentView.addSubview(label)
contentView.addSubview(collectionView)
updateConstraints()
}

override func updateConstraints() {
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: topAnchor),
label.leadingAnchor.constraint(equalTo: leadingAnchor),
label.trailingAnchor.constraint(equalTo: trailingAnchor)
])
collectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: label.bottomAnchor),
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor),
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor),
])
super.updateConstraints()
}

let list = [String](repeating: "Task_", count: 10)
public let label: UILabel = {
let v = UILabel()
v.textAlignment = .center
return v
}()

public lazy var collectionView: UICollectionView = { [unowned self] in
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
let v = UICollectionView(frame: .zero, collectionViewLayout: layout)
v.register(CollectionCell.self, forCellWithReuseIdentifier: "CollectionCell")
v.delegate = self
v.dataSource = self
v.isScrollEnabled = false
return v
}()

override func sizeThatFits(_ size: CGSize) -> CGSize {
let collectionCellHeight = 50
let rows = list.count / 5 // 5: items per row
let labelHeight = 20 // you can calculate String height
let height = CGFloat((collectionCellHeight * rows) + labelHeight)
let width = contentView.frame.size.width
return CGSize(width: width, height: height)
}
}
extension TableCell: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return list.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CollectionCell
cell.label.text = "\(list[indexPath.item])\(indexPath.item)"
return cell
}
}
extension TableCell: UICollectionViewDelegate{

}
extension TableCell: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width/5, height: 50)
}
}

CollectionCell

class CollectionCell: UICollectionViewCell{
let padding: CGFloat = 5
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}

func commonInit(){
backgroundColor = .yellow
contentView.addSubview(label)
updateConstraints()
}

override func updateConstraints() {
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
label.topAnchor.constraint(equalTo: topAnchor, constant: padding),
label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: padding),
label.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -padding),
label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -padding)
])
super.updateConstraints()
}

public let label: UILabel = {
let v = UILabel()
v.textColor = .darkText
v.minimumScaleFactor = 0.5
v.numberOfLines = 1
return v
}()
}

How to push view controller on a button tap in nested collection view cell swift

First you have to make a property in tableViewCell:

weak var parent:ViewController?

Then in viewController you have to use cell for row of tableView:

cell.parent = self

Then create same property in collectionViewCell:

weak var parent:ViewController?

And use collectionView func cell for item at:

cell.parent = parent

And use that parent inside your button func:

 @objc func onTap() {
let destinationVC = NextViewController()
parent?.navigationController.pushViewController(destinationVC,animated:true)
}

How to populate different array values in collection view inside of UITableview using swift?

First your array2 has to be like this :

let array2 = [["product id 1","product id 2"],["product id 3","product id 4"],["product id 5","product id 6"],["product id 7","product id 8","product id 9","product id 10","product id 11"]]

Don't use NSArray in Swift. you can write it as [String], [[String]].

Your ViewController will have only UITableViewDelegate and UITableViewDatasource methods:

extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : TableViewCell = tableView.dequeueReusableCell(withIdentifier: "cells") as! TableViewCell
cell.tableviewlabel1.text = array[indexPath.row]
cell.tableviewlabel2.text = array1[indexPath.row]

cell.arrayForCollectionView = array2
return cell
}
}

Then in your TableViewCell:

class TableViewCell: UITableViewCell {

var arrayForCollectionView : [[String]]! {
didSet {
self.collectionView.reloadData
}
}

@IBOutlet weak var collectionView: UICollectionView!

}

extension TableViewCell : UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if (arrayForCollectionView != nil) {
return arrayForCollectionView.count
}
return 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "collection", for: indexPath) as! CollectionViewCell


let rowValue = arrayForCollectionView[indexPath.row]
for i in 0..<rowValue.count {
cell.collectionviewlabel1.text = rowValue[i] as? String
}
return cell
}
}

Let me know if you are getting any issue.

Segue in a UICollectionView embedded in a UITableviewCell, Swift

May be you can create a variable to handle this. You can do optional also.

class HomeVTwoTableViewCell: UITableViewCell{
var liveCommunities: Results<Community>?
@IBOutlet weak var collectionView: UICollectionView!
var didSelectAction: () -> Void // add your action here

Here you can call to this function

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedCommunity = (liveCommunities?[indexPath.row].communityId)!
HomeVTwoTableViewController().liveCellSelected()
didSelectAction() // Invoque your action
}

//On the cell creator, add the navigation or logic when you want to tap the cell

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellBig", for: indexPath) as! HomeVTwoTableViewCell
cell.update()
cell.didSelectAction = {
// add here your navigation
}
return cell
} else {
return UITableViewCell()
}
}


Related Topics



Leave a reply



Submit