How to use two custom cell in UITableview - ios

var mutipleArrayForFirstCell:[String] = ["1","2","3","4","5","6","7","8","9","10"]
var mutipleArrayForSecondCell:[String] = ["11","12","13","14","15","16","17","18","19","20"]
//MARK - TableView delegates
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 1 {
return mutipleArrayForFirstCell.count
}else {
return mutipleArrayForSecondCell.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let valueAt1stCell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath) as! multipleCustomCellTableViewCell
valueAt1stCell.Firstlabel.text = mutipleArrayForFirstCell[indexPath.row]
return valueAt1stCell
} else {
let valueAt2ndCell = tableView.dequeueReusableCell(withIdentifier: "SecondCell", for: indexPath) as! SecondCustomTableviewCell
valueAt2ndCell.secondLabel.text = mutipleArrayForSecondCell[indexPath.row]
return valueAt2ndCell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
My questions is i want to show the above declared two array value in two different cells. How can i do it?? it showing like this:
But it should show 1-10 in one cell and 11-20 in another cell.someone please help me ,Thanks in advance
how can i give some space between two cells ?

Try this one
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
//First Array
let valueAt1stCell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath) as! multipleCustomCellTableViewCell
valueAt1stCell.Firstlabel.text = mutipleArrayForFirstCell[indexPath.row]
return valueAt1stCell
default:
//Second Array
let valueAt2ndCell = tableView.dequeueReusableCell(withIdentifier: "SecondCell", for: indexPath) as! SecondCustomTableviewCell
valueAt2ndCell.secondLabel.text = mutipleArrayForSecondCell[indexPath.row]
return valueAt2ndCell
}
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let valueAt1stCell = tableView.dequeueReusableCell(withIdentifier: "FirstCell", for: indexPath) as! multipleCustomCellTableViewCell
valueAt1stCell.Firstlabel.text = mutipleArrayForFirstCell[indexPath.row]
return valueAt1stCell
} else {
let valueAt2ndCell = tableView.dequeueReusableCell(withIdentifier: "SecondCell", for: indexPath) as! SecondCustomTableviewCell
valueAt2ndCell.secondLabel.text = mutipleArrayForSecondCell[indexPath.row]
return valueAt2ndCell
}
}

Related

UITableViewCell 3 Time Selected Change Background Color on Multiple Selection

I have 5 rows. Background color will change when 3 or more is selected.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
let backgroundView = UIView()
backgroundView.backgroundColor = YOUR_COLOR_HERE
cell.selectedBackgroundView = backgroundView
return cell
}
These code change bacground color. But I want the background color to change when 3 or more is selected.
How can I do that?
First of all you should add configuration for both states, whether tableviewCell meets the isTapsEnough condition or not.
var numberOfTaps: Int = 0
var isTapsEnough: Bool { retrun numberOfTaps >= 3 }
func tap() {
self.numberOfTaps += 1
if self.isTapsEnough {
self.tableView.reloadData()
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.contentView.backgroundColor = self.isTapsEnough ? .yellow : .clear
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) -> UITableViewCell {
self.tap()
}
you can use this
var numberTaps = 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//code cell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if numberTaps == 3
{
cell.backgroundColor = .red
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) -> UITableViewCell {
numberTaps += 1
if numberTaps == 3
{
tableView.reloadData()
}
}
You can try with this example, although code syntax may be wrong.
var indexPaths: [IndexPath] = [IndexPath]()
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false {
tableView.deselectRow(at: indexPath, animated: true)
return nil
}
indexPaths.append(indexPath)
return indexPath
}
func tableView(_ tableView: UITableView, willDeselectRowAt indexPath: IndexPath) -> IndexPath? {
for (index, value) in indexPaths.enumerated() {
if value == indexPath {
indexPaths.remove(at: index)
}
}
return nil
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//code cell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if indexPaths.count >= 3
{
cell.backgroundColor = .red
}
return cell
}
Best way to make adjustments in the background color, etc is in willDisplayCell and observe indexPathsForSelectedRows:
(disclaimer: typed in browser, not tested in Xcode)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if tableView.indexPathsForSelectedRows.count >= 3 && tableView.indexPathsForSelectedRows.contains(indexPath) {
cell.backgroundColor = .red // or change the backgroundView color
}
else {
cell.backgroundColor = .clear // or whatever color you want
}
}
This will help you to start
var SelectedIndexpath = [IndexPath]()
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if SelectedIndexpath.contains(indexPath){
SelectedIndexpath.remove(at: SelectedIndexpath.index(of: indexPath)!)
}else{
SelectedIndexpath.append(indexPath)
}
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
if SelectedIndexpath.count >= 3 && SelectedIndexpath.contains(indexPath){
cell.backgroundColor = .red
}else{
cell.backgroundColor = .white
}
cell.accessoryType = SelectedIndexpath.contains(indexPath) ? .checkmark : .none
cell.textLabel?.text = "\(indexPath.row)"
return cell
}

how to use number of static cells in UITableView using XIB's

I have been trying to use static cells using XIB's ,But in cell for row at index path I am getting an error like "Cannot convert return expression of type 'UITableViewCell.Type' to return type 'UITableViewCell'" at the line of " return UITableViewCell".Can any one help me to do this ,Thanks in advance.
extension TriipDetailsViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0
{
let cell : TripDriverDetailsCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripDriverDetailsCell", for: indexPath) as! TripDriverDetailsCell
return cell
}else if indexPath.row == 1 {
let cell : TripFareDetailsCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripFareDetailsCell", for: indexPath) as! TripFareDetailsCell
return cell
}else if indexPath.row == 2 {
let cell : TripPaymentModeCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripPaymentModeCell", for: indexPath) as! TripPaymentModeCell
return cell
}
return UITableViewCell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.row == 0{
return 230
}else if indexPath.row == 1{
return 200
}else if indexPath.row == 2{
return 120
}
}
}
Eliminate the return UITableViewCell.
Some people might say return UITableViewCell(), but I’d rather handle this case as the error that it really is, e.g.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.row {
case 0:
return tableView.dequeueReusableCell(withIdentifier: "TripDriverDetailsCell", for: indexPath)
case 1:
return tableView.dequeueReusableCell(withIdentifier: "TripFareDetailsCell", for: indexPath)
case 2:
return tableView.dequeueReusableCell(withIdentifier: "TripPaymentModeCell", for: indexPath)
default:
fatalError("Unexpected row number \(indexPath.row)")
}
}
The heightForRowAt should similarly handle the scenario where the indexPath.row is not 0, 1, or 2, e.g.:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath.row {
case 0: return 230
case 1: return 200
case 2: return 120
default: fatalError("Unexpected row number \(indexPath.row)")
}
}
let cell : UITableViewCell
if indexPath.row == 0
{
cell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripDriverDetailsCell", for: indexPath) as! TripDriverDetailsCell
}else if indexPath.row == 1 {
cell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripFareDetailsCell", for: indexPath) as! TripFareDetailsCell
}else if indexPath.row == 2 {
cell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripPaymentModeCell", for: indexPath) as! TripPaymentModeCell
}else {
cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
}
return cell
}
You've got
Cannot convert return expression of type 'UITableViewCell.Type' to return type 'UITableViewCell
because you return a cell as return UITableViewCell that means you return a whole UITableViewCell class instead of single UITableViewCell() therefore in the last you've to return cell as return UITableViewCell()
e.g.
extension TriipDetailsViewController: UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0
{
let cell : TripDriverDetailsCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripDriverDetailsCell", for: indexPath) as! TripDriverDetailsCell
return cell
}else if indexPath.row == 1 {
let cell : TripFareDetailsCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripFareDetailsCell", for: indexPath) as! TripFareDetailsCell
return cell
}else if indexPath.row == 2 {
let cell : TripPaymentModeCell = tripDetailsTableView.dequeueReusableCell(withIdentifier: "TripPaymentModeCell", for: indexPath) as! TripPaymentModeCell
return cell
}
return UITableViewCell() //Here you've to change
}

Not Recognizing Clicked Cell UITableView inside UITableViewCell using NIB

I'm writing an app that have a dashboard with multiple cells. One of the cells have a question, but the answer are dynamically filled, so I decided to use a UITableView to handle it.
I set the the UITableViewCell as the delegate and dataSource of the internal UITableView and made the configurations for define the cell and the selected state.
extension SurveyTableViewCell: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
answers = model.getSurveyAnswers()
return (answers?.count)!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier, for: indexPath) as! InsideSurveyTableViewCell
cell.idAnswer.text = alphabetQuestion[indexPath.row]
cell.answer.text = answers?[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 100.0
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier, for: indexPath) as! InsideSurveyTableViewCell
cell.selectRow()
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier, for: indexPath) as! InsideSurveyTableViewCell
cell.deselectRow()
}
}
But the click inside the cell in the internal UITableViewCell is not recognized. I need to recognize this click to after send the user answer to the server.
I saw some solutions, but using storyboard. I use only nib's on my projects.
But I still tried with an approach that I saw on youtube wich uses storyboard.
On the cell that will use the internal UITableView I declared a function to set the delegate and dataSource of the internal tableView and gave to it a tag.
extension SurveyTableViewCell {
func setTableViewDataSourceDelegate<D:UITableViewDelegate & UITableViewDataSource>(_ dataSourceDelegate: D, forRow row: Int) {
subTableView.dataSource = dataSourceDelegate
subTableView.delegate = dataSourceDelegate
subTableView.reloadData()
}
}
Than on the viewController that manage the outer UITableView:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView.tag == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier) as! InsideSurveyTableViewCell
cell.idAnswer.text = "A."
cell.answer.text = "QUALQUER COISA"
return cell
}
if retrivedCell is SurveyTableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: SurveyTableViewCell.identifier, for: indexPath) as! SurveyTableViewCell
cell.delegate = self
cell.setTableViewDataSourceDelegate(self, forRow: indexPath.row)
cell.setPositionRow(row: indexPath.row - 1)
cell.subTableView.rowHeight = UITableViewAutomaticDimension
cell.subTableView.estimatedRowHeight = 50
return cell
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView.tag == 1 {
return 3
}
var numberOfCells: Int = 0
if cellsToPresent != nil {
numberOfCells = cellsToPresent!.count
}
return numberOfCells + 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.tag == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier) as! InsideSurveyTableViewCell
cell.selectRow()
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if tableView.tag == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: InsideSurveyTableViewCell.identifier) as! InsideSurveyTableViewCell
cell.deselectRow()
}
}
The selectRow and deselectRow are methods to change the label of the cell of the inner tableView.
But still without success.
if I use the method:
tableView.dequeueReusableCell(withIdentifier: identifier, for: indexPath)
The app break complaining that I'm trying to dequeue different cells with the same indexPath.
Thanks for your help.
Don't use
let cell = tableView.dequeueReusableCell(withIdentifier:) in didSelect or didDeSelect methods.
Use
let cell = tableView.cellForRow(at: indexPath)
I hope this will help you.

Limit number of selected cells by section in TableView

I've spent a lot of time searching a solution to limit the number of selected cells in a UITableView.
Here is a piece of code I found :
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let selectedRows = tableView.indexPathsForSelectedRows {
if selectedRows.count == limit {
return nil
}
}
return indexPath
}
The problem is that tableView.indexPathsForSelectedRows contains selected cells that are VISIBLE and from any section.
Does a property like : tableView.selectedCellsForSection(section: 0) exist ?
Thanks for your help !
UPDATE 1
This is an example with a car that containts several options
var selectedOptions = [IndexPath : Option]() // Option can be for example, the color of the car
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
let maxOptionForSection = car.options![indexPath.section]?.max
let numberOfSelectedOptions = selectedOptions.filter { $0.key.section == indexPath.section }
if numberOfSelectedOptions.count == maxOptionForSection {
return nil
}
return indexPath
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? OptionCell {
cell.checkButton.isChecked = true
cell.option.isSelected = true
selectedOptions[indexPath] = cell.option
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? OptionCell {
cell.checkButton.isChecked = false
cell.option.isSelected = false
selectedOptions.removeValue(forKey: indexPath)
}
}
SOLUTION
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let optionCell = cell as! OptionCell
if optionCell.option.isSelected {
optionCell.checkButton.isChecked = true
} else {
optionCell.checkButton.isChecked = false
}
}
This will limit it to the section in which the row was clicked:
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
if let selectedRows = tableView.indexPathsForSelectedRows?.filter({ $0.section == indexPath.section }) {
if selectedRows.count == limit {
return nil
}
}
return indexPath
}

Multiple checkmark in Tableview in swift3

How to do the multiple checkmark in tableview. I need to select the multiple checkmark in tableview and what are the checkmarks I need to select to place the multiple values in label.
Example player1,player2,player3 in label
here is my code
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return TypeOfAccountArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! UITableViewCell
let cell:TypeofAccountCell=tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TypeofAccountCell
cell.Uertype_lbl.text=TypeOfAccountArray[indexPath.row]
cell.selectionStyle = UITableViewCellSelectionStyle.none;
cell.Uertype_lbl.font = UIFont(name:"Roboto-Regular", size:13)
cell.Uertype_lbl.adjustsFontSizeToFitWidth = true
if (selectedIndex == indexPath as NSIndexPath?) {
cell.checkmarkbtn.setImage(UIImage(named: "checkmark.png"),for:UIControlState.normal)
} else {
cell.checkmarkbtn.setImage(UIImage(named: "uncheckmark.png"),for:UIControlState.normal)
}
// Configure the cell...
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
let row = indexPath.row
print(TypeOfAccountArray[row])
selectedIndex = indexPath as NSIndexPath?
self.Type_of_account_txt.text = (TypeOfAccountArray[row])
self.Type_account_view.isHidden = true
tableView.reloadData()
}
Change your selectedindex to hold array of index path var selectedIndexes = [IndexPath](), on your cell xib, set your checkmark image on button selected stated and uncheckmark image on normal status and use the below code.
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TypeOfAccountArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell:TypeofAccountCell=tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TypeofAccountCell
cell.Uertype_lbl.text=TypeOfAccountArray[indexPath.row]
cell.selectionStyle = UITableViewCellSelectionStyle.none;
cell.Uertype_lbl.font = UIFont(name:"Roboto-Regular", size:13)
cell.Uertype_lbl.adjustsFontSizeToFitWidth = true
// Configure the cell...
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath as IndexPath, animated: true)
let cell:TypeofAccountCell=tableView.cellForRow(at: indexPath) as! TypeofAccountCell
if selectedIndexes.contains(indexPath)
{
cell.checkmarkbtn.isSelected = false
if let index = selectedIndexes.index(of: indexPath) {
selectedIndexes.remove(at: index)
}
}
else
{
cell.checkmarkbtn.isSelected = true
selectedIndexes.append(indexPath)
}
}
self.Type_of_account_txt.text = ""
for element in selectedIndexes
{
self.Type_of_account_txt.text = (self.Type_of_account_txt.text ?? "") + "\(TypeOfAccountArray[element.row]) ,"
}
if (selectedIndexes.count > 0)
{
self.Type_of_account_txt.text = self.Type_of_account_txt.text?.substring(to: (self.Type_of_account_txt.text?.index(before: (self.Type_of_account_txt.text?.endIndex)!))!)
}
}
you need to follow this step :
In didSelectRowAt, you need to add and remove indexpath in array for multiple checkmark.
Now , in cellForRowAtIndexPath you need to check that current
indexPath consist in array .
if (![arrIndexPath containsObject: indexPath]) {
// do something
cell.checkmarkbtn.setImage(UIImage(named: "checkmark.png"),for:UIControlState.normal)
}

Resources