switching between different classes for UITableViewCell - ios

I have two data sources, and two different classes for custom cells in my table.
I want by pressing one button to switch between sources and classes and update my UITableView accordingly.
Unfortunately It works only one time I switch from one set to another. It doesn't return back.
Hope my code will help to explain what I mean:
var displayMode : Int = 1
#objc func tappedButton(_ sender: UIButton?) {
if displayMode == 1 {
displayMode = 2
myTable.reloadData()
} else {
displayMode = 1
myTable.reloadData()
}
}
override func tableView(tableView: UITableView,
cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if displayMode == 1 {
let cell = tableView.dequeueReusableCellWithIdentifier(cellId,
forIndexPath: indexPath) as! Class1
cell.taskTitle.text = source1.text
return cell
}
else {
let cell = tableView.dequeueReusableCellWithIdentifier(cellId,
forIndexPath: indexPath) as! Class2
cell.taskTitle.text = source2.text
return cell
}
}
Should I delete table cells before changing mode?

You use the same cellID in
let cell = tableView.dequeueReusableCellWithIdentifier(cellId,
forIndexPath: indexPath) as! Class1
and
let cell = tableView.dequeueReusableCellWithIdentifier(cellId,
forIndexPath: indexPath) as! Class2
Should be two different cells for 2 different classes (2 different IDS)

1) You need to create 2 separate classes for cells:
class FirstCellClass: UITableViewCell {}
class SecondCellClass: UITableViewCell {}
2) Then register the cells(or add cells in Storyboard):
tableView.register(FirstCellClass.self, forCellReuseIdentifier: String(describing: FirstCellClass.self))
tableView.register(SecondCellClass.self, forCellReuseIdentifier: String(describing: SecondCellClass.self))
3) Check display mode and return specific cell cellForRowAtIndexPath and items count in numberOfRowsInSection:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch displayMode {
case .first:
return firstDataSource.count
case .second:
return secondDataSource.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch displayMode {
case .first:
let cell = tableView.dequeueReusableCell(
withIdentifier: String(describing: FirstCellClass.self),
for: indexPath
) as! FirstCellClass
configureFirstCell(cell)
return cell
case .second:
let cell = tableView.dequeueReusableCell(
withIdentifier: String(describing: SecondCellClass.self),
for: indexPath
) as! SecondCellClass
configureSecondCell(cell)
return cell
}
}

Related

Passing TableViewCell to a new TableView (at the top) Swift

What I want to do:
I have a feed (TableView( and once the user taps on a Post (TableViewCell), he should see a new Page (TableView) with the Post he tapped on first (the same TableViewCell) on top and a couple of comments below.
My Problem:
I dont get how to "clone" that TableViewCell.
Here two pictures for a better understanding:
Some complications:
I have multiple post types in the main feed, so the code would have to differentiate between them to see which cell type to use to display the content.
My code:
Main Feed
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return mixed.count
}
else if section == 1{
return phots.count
}
else{
return texttt.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = tableView.dequeueReusableCell(withIdentifier: mixedTableViewCell.identifier, for: indexPath) as! mixedTableViewCell
cell.configure(with: self.mixed[indexPath.row])
return cell
}
else if indexPath.section == 1{
let cell = tableView.dequeueReusableCell(withIdentifier: popularTableViewCell.identifier, for: indexPath) as! popularTableViewCell
cell.configure(with: self.phots[indexPath.row])
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: self.texttt[indexPath.row])
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "commentsVC")
vc.modalPresentationStyle = .fullScreen
self.navigationController?.pushViewController(vc, animated: true)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
My second ViewController
class CommentsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var table: UITableView!
var texty = [TextComment]()
override func viewDidLoad() {
super.viewDidLoad()
table.register(popularTableViewCell.nib(), forCellReuseIdentifier: popularTableViewCell.identifier)
table.register(featuredTableViewCell.nib(), forCellReuseIdentifier: featuredTableViewCell.identifier)
table.register(textTableViewCell.nib(), forCellReuseIdentifier: textTableViewCell.identifier)
table.register(mixedTableViewCell.nib(), forCellReuseIdentifier: mixedTableViewCell.identifier)
table.register(textComTableViewCell.nib(), forCellReuseIdentifier: textComTableViewCell.identifier)
table.delegate = self
table.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return 1
}
else{
return 15
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: textComTableViewCell.identifier, for: indexPath) as! textComTableViewCell
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0{
// self.table.estimatedRowHeight = 250
// self.table.rowHeight = UITableView.automaticDimension
// return UITableView.automaticDimension
return 300
}
else{
// self.table.estimatedRowHeight = 150
// self.table.rowHeight = UITableView.automaticDimension
// return UITableView.automaticDimension
return 150
}
}
Note
Right now the it isnt working at all, how I want it. I just have these "mock" posts as space-fillers in there.
Any help or ideas would be greatly appreciated!
My structs
struct PhotoPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let postImageName: String
let postID: String
}
struct TextPost {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
let postID: String
}
struct MixedPhoto {
let numberOfComments: Int
let username: String
let timestampName: String
let userImageName: String
let textName: String
let postImageName: String
let postID: String
}
Here my errors:
Each instance of UITableView has its own pool of cells, for this reason it would not be correct to "steal" an instance of the cell from one UITableView and put it into another. Also, as far as i can see you already have a convenient way to feed your cells with data, and dequeue corresponding types. Thus the only thing left here is to pass the required data from MainFeed under your tableView(_: didSelectRowAt:) function, something like that:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: "commentsVC") as? CommentsViewController else {
return
}
switch indexPath.section {
case 0:
vc.mixedData = mixed[indexPath.row]
case 1:
vc.photoData = photos[indexPath.row]
default:
vc.textData = texttt[indexPath.row]
}
vc.modalPresentationStyle = .fullScreen
navigationController?.pushViewController(vc, animated: true)
}
And then, under the CommentsViewController's tableView(_:, cellForRowAt:) function, implement pretty much the same stuff you did in MainFeed:
var mixedData: MixedPhoto?
var photoData: PhotoPost?
var textData: TextPost?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell: UITableViewCell
switch (mixedData, photoData, textData) {
case (.some(let value), _, _):
cell = tableView.dequeueReusableCell(withIdentifier: mixedTableViewCell.identifier, for: indexPath) as! mixedTableViewCell
cell.configure(with: value)
case (_, .some(let value), _):
cell = tableView.dequeueReusableCell(withIdentifier: popularTableViewCell.identifier, for: indexPath) as! popularTableViewCell
cell.configure(with: value)
case (_, _, .some(let value)):
cell = tableView.dequeueReusableCell(withIdentifier: textTableViewCell.identifier, for: indexPath) as! textTableViewCell
cell.configure(with: value)
default:
fatalError("The data is not set")
}
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: textComTableViewCell.identifier, for: indexPath) as! textComTableViewCell
return cell
}
}
Also I should say that it's a good idea to implement a common protocol for your data types, so you actually can define a single non-optional variable in the CommentsViewController instead of three optionals.

Dynamic Custom TableView Cell swift

I have an application where I used table view with custom cells which works fine. The problem I am having now is I want to make it dynamic by this, the number of cell is not fixed. That is, the cell could be 1, 2, 3 or 5, depending on the count of an array. This cell UI varies, too
Cell1: could have an image and a label.
Cell2: could have two labels.
Cell3: could have a dayPicker.
this is the way to create the cells when I know the number returned
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "firstTableCell") as! FirstTableCell
// Set up cell.label
return cell
} else if indexPath.row == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "secondTableCell") as! SecondTableCell
// Set up cell.button
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "thirdTableCell") as! ThirdTableCell
// Set up cell.textField
return cell
}
}
but now numberOfRowsInSection varies and so those the view items.
how can I do this? Programmatically or otherwise, programmatically preferred.
A dynamic table view can be accomplished with an appropriate data model.
For example use an enum for the kind and a struct with a member to indicate the kind
enum CellKind {
case image, label, picker
}
struct Model {
let kind : CellKind
// other struct members
}
How many cells are displayed depends on the items in the data source array
var items = [Model]()
In numberOfRows return the number of items
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
In cellForRow display the cells depending on the kind rather than on the index path
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.row]
switch item.kind {
case .image:
let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell") as! ImageCell
// Set up cell.image
return cell
case .label:
let cell = tableView.dequeueReusableCell(withIdentifier: "labelCell") as! LabelCell
// Set up cell.label
return cell
case .picker:
let cell = tableView.dequeueReusableCell(withIdentifier: "pickerCell") as! PickerCell
// Set up cell.picker
return cell
}
}

Show two different custom cells in same uitableview - swift firebase

I am currently having a problem with displaying two different types of custom cells on the same uitableview.
What I have managed so far, is receiving the "updates" to the update cell, known as cell. I just cannot figure out how to also get numberOfRowsInSection to return two values, so both of my cells will show.
Let me explain through my code:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return updates.count
return updatesTask.count // I CANNOT DO THIS - what can I do instead?
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
let update = updates[indexPath.row]
let updateTask = updatesTask[indexPath.row]
// Example of the two different cells that need different data from firebase
cell.nameLabel.text = update.addedByUser
cellTask.nameLabel.text = updateTask.addedByUser
As you can probably see, the let updateTask is trying to get an indexPath.row but that is not possible, since I cannot have two return values in the numberOfRowsInSection, which is a problem because that number is referring to the place where the data is stored in my firebase database.. How can I modify this to make it work?
Hope you guys understand where I am going with this, otherwise let me know and I will try to explain better :-)
#Callam's answer is great if you want to put them in two sections.
This is the solution if you want all to be in one section.
First, in numberOfRowsInSection method you need to return the sum of those two array counts like this: return (updates.count + updatesTask.count)
Then you need to configure cellForRowAtIndexPath method like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row < updates.count{
// Updates
let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let update = updates[indexPath.row]
cell.nameLabel.text = update.addedByUser
return cell
} else {
// UpdatesTask
let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
let updateTask = updatesTask[indexPath.row-updates.count]
cellTask.nameLabel.text = updateTask.addedByUser
return cellTask
}
}
This will display all cells followed by all cellTasks.
If updates array and updatesTask array have equal number of items and you want to display them one by one you can use this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row % 2 == 0 {
// Updates
let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let update = updates[indexPath.row/2]
cell.nameLabel.text = update.addedByUser
return cell
} else {
// UpdatesTask
let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
let updateTask = updatesTask[indexPath.row/2]
cellTask.nameLabel.text = updateTask.addedByUser
return cellTask
}
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
return updates.count
case 1:
return updatesTask.count
default:
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let update = updates[indexPath.row]
cell.nameLabel.text = update.addedByUser
return cell
case 1:
let cell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
let updateTask = updatesTask[indexPath.row]
cell.nameLabel.text = updateTask.addedByUser
return cell
default:
return UITableViewCell()
}
}
For each row you have to choose if you want to display one type of cell or the other but not both. You should have a flag in numberOfRowsInSection telling your method that you want to load Cell or CellTask and then return the correct number of rows.
You should return total number of rows in your numberOfRowsInSection method. so you can return summation of your both array's count something like,
return updates.count + updatesTask.count
now in your cellForRowAtIndexPath method you can differentiate your cell something like,
let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
if indexPath.row % 2 == 1 {
//your second cell - configure and return
return cellTask
}
else
{
//your first cell - configured and return
return cell
}
I am not sure what you want to achieve. If you want to display the number of cells updates[] and updatesTask[] have elements you can do it like this
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (updates.count + updatesTask.count)
}
then you can modify your cellForRowAtIndexPath method like this:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:updateTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! updateTableViewCell
let cellTask:tasksTableViewCell = tableView.dequeueReusableCellWithIdentifier("TaskCell", forIndexPath: indexPath) as! tasksTableViewCell
if indexPath.row < updates.count{
//update
let update = updates[indexPath.row]
cell.nameLabel.text = update.addedByUser
}else{
let updateTask = updatesTask[indexPath.row]
cellTask.nameLabel.text = updateTask.addedByUser
}
return cell
}
with the if condition you can choose from which array you are taking data.
But be careful to name an array exactly the same as another constant like you did here
let updateTask = updatesTask[indexPath.row]
You can create a simple View Model, that will hold the multiple item types:
enum ViewModelItemType {
case nameAndPicture
case about
case email
case friend
case attribute
}
protocol ViewModelItem {
var type: ViewModelItemType { get }
var rowCount: Int { get }
var sectionTitle: String { get }
}
Then create a model item type for each section. For example:
class ViewModelNameAndPictureItem: ViewModelItem {
var type: ProfileViewModelItemType {
return .nameAndPicture
}
var sectionTitle: String {
return “Main Info”
}
var rowCount: Int {
return 1
}
var pictureUrl: String
var userName: String
init(pictureUrl: String, userName: String) {
self.pictureUrl = pictureUrl
self.userName = userName
}
}
Once you configure all your section items with, you can save them in ViewModel:
class ProfileViewModel {
var items = [ViewModelItem]()
}
And add to you TableViewController:
let viewModel = ViewModel()
In this case, NumberOfSections, NumberOfRows and CellForRowAt methods will be clean and simple:
override func numberOfSections(in tableView: UITableView) -> Int {
return viewModel.items.count
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModel.items[section].rowCount
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = viewModel.items[indexPath.section]
switch item.type {
// configure celll for each type
}
}
Configuring the section title will also be very neat:
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return viewModel.items[section].sectionTitle
}
Please check my recent tutorial on this topic, that will answer your question with the details and examples:
https://medium.com/ios-os-x-development/ios-how-to-build-a-table-view-with-multiple-cell-types-2df91a206429

TableViewCell not updating properly swift 2.2

In my app I created two custom tableview cells.
Problem I am facing now the second tableview cell update with last element of the array only.
In cellForRowAtIndexpath array elements are displaying fine.
Consider [ "Value1", "Value2" ] is my array. In tableView only value2 is displaying in two cells.
var title = ["value1","value2"]
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let row = indexPath.row
let x = Id[indexPath.row]
if x == 0{
let cell1 = tableView.dequeueReusableCellWithIdentifier("Cell1", forIndexPath: indexPath) as! MyCell1
return cell1
}
else{
let cell2 = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as! MyCell2
for index in 0..<myArray.count{
cell2.titleButton.setTitle(title[index],forState:UIControlState.Normal)
}
return cell2
}
}
I am stuck here, your help will be appreciated.
Following is the solution, reason it was going out of range was because value incremented when cell were dequed as cellforrowAtIndexPath was called every time we scrolled down(since some cells were not visible and these cells were dequed when we scrolled down):-
var name = ["HouseBolo","HouseBolo1","HouseBolo2","HouseBolo3"]
var propertyVal:Int = 0
var projectVal:Int = 0
var type = ["Apartment","Villa","Home","Flat","Plot"]
var arrangedData = [String]()
var flatId = [0,1,2,0,0]
override func viewDidLoad() {
super.viewDidLoad()
// I want the Expected Output in Tableview Cell is
// 1. Apartment 2. HouseBolo 3. HouseBolo1 4. Villa 5. Home
for item in flatId {
if item == 0 {
arrangedData.append(type[propertyVal])
propertyVal+=1
}
else {
arrangedData.append(name[projectVal])
projectVal+=1
}
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrangedData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let flatDetails = flatId[indexPath.row]
// For Property Cell
if flatDetails == 0{
let cell = tableView.dequeueReusableCellWithIdentifier("Cell1", forIndexPath: indexPath) as? PropertyCell
if(cell != nil) {
cell!.pType.text = arrangedData[indexPath.row]
}
return cell!
}
// For Project Cell
else {
let cellan = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as? ProjectCell
if(cellan != nil) {
cellan!.projectName.setTitle(arrangedData[indexPath.row], forState: UIControlState.Normal)
}
return cellan!
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
You need to use :
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! searchCell
in :
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {}
block.
searchCell : is a class of type : UITableViewCell
After that, go in Storyboard and change the identifier of your cell with : "cell"
In the code...
let cell2 = tableView.dequeueReusableCellWithIdentifier("Cell2", forIndexPath: indexPath) as! MyCell2
for index in 0..<myArray.count{
cell2.titleButton.setTitle(title[index],forState:UIControlState.Normal)
}
return cell2
you are iterating over 'myArray' and assigning the value to 'cell2.titleButton'. Cell 2 will always have the last value assigned to it's title. It's assigning it to 'value1', then reassigning it to 'value2'. Looping through the array seems to be the issue (assuming the cells are displaying - just always showing the title from the last item in the array.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
}
You have to add your custom tableview cell class name in the place of UITableViewCell
Something like this -
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> **custom tableview cell class name**
{
}
And also in Storyboard ,change the identifier of your cell with : "cell1" and "cell2"

How to reuse cells in a UITableView?

I'm running into some problems today in my application. I'm using a UITableView to present different cells some contain a specific button, some display a game your currently in, some are just for spacing between cells.
However im running into some problems when I do tableView.reloadData().
When I click on 'new game' a new game cell should be added, but instead of that the last cells are moved down (like expected, because something comes in between), however the upper cells that should change, they don't. I expect this to be because of reusing (or "caching"). Maybe someone can help me out on how to fix this.
Here is an image of what is happening explanation
Now I have different cells, all with their own Identifiers for example: "Emptycell", "Gamecell", "startnewgameBtnCell". I do this because I create each cell in storybuilder.
here is my code for cellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
}
return cell
In this code I check if its a gamecell or not, emptycells or cells that contain a label or button are all FirstMenuTableViewCell. Only GameCell have their own class GameViewCell.
I have also double checked to see if my identifiers are build up correctly and they are.
Maybe someone can explain me exactly whats happening and what might be the correct approach to solve the situation I'm in, I think I may not fully understand how to use UITableViewCell with custom cells.
Thanks for reading
You create new variables called cell in the if statements. You are hiding the outer cell.
Use one cell variable.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
}
return cell
}
Try update your code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = UITableViewCell()
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}
if ((cell_identifiers[indexPath.row][1] as! String) == "NOT" ) {
var cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
return cell
if me, i coded:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier = cell_identifiers[indexPath.row][0] as! String
if ((cell_identifiers[indexPath.row][1] as! String) == "MYTURN" ) {
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}else { // if you sure just have 2 cell type
let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
}
But i think you should use section in tableview,it is better. So, you have 3 section, and 2 headerofsection in there. the first section have 1 row, the second have self.myTurnMatches.count row.... :
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section == 0 || section == 1{
return 44
}else{
return 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.section == 1{
let cell = tableView.dequeueReusableCellWithIdentifier("GameViewCell 's identifier", forIndexPath: indexPath) as! GameViewCell
let match = self.myTurnMatches[indexPath.row - 4]
setupGameViewCellObject(match)
return cell
}else{
let cell = tableView.dequeueReusableCellWithIdentifier("FirstMenuTableViewCell 's identifier", forIndexPath: indexPath) as! FirstMenuTableViewCell
return cell
}
}

Resources