UITableView with different optional sections?
This looks like my way of approaching such problems. I'm using enums (Obj-C & especially Swift) to handle and identify my Sections and I always return the full amount of potential sections:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return FormSection.count // enum function
}
In func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
, however, I switch the unused sections off by returning 0 rows.
The benefit I saw after struggling with your type of dynamic tables was that all sections are always at the same index which made cell management relatively easy:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let section:FormSection = FormSection(rawValue:indexPath.section)!
switch section {
case .Header:
//…
default:
//…
}
}
The same goes for section headers/footers:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
switch section {
case FormSection.Header.rawValue:
return nil
case FormSection.RoomSetup.rawValue where foo == false:
return nil
default:
// return header with title = FormSection(rawValue: section)?.headerTitle()
// Swift enums ftw ;)
}
And the number of rows is calculated/fetched at runtime:
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let section:FormSection = FormSection(rawValue:section)!
switch section {
case .Section1:
return fooExpanded ? (numberOfFoo) : 0
case .Section2:
return model.barCount()
default:
return 1
}
}
How To use different segues for different UTableView Sections and pass data
First of all you don't need to get the cell in your 'didSelectRowAtIndexPath' method, so the first line where you create a reference to the cell is unnecessary.
You have an index path that has a row and section index within it, use that to obtain the data out of your sectionItems array e.g
let data = sectionItems[indexPath.section][indexPath.row]
switch indexPath.section {
case 0:
self.performSegueWithIdentifier("sectionOneSegue", sender: data)
case 1:
self.performSegueWithIdentifier("sectionTwoSegue", sender: data)
default:
break
}
That should be all you need within that method.
You can then override the prepareForSegue method and check the segue.identifier property to see which segue has been performed and extract the destinationViewController from there. Once you have the view controller you can pass your data to it through a property on the view controller.
if segue.identifier == "sectionOneSegue" {
guard let data = sender as? String,
newViewController = segue.destinationViewController as? NewViewController else {
return
}
newViewController.data = data
}
In the above code I'm making sure that the sender is the expected data type (the one sent from the above performSegueWithIdentifier method) and that the destination controller is the one that I want, then as soon as I know everything is correct I'm setting the property on the destination controller with the data that I want to send to it.
I hope this helps.
CheckBox UITableView with Different Sections
Example using a UIButton
with checked / unchecked background images with an on/off state:
//
// TableWithCheckTableViewController.swift
// SWTemp2
//
// Created by Don Mag on 6/6/17.
// Copyright © 2017 DonMag. All rights reserved.
//
import UIKit
class MyCheckTableViewCell: UITableViewCell {
@IBOutlet weak var myLabel: UILabel!
@IBOutlet weak var myCheckButton: UIButton!
var checkedImage = UIImage(named: "Checked")
var unCheckedImage = UIImage(named: "UnChecked")
var isOn: Bool = false {
didSet {
myCheckButton.setBackgroundImage(self.isOn ? checkedImage : unCheckedImage, for: .normal)
}
}
var checkTapAction : ((Bool)->Void)?
@IBAction func buttonTapped(_ sender: Any) {
self.isOn = !self.isOn
checkTapAction?(self.isOn)
}
}
// simple data object
class MyCheckObject: NSObject {
var theTitle = ""
var theCheckState = false
init(_ title: String) {
theTitle = title
}
}
class TableWithCheckTableViewController: UITableViewController {
// array of MyObjects
var myData = [MyCheckObject]()
override func viewDidLoad() {
super.viewDidLoad()
// just to make it a little easier to see the rows scroll
tableView.rowHeight = 60
// create 40 data objects for the table
for i in 1...40 {
let d = MyCheckObject("Data Item: \(i)")
myData.append(d)
}
tableView.reloadData()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MyCheckTableViewCell", for: indexPath) as! MyCheckTableViewCell
// Configure the cell...
let d = myData[indexPath.row]
cell.myLabel.text = d.theTitle
cell.isOn = d.theCheckState
// set a "Callback Closure" in the cell
cell.checkTapAction = {
(isOn) in
// update our Data Array to the new state of the switch in the cell
self.myData[indexPath.row].theCheckState = isOn
}
return cell
}
}
How to show multiple customcell and a custom section header in one uitableview?
Try to keep as few types of cells as you can. If one type cell is similar to another but with one or two extra labels, just set it all up in the same cell and keep the labels empty on the cell that doesn't need them. That way they can be in the same reuse queue. If the cells are different enough you might need to have more queues. Just instantiate them with a different cellIdentifier
and they will get added to the queue for that identifier.
eg.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:@"firstRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:@"firstRowCell"];
}
// -- first cell setup
} else {
cell = [tableView dequeueReusableCellWithIdentifier:@"genericRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:@"genericRowCell"];
}
// -- generic cell setup
}
// -- common cell setup
return cell;
}
Related Topics
Get Section Number in Custom Cell Button Action
Ios11 Uibarbuttonitem Not Working
Adding Firebase Data to an Array in iOS Swift
Add View as a Parameter to a Custom Viewmodifier
Nsfetchedresultscontroller Swift Sections
How to Detect Which Image Has Been Tapped in Swift
How to Add Two or More Buttons to Annotationview: Mkannotationview
Which Passes How to Access in Apple Wallet
Uitableviewcell Initwithstyle:Uitableviewcellstylesubtitle Is Not Working
Saving an Image to Photos Library Using Swift 2.0
Custom Uibutton Class for Button Touch Event
Stream Data from Network in Avaudioengine, Is It Possible
Dynamically Passing Closure with Keypaths to a Sorting Function
Horizontal Paging Uicollectionview with Automatic Item Size in a Vertical Stack View
How to Crop Image in Circle Shape with Grid Inside Circle
Nsurlsession/Nsurlconnection Http Load Failed (Kcfstreamerrordomainssl, -9802) on a Subdomain