Warning trying to call BOOL method from another method - ios

I am following an iOS tutorial and my code is supposed to be correct, but I am getting an error which is not shown at the original tutorial code.
These are the concerning methods:
-(BOOL)tableview:(UITableView *)tableView canCollapseSection:(NSInteger)section {
if (section >0) return YES;
return NO;
}
And here the piece of code supposed to be correct, but throws an error:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResults count];
}
else {
if ([self tableView:tableView canCollapseSection:section])
{
if ([expandedSections containsIndex:section])
{
.../...
The error is shown at line
if ([self tableView:tableView canCollapseSection:section])
And this is the error message:
No visible #interface for 'ToDoItemsTableViewController' declares the selector 'tableView:canCollapseSection:'
Is there any visible error in the code?...

in your method you are calling tableView but it should be tableview. small 'V'

- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
tableView : V should be capital, please check after -(BOOL):tableview part

Declare
-(BOOL)tableview:(UITableView *)tableView canCollapseSection:(NSInteger)section
in your .h file.
Also make sure that, you typed it correctly (any spelling mistake can also cause the issue).

You just need to declare your method
-(BOOL)tableview:(UITableView *)tableView canCollapseSection:(NSInteger)section
in yourViewController.h file.

Related

unnecessary uitableview delegate methods

I inherited another developer code, but didn't understood the following code:
-(CGFloat)tableView:(UITableView*)tableView heightForFooterInSection:(NSInteger)section
{
return 0.0;
}
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return nil;
}
-(UIView*)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
return nil;
}
Is anything can happen if i'll delete it ?
it seems unnecessary
If you don't need them just comment them out. You 'll be fine.
Those methods are just part of the UITablieView "appearance" of the table. It is the string that is displayed under a section in your TableView. You can just comment them out or delete them totally, this won't affect your program.

Preventing a specific move in moveRowAtIndexPath

I have a UITableView in my Objective-C iOS app, of which I need to have a specific cell displaying information while all the others cells should move freely.
With my current code, I prevented said cell to be moved by other cells, but it is still possible to move underneath it.
This cell is not part of my Data model so I really need to keep this in the controller layer.
In other words, I'm looking for a way to prevent the default behaviour.
Below is my current code:
-(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath
{
if (destinationIndexPath.row == [tableView numberOfRowsInSection:0]-2) {
//prevent the move
}
else {
[[BNRItemStore sharedStore] moveItemAtIndex:sourceIndexPath.row toIndex:destinationIndexPath.row];
}
}
What should I change in order to obtain the desired functionality?
Did you try to implement this delegate method?
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath;
Use targetIndexPathForMoveFromRowAtIndexPath as below,
// Allows customization of the target row for a particular row as it is being moved/reordered
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
if( proposedDestinationIndexPath is ok ) {
return proposedDestinationIndexPath;
} else {
return sourceIndexPath;
}
}

Row deletion animation issue with swipe to delete

I am implementing swipe to delete feature on one of my table that uses custom table view cells. The issue I am facing is when I tap on "Delete" button, I see a weird transition while cell is being removed.
Below is my code in "commitEditingStyle" and also see the attached screenshot I captured while row is being removed.
PS: I have tried with all types of row removal animation styles but no luck.
- (void)tableView:(UITableView *)iTableView commitEditingStyle:(UITableViewCellEditingStyle)iEditingStyle forRowAtIndexPath:(NSIndexPath *)iIndexPath {
if (iEditingStyle == UITableViewCellEditingStyleDelete && iTableView == self.temporaryCartTable) {
if (self.temporaryCartTable.frame.size.height == kMyAppCartTableViewExpandedHeight) {
[self.temporaryCartTable beginUpdates];
[self.temporaryCartTable deleteRowsAtIndexPaths:[NSArray arrayWithObjects: iIndexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
MyAppCartInfo *aMyAppCartInfo = [self cart];
if (([[aMyAppCartInfo.tempProducts allKeys] count] > iIndexPath.row) && [aMyAppCartInfo.tempProducts containsObjectForKey:[[aMyAppCartInfo.tempProducts allKeys] objectAtIndex:iIndexPath.row]]) {
[aMyAppCartInfo.tempProducts removeObjectForKey:[[aMyAppCartInfo.tempProducts allKeys] objectAtIndex:iIndexPath.row]];
}
[self.temporaryCartTable endUpdates];
}
}
}
- (BOOL)tableView:(UITableView *)iTableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return (iTableView == self.temporaryCartTable) ? YES : NO;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)iTableView editingStyleForRowAtIndexPath:(NSIndexPath *)iIndexPath {
return UITableViewCellEditingStyleDelete;
}
- (CGFloat)tableView:(UITableView *)iTableView heightForRowAtIndexPath:(NSIndexPath *)iIndexPath {
if (iTableView == self.temporaryCartTable) {
if (self.isTempCartCell)
return 92.0;
else
return 58.0;
} else {
return 58.0;
}
}
Add the following method implementation to your UITableViewDelegate
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
Use [self.temporaryCartTable setRowHeight:xxx] instead of using the delegate rowHeightAtIndexPath. After the row is deleted and there is no other rows in the table, the delegate will not called and your table view's row height will be retrieved by its property (hence the default height). Plus, using this method from the delegate affects the performance.
If anyone else is having this, the problem in my case was heightForRowAtIndexPath: When cells have dynamic size delete animation behaves strange. In my case the solution was to use a different approach and not spend time investigating. But you can test it and see results. Assign a fixed height for cells:
self.tableView.rowHeight = Constant;
comment out heightForRowAtIndexPath:. And animations should be ok now.
I know this is not the solution but may still help someone.

UITableView - Section header. How to change text?

I have a project which uses Storyboards. I have a UITableView with Static cells and Group style.
I need to change the section text in one section depending on which selection is made in a segmented control (in another section)
I have found some solutions which indicate that you should use override this method:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
and trigger an update by calling:
[[self tableView]reloadSections:[NSIndexSet indexSetWithIndex:SectionToChange] withRowAnimation:UITableViewRowAnimationFade];
The problem is when I call reloadSections then all the rows and cells in the section in question get deleted. The text updates correctly thought but with this unwanted side effect.
I think I found the answer here: Changing UITableView section header without tableView:titleForHeaderInSection
It may not be very elegant but it seams to work.
I can trigger an update to only the section header with none of the unwanted side effects by calling:
[self.tableView headerViewForSection:1].textLabel.text = [self tableView:self.tableView titleForHeaderInSection:1];
So the only thing needed is to implement:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if (section == 1){
if (self.segmentX.selectedSegmentIndex == 0) // or some condition
return #"Header one";
else
return #"Header two";
}
return nil;
}
If you have implemented these functions then removing them should fix your problem:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-(UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{ if (section == 0)
{
lbl.text = #"abc";
}
if (section == 2)
{
lbl.text = #"2ndsectionbeigns";
}
return headerview;
}

Creating Grouped UITableview with Different Cell Types

I need to create a grouped uitableview that includes some sections and possibly different cell types in each sections.
I am trying to create something like old foursquare app, user page (includes 'leaderboard', 'friend suggestions', 'friends', 'stats', 'most explored categories' ... sections).
I am fairly new to ios programming, so that view may not be a grouped uitableview.
What I especially stuck is creating different cells for sections, and finding out which cells are clicked.
My data source will be 2 different NSArray* that consists of different data types, that's why I need different custom cells.
Since you have two different sets of data and you need to display both in different sections, you have to split the data source methods into two.
Basically, choose which dataset you want to be first and off you go.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section)return secondArray.count;
//Essentially, if statements evaluate TRUE and move forward if the inside is 1 or greater (TRUE == 1)
return firstArray.count;
//If the first if statement return hits, then the code will never reach this statement which turns this into a lighter if else statement
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section)
{
//do stuff with second array and choose cell type x
}
else
{
//do stuff with first array and choose cell type y
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the cell with: UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(indexPath.section)
{
//perform action for second dataset
}
else
{
//perform action for first dataset
}
}
For headers, you can use either of these methods and just keep the same type of styling as above:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
You can create multiple custom subclasses of UITableViewCell, and in the tableView:cellForRowAtIndexPath: method for your UITableViewDataSource, you can use if-statements to determine what type of cell to use.
For example, here's a rough outline of what I might do:
-(UITableViewCell *)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//First, determine what type of object we're showing
if (indexPath.section == 0) {
//Create and return this cell.
} else if (indexPath.section == 1) {
//Create and return this cell.
}...
}
Here's how you'd implement numberOfRowsInSection:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return [firstSectionArray count];
} else if (section == 1) {
return [secondSectionArray count];
} ...
}
For didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
ObjectSelected *objectSelected = [firstArray objectAtIndex:indexPath.row];
//Now you've got the object, so push a view controller:
DetailViewController *dvc = [[DetailViewController alloc] init];
dvc.objectSelected = objectSelected;
[self.navigationController pushViewController:dvc];
} else if (indexPath.section == 1) {
//Same thing, just call [secondArray objectAtIndex:indexPath.row] instead!
}
}

Resources