IndexPath values are changing while scrolling UITableviewcells? - ios

While moving from first view controller to second view controller I'm saving indexpaths in a array and in the return when loading a table in first view controller, if the current indexpath is in the saved indexpaths array I have to create a custom accessory button.
But, when scrolling UITableview along with the required cell another cell also getting custom button. When I'm printing the NSindexPaths while scrolling I'm getting random values instead of normal one's.
For the above I'm using the following code:
- (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
// NSLog(#"newdata value is =%d",newData);
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
UITableViewCell *cell = [self.positionsTable dequeueReusableCellWithIdentifier:#"playersInPosition"];
if (cell == nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"playersInPosition"]autorelease];
}
UILabel *lblName = (UILabel *)[cell viewWithTag:100];
[lblName setText:[inputData objectAtIndex:[indexPath row]]];
UILabel *pname = (UILabel *)[cell viewWithTag:102];
[pname setText:[appDelegate.playersNFL objectAtIndex:[indexPath row]]];
for (NSIndexPath *object in appDelegate.indexPathList) {
if ([object isEqual:indexPath]) {
NSLog(#"saved index path values are =%#",appDelegate.savedIndexPath);
UIButton *button = [self ChangeAccessoryButtonStyle:appDelegate.indexPathList[0]];
cell.accessoryView = button;
}
}
return cell;
}

I don't remember any part of documentation saying the index-paths are meant to be reused by a table view, it might be a good idea then to compare the objects with a designed function:
compare:
Indicates the depth-first traversal order of the receiving
index path and another index path.
-(NSComparisonResult)compare:(NSIndexPath *)indexPath
Parameters
indexPath Index path to compare. This value must not be nil. If the
value is nil, the behavior is undefined.
Return Value
The depth-first
traversal ordering of the receiving index path and indexPath.
NSOrderedAscending: The receiving index path comes before indexPath.
NSOrderedDescending: The receiving index path comes after indexPath.
NSOrderedSame: The receiving index path and indexPath are the same
index path.
Availability
Available in iOS 2.0 and later.
Declared In
NSIndexPath.h

Try to remove this line and create cell each time.
UITableViewCell *cell = [self.positionsTable dequeueReusableCellWithIdentifier:#"playersInPosition"];

Related

tableview viewWithTag not retrieving UIElements objective-c

I am doing using some code that I have seen work before. Essentially a user answers yes or no on a post with some buttons. Pressing yes or no updates the database, which is working correctly, and it also updates the visible UI, which is not working. This UI updates the buttons so they one is selected, other is highlighted and both are disabled for user interaction. Also it makes changes to two UILabels. The method that these buttons calls needs to update the database and retrieve the buttons from the tableViewCell and update the changes I have the methods working in another ViewController so I can not understand the difference here. Here is my cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *simpleTableIdentifier = [NSString stringWithFormat:#"%ld,%ld",(long)indexPath.section,(long)indexPath.row];
NSLog(#" simple: %#",simpleTableIdentifier);
if (indexPath.row==0) {
ProfileFirstCell *cell = [self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[ProfileFirstCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
cell = [self createProfileCell:cell];
return cell;
}else{
YesNoCell *cell =[self.tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell==nil) {
cell=[[YesNoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell = [self createYesNoCell:cell:indexPath];
return cell;
}
}
Essentially what this does is create the users profile in the first cell, and load all the questions that user asks. This is the major difference I see between the old tableView and this tableView. In createYesNoCell I create the UIElements and create tags as follows
cell.yesVoteButton.tag=indexPath.row+ yesVoteButtonTag1;
cell.noVoteButton.tag=indexPath.row+ noVoteButtonTag1;
cell.yesCountLabel.tag=indexPath.row+ yesCountLabelTag1;
cell.noCountLabel.tag=indexPath.row+ noCountLabelTag1;
The buttons have the selector that initiates a number of things. It finds which button was pressed by the following.
NSInteger index;
if(sender.tag>=yesVoteButtonTag1){
NSLog(#"Yes button pressed");
votedYes=true;
index=sender.tag-yesVoteButtonTag1;
}else{
NSLog(#"No button Pressed");
votedYes=false;
index=sender.tag-noVoteButtonTag1;
}
UILabel *yesLabel = (UILabel*) [self.tableView viewWithTag:index+yesCountLabelTag1]; // you get your label reference here
UIButton *yesButton=(UIButton *)[self.tableView viewWithTag:index+1+yesVoteButtonTag1];
NSLog(#"Tag IN METHOD: %ld",index+yesVoteButtonTag1);
UILabel *noLabel = (UILabel*) [self.tableView viewWithTag:index+1+noCountLabelTag1]; // you get your label reference here
UIButton *noButton=(UIButton *)[self.tableView viewWithTag:index+noVoteButtonTag1];
These viewWithTag calls are nil when I look at them. The only difference that I can see from my earlier implementation is that the old one had sections and one row, while this one is all rows and one section. So replacing the indexPath.section with indexPath.row should account for that. Also I checked that the tag made in cellForRowAtIndexPath is the same as the row recovered in the yes/no vote method, because it is displaced by one because of the profile cell being created at indexPath.row==0. I tried passing the cell to the yes/no vote method and tried to recover the buttons and labels with contentView as some suggestions made on similar posts. However this didn't seem to solve my problem. Really would appreciate some insight on this.
have you call the '[tableView reload]' method to update the UITableView, it may helps.
Firstly, the table reuse identifier should be used for types of cells, not one for each cell. You have two types, so you should use two fixed reuse identifiers.
ProfileFirstCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"ProfileCell"];
if (cell == nil) {
cell = [[ProfileFirstCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"ProfileCell"];
}
and
YesNoCell *cell =[self.tableView dequeueReusableCellWithIdentifier:#"YesNoCell"];
if (cell==nil) {
cell=[[YesNoCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"YesNoCell"];
}
Secondly, rather than trying to get a reference to a cell after creating the table, which isn't working for you, you should initialize the cells completely when they are created. (TableView won't create cells unless they're visible, so you shouldn't rely on their existing at all.)
createProfileCell should really be called initializeProfileCell, because you're not creating the cell in it - you already did that in the line above, or recovered an old one.
Then your call to initializeProfileCell can take a flag specifying whether it is a Yes or No cell and set its properties accordingly.
cell = [self initializeProfileCell:cell isYes:(indexPath.section==0)];
Similarly with createYesNoCell --> initializeYesNoCell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"YOURCELL_IDENTIFIER";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
UILabel *title = (UILabel*) [cell viewWithTag:5];
UILabel *vensu =(UILabel*) [cell viewWithTag:7];
vensu.text = #"YOUR TEXT";
title.text = #"YOUR TEXT";
return cell;
}

How to differenciate indexPath of first cell with indexPath of empty space at the end of table?

I use the following code to detect a click on a UITableView and take action depending on which cell is clicked, and which element in the cell was clicked, with a default action for any element that doesn't match.
-(void)addTapRecognizer {
// this is called when the view is created
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleTap:)];
singleTap.delegate = self;
singleTap.numberOfTapsRequired = 1;
singleTap.numberOfTouchesRequired = 1;
[self.tableView addGestureRecognizer:singleTap];
}
- (void)handleTap:(UITapGestureRecognizer *)tap {
NSLog(#"tap detected!");
if (UIGestureRecognizerStateEnded != tap.state) {
return;
}
UITableView *tableView = (UITableView *)tap.view;
CGPoint p = [tap locationInView:tap.view];
NSIndexPath* indexPath = [tableView indexPathForRowAtPoint:p];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
NSLog(#"selectedIndex = %ld", (long)indexPath.row);
// take action depending where the cell was clicked
// with a default action if no element matches
MyTableViewCell *cell = (MyTableViewCell *) [self.tableView cellForRowAtIndexPath:indexPath];
CGPoint pointInCell = [tap locationInView:cell];
if(CGRectContainsPoint(cell.someImage.frame,pointInCell)) {
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
if (...) {
...
return;
}
[self openItemID:[ItemList[indexPath.row] valueForKey:ID_ITEM]];
return;
}
My problem is that when there aren't enough cells to fill the screen (so for instance the table contains 2 cells and then blank space below), when the user clicks below the last cell, this is treated as a click on the first cell (the console logs "selectedIndex = 0" in both cases).
Is there a way to tell the difference between such a click, in the empty space at the end of the table, and a click on a "proper" cell of the table?
Is there a way to tell the difference between such a click, in the empty space at the end of the table, and a click on a "proper" cell of the table?
Yes. For the cheap and easy solution only do what you are trying to do if you actually get an indexPath:
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:p];
if(indexPath != nil){
// do everything in here
}
Basically, your indexPath is returning nil because it can't find a row. From the docs:
An index path representing the row and section associated with point, or nil if the point is out of the bounds of any row.
You could do it the way that you're currently doing it but is there any reason why you aren't using:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
This is a much more standard way of detecting the cell that the user tapped on.
This method won't be called if you tap on something that isn't a cell and has a number of other benefits. Firstly you get a reference to the tableView and the indexPath for free. But you also won't need any gesture recognisers this way either.
Try something like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// Do stuff with cell here...
}
Obviously this all assumes that you have correctly set a class as your table view's delegate.
NB: It's very easy to mistakenly write didDeselectRowAtIndexPath instead of didSelectRowAtIndexPath when using Xcode's autocompletion to do this. I always do this and then inevitably realise my mistake 20 minutes later.

Disabling a cell in didSelectRowAtIndexPath not working?

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = NO;
}
I use the above code to disable a cell after a user clicks on it once. The problem I've run into is that when a cell is added to the table, that new cell is disabled, and the previously disabled one isn't anymore.
How can I fix this problem?
Cells get reused as the user scrolls the table. You need to keep track of which rows the user has disabled so in your cellForRowAtIndexPath you can set the userInteractionEnabled property (to YES or NO as needed) for every cell every time it is requested.
Update - more details.
You need to keep track of which index paths the user has selected. Add an instance variable of type NSMutableSet and add each indexPath to this in your didSelectRow... method.
Then in your cellForRow... method you need to check if the current indexPath is in the set or not. Based on the result you set the cell's userInteractionEnabled property:
cell.userInteractionEnabled = ![theSelectedPathsSet containsObject:indexPath];
where theSeletedPathsSet is your NSMutableSet instance variable.
This solution assumes the rows and sections in your table are fixed. If the user can do things that results in rows being added, removed, or moved, then you can't simply track the index paths. You need to use some other key to know which rows have been selected.
Are you using dequeueReusableCellWithIdentifier in your cellForRowAtIndexPath?
You should have something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *reuseIdentifier = #"myTableViewCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (!cell) {
cell = [[ArticleTableViewCell alloc] init];
}
// customise cell here (like cell.title = #"Woopee";)
if (self.selectedCells containsObject:[NSString stringWithFormat:#"%d", indexPath.row]] {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = NO;
}
return cell;
}
Expanding on the other answer, you can keep track of whether a specific cell has been previously selected (are therefore should be disabled) by doing something like this with the above:
Declare a property like #property (nonatomic, strong) NSMutableArray *selectedCells; then:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
[self.selectedCells addObject:[NSString stringWithFormat:#"%d", indexPath.row]];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.userInteractionEnabled = NO;
}
My laptop is about to die, but if it crashed you should look at the code the initialises the cell (alloc and init) or keep what you had before there.
You need to keep a record of which cells have been disabled. You could store the indexPath of the selected cells in an array and then use that to determine which cells should be active and not active in your cell:forRowAtIndexPath: method.

Can't Change Accessory Type From didSelectRowAtIndexPath?

Before I post the question itself, I need to state this is a jailbreak app. This is why I'm writing in "bizarre" folders in the filesystem.
Let's continue.
Here is my cellForRowAtIndexPath method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"pluginCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier];
}
if(indexPath.row == 0)
{
cell.textLabel.text = #"default";
}else
{
//Get the plugin's display name.
NSBundle *currentPlugin = [[NSBundle alloc] initWithPath:[NSString stringWithFormat:#"/Library/Cydeswitch/plugins/%#", [plugins objectAtIndex:indexPath.row - 1], nil]];
cell.textLabel.text = [[currentPlugin localizedInfoDictionary] objectForKey:#"CFBundleDisplayName"];
if(cell.textLabel.text == nil)
{
//No localized bundle, so let's get the global display name...
cell.textLabel.text = [[currentPlugin infoDictionary] objectForKey:#"CFBundleDisplayName"];
}
[currentPlugin release];
}
if([[[cell textLabel] text] isEqualToString:[settings objectForKey:#"pluginToExecute"]])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
currentCell = [cell retain];
}
return cell;
}
Like you can see, this method uses a member called currentCell to point to the cell that is currently "selected". This is an options table and the user should be able to have only one cell with the Checkmark accessory icon at any time.
When the use selects another cell, he is changing an option and the Checkmark is supposed to disappear from the current cell and appear in the newly appeared cell. I do that like this:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
currentCell.accessoryType = UITableViewCellAccessoryNone;
[currentCell release];
currentCell = [[self tableView:tableView cellForRowAtIndexPath:indexPath] retain];
NSLog(#"CURRENT CELL %#", currentCell.textLabel.text);
currentCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
But it doesn't work. The moment I tap another cell, the Checkmark correctly disappears from the old cell, but it never shows up in the new cell.
I know the selection work fine because that NSLog there prints the new cell's text just fine.
I have tried keeping track of the indexPath before, but it didn't work at all. When I tried using indexPaths instead of pointers to cells, when the user tapped the cell nothing happened at all (at least with my current approach the checkmark disappears from the old cell).
I think it has something to do with cellForRowAtIndexPath because if I keep pointing at the cells the checkmark disappears, but for some reason when trying to change the accessory type from a cell fetched with cellForRowAtIndexPath it doesn't seem to work at all.
Any help will be appreciated.
Typo? Try this:
currentCell = [[self.tableView cellForRowAtIndexPath:indexPath] retain];
You mustn't keep track of the last selected cell the way you are. Cell's get reused. Use an ivar to keep track of the indexPath or some other key appropriate to your data.
Then in the didSelect... method you get a reference to the old cell using the saved indexPath or key. In the cellForRow... method you need to set the proper accessoryType based on whether the current indexPath matches your saved indexPath.
Lastly, do not call your own delegate/data source method. When getting a reference to a cell, ask the table view for it directly.
BTW - you are over-retaining currentCell in your cellForRow... method. There is no need to retain it all in that method unless it is the first time you are making the assignment.

Assertion failure when using UISearchDisplayController in UITableViewController

I've been trying to add simple Search functionality to a TableViewController in my app. I followed Ray Wenderlich's tutorial. I have a tableView with some data, I added the search bar + display controller in storyboard, and then I have this code:
#pragma mark - Table View
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"BreedCell" forIndexPath:indexPath];
//Create PetBreed Object and return corresponding breed from corresponding array
PetBreed *petBreed = nil;
if(tableView == self.searchDisplayController.searchResultsTableView)
petBreed = [_filteredBreedsArray objectAtIndex:indexPath.row];
else
petBreed = [_breedsArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = petBreed.name;
return cell;
}
#pragma mark - Search
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[_filteredBreedsArray removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#",searchString];
_filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy];
return YES;
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption {
// Tells the table data source to reload when scope bar selection changes
[_filteredBreedsArray removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF.name contains[c] %#",self.searchDisplayController.searchBar.text];
_filteredBreedsArray = [[_breedsArray filteredArrayUsingPredicate:predicate] mutableCopy];
return YES;
}
The standard stuff, but when I enter text in the search bar it crashes every time with this error:
2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Assertion failure in -[UISearchResultsTableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2372/UITableView.m:4460
2013-01-07 19:47:07.330 FindFeedo[3206:c07] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier BreedCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
I understand that in iOS 6 the handling and dequeueing system for cells changed, and also that the search uses a different tableView, so I thought the problem was that the search tableView with the filtered results didn't know about the cell, so I put this in my viewDidLoad:
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"BreedCell"];
And voila! It worked... Only the first time you search. If you go back to the original results and search again, the app crashes with the same error. I thought about maybe adding all the
if(!cell){//init cell here};
stuff to the cellForRow method, but doesn't that go against the whole purpose of having the dequeueReusableCellWithIdentifier:forIndexPath: method? Anyway, I'm lost. What am I missing? Help, please. Thank you in advance for all your time (:
Alex.
Try using self.tableView instead of tableView in dequeueReusableCellWithIdentifier:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"BreedCell"];
//Create PetBreed Object and return corresponding breed from corresponding array
PetBreed *petBreed = nil;
if(tableView == self.searchDisplayController.searchResultsTableView)
petBreed = [_filteredBreedsArray objectAtIndex:indexPath.row];
else
petBreed = [_breedsArray objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = petBreed.name;
return cell;
}
This code works pretty well
Note
If you have custom height cells, do not use
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
Use this instead
[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
The reason why it worked great on first run but then crashed if you exited the results table and went back in for another search is because the Search Display Controller is loading a new UITableView each time you enter search mode.
By search mode I mean, you've tapped the textfield and you've began to type, at which point a table view is generated to display results, exiting this mode it achieved by hitting the cancel button. When you tap the textfield the second time and begin typing again - this is entering "search mode" for the second time.
So in order to avoid the crash you should register the cell class for the table view to use in the searchDisplayController:didLoadSearchResultsTableView: delegate method (from UISearchDisplayDelegate) of instead of in your controllers viewDidLoad method.
As follows:
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView
{
[tableView registerClass:[DPContentTableCell class] forCellReuseIdentifier:cellIdentifier];
[tableView registerClass:[DPEmptyContentTableCell class] forCellReuseIdentifier:emptyCellIdentifier];
}
This caught me by surprise because on iOS 7... the table view is being reused. So you can register the class in viewDidLoad if you prefer. For legacy sakes, I'll keep my registration in the delegate method I mentioned.
After searching, 'tableView' of cellForRowAtIndexPath method seems not an instance of the Table that you define. So, you can use an instance of a table that defines the cell. Instead of:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
Use:
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
(Do not use the tableView of cellForRowAtIndexPath method, use self.tableView.)
Dequeue the cell without using the 'indexPath' and in case of you obtain a nil element, you have to allocate it manually.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"YourCellId"];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"YourCellId"];
// fill your cell object with useful stuff :)
return cell;
}
Trying to use self.tableView for dequeue the cell may cause crashes when you have a sectioned main list and a plain search list.
This code instead work in any situation.
When I had this problem, the solution was replacing tableView dequeueReusableCellWithIdentifier:#yourcell with self.tableView
I am working on that tutorial also. The default TableViewController has "forIndexPath" and in his example it doesn't exist. Once I removed it the search works.
//Default code
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//Replace with
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
for swift 3 you just need to add self:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = self.tableView.dequeueReusableCell(withIdentifier: "yourCell", for: indexPath) as! YourCell
...
}

Resources