perform segue from collection view inside table view - swift

I have a table view with a collection view in my 2nd cell.
When a video from the collection view is clicked, i want to perform a segue to another view controller.

that's the sample code.
class tableViewClass: UIViewController, UITableViewDelegate, UITableViewDataSource, VideoCellSelectionDelegate {
#IBOutlet weak var tableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "VideoCell", for: indexPath) as! VideoCell
cell.delegate = self
return cell
}
func didSelect() {
//performSegue
}
}
the VideoCell must have a delegate which is called when a collectionView cell is select
protocol VideoCellSelectionDelegate {
func didSelect()
}
class VideoCell: UITableViewCell, UICollectionViewDelegate {
var delegate: VideoCellSelectionDelegate?
#IBOutlet weak var collectionView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
delegate?.didSelect()
}
}

Related

How to Navigate to new View Controller from collection view cell? In Swift

I have two View controllers(VC-1, VC-2).
View controller 1 is having a table view and further that table view is consists of 4 collection views. I want to navigate to new VC(VC-2). But unable to get "self.storyboard.instantiateViewController" in didSelect method of collection View.
So now how I can navigate to VC-2
You should use delegate. you can create a protocol and define a method for routing and implement it into VC1
You can use the below sample code.
This code is using closure syntax
class FirstVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "TableCell_Identifier") as! TableCell
cell.configureCell(data: ["Your", "Data"])
cell.didSelectRow = { data in
// Goto second view controller
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondVC")
self.navigationController?.pushViewController(vc!, animated: true)
}
return cell
}
}
class TableCell: UITableViewCell, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet weak var colView: UICollectionView!
var didSelectRow: ((_ data: String) -> Void)? = nil // Closure
var arrData = [String]()
func configureCell(data: [String]) {
// Setup CollectionView data
self.arrData = data
self.colView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.arrData.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CELL_IDENTIFIER", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let data = self.arrData[indexPath.row]
didSelectRow?(data)
}
}

How to use NavigationController by taping on CollectionViewCell which in TableViewCell

I want to pushViewController and show detail about that cell!
Swift5
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return ViewController.typeOfDishes.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return ViewController.typeOfDishes[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.myTableView.dequeueReusableCell(withIdentifier: "MyTableViewCell") as! MyTableViewCell
return cell
}
}
import UIKit
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var myCollectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
myCollectionView.delegate = self
myCollectionView.dataSource = self
}
}
extension MyTableViewCell: UICollectionViewDelegate, UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return ViewController.dishesCountByArray[ViewController.indexOfTableView!]
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
////////////There I want to do PushViewController Action
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.myCollectionView.dequeueReusableCell(withReuseIdentifier: "MyCollectionViewCell", for: indexPath) as! MyCollectionViewCell
return cell
}
}
I want to normally pu​sh when user taps on collection view cell
Inside here Add a delegate
class MyTableViewCell: UITableViewCell {
weak var delegate:ViewController?
.....
}
Then set it here
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.myTableView.dequeueReusableCell(withIdentifier: "MyTableViewCell") as! MyTableViewCell
cell.delegate = self
return cell
}
Now you can push here
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondID") as! SecondViewController
self.delegate?.navigationController?.push////
}

I want to create a signup Form with n number of UITextFields in custom UITableViewCell

I m creating a UITableViewCell which can display n numbers of UITextfields.Please suggest me how to declare these textfields . And also mention how to implement the cellForRowAt function for it.
Heres my UITableViewCell file
import UIKit
class CustomTableViewCell: UITableViewCell, UITextFieldDelegate {
#IBOutlet weak var textlab: UITextField!
func configure(text: String?, placeholder: String) {
textlab.text = text
textlab.placeholder = placeholder
textlab.accessibilityValue = text
textlab.accessibilityLabel = placeholder
}
#IBOutlet weak var underlineLabel: UILabel!
#IBOutlet weak var AlertMessage: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
AND THE VIEW CONTROLLER FOR IT IS AS FOLLOWS:
import UIKit
class CustomViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
var blanklabel = ["","","",""]
var textfields = ["First Name","Last Name","Email","Contact Number"]
var alertmsg = ["Please enter your First Name","Please enter your Last Name","Please enter your Email","Please enter your Contact number",]
var textfield = UITextField()
var AlertMessage = UILabel()
#IBAction func nextLabel(_ sender: Any) {
}
override func viewDidLoad() {
super.viewDidLoad()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 4
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomTableViewCell
return cell
}
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
return nil
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
}
It's not good idea to do it in UITableView with dynamic cells. Try to use custom view (change your cell class to subclass of UIView) in UIStackView or UITableView with static cells. And set uitextfields as properties in your viewcontroller.

swift segue from tableView through a navigationController to a TableViewController

I cannot get this to segue to another TableViewController. I keep getting a crash... I know it is because it is going through the NavigationController and I do not know how to segue from the main controller to pass it and go to the tableView. Heres the look
the segue from the navControl to the tableView is called "ChildsInfo"
Here is what I am trying and crashing.
class PagesViewController: UIViewController, UITableViewDelegate {
#IBOutlet weak var pagesTableView: UITableView!
#IBOutlet weak var infoProgressBar: UIProgressView!
let pages = ["Page 1","Page 2","Page 3"]
var myIndex = 0
var selectedPage: String?
override func viewDidLoad() {
super.viewDidLoad()
pagesTableView.dataSource = self
pagesTableView.delegate = self
// Do any additional setup after loading the view.
}
}
extension PagesViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "pagesTableViewCell")
cell?.textLabel?.text = pages[indexPath.row]
return cell!
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pages.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 71.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
performSegue(withIdentifier: "ChildsInfo", sender: self)
}
}
}
Based on the images you have posted I'm assuming the crash you are getting is that the segue is not found. This is because you should be trying to perform the segue to the navigation controller itself from the table view (i.e. the link on the left in your image). The navigation controller then has a root view controller and you can push others onto the stack as required.

Not reuse data with ReusableCell of CollectionView

I have tableView:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellTime", for: indexPath) as! TimeViewCell
let showHour = self.infoWripper.sorted(by: { $0.hour < $1.hour })[indexPath.row]
cell.labelTime.text = showHour.showHour()
cell.dataForShow = showHour.showFullTime()
return cell
}
Cell of TableView contents UICollectionView with cells.
class TimeViewCell: UITableViewCell {
#IBOutlet weak var labelTime: UILabel!
var dataForShow = [String]()
#IBOutlet weak var collectionView: UICollectionView!
override func awakeFromNib() {
super.awakeFromNib()
collectionView.delegate = self
collectionView.dataSource = self
}
}
extension TimeViewCell: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataForShow.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as! CustomCollectionCell
cell.labelCollection.text = dataForShow[indexPath.row]
//heightForCell = collectionView.contentSize.height
return cell
}
}
class CustomCollectionCell: UICollectionViewCell {
#IBOutlet weak var labelCollection: UILabel!
}
When I open VC with table - view is OK, but when I begin scrolling - I see, that data not correct (reuse), but I can't find my mistake.
before scroll:
after:
You need to reload the collection view in your cell.
Try this:
class TimeViewCell: UITableViewCell {
....
var dataForShow = [String]() {
didSet {
self.collectionView?.reloadData()
}
}