I want to add data or cells in UITableview when we scrolled to the last cell of the UITableView. In other words, as we have seen in many iPhone apps, that when we reached to the last cell of the UITableview the more cells get added to it at runtime. I want to achieve that functionality in my project.
Means Add some more cells to the UITableview when we reached to the previously added last cell.
Please tell me the sample code or any tutorial for it.
I think that there are 2 questions here.
First, how to detect the end of tableVeiw? Second, how to add cells dynamically?
First question, I think it can be done by observing the value of content offset of scrollView or current indexPath of tableView cell. The content offset of scrollView can be observed by following method of UIScrollViewDelegate. The content offset is a property of scrollView.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat currentOffset = scrollView.contentOffset;
// Detect scrolling to bottom by this offset value.
....
}
The index of cell may be decided by the method of UITableViewDataSource.
- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
Second question can be overwhelmed by the methods of UITableView.
beginUpdates
endUpdates
insertRowsAtIndexPaths:withRowAnimation:
deleteRowsAtIndexPaths:withRowAnimation:
insertSections:withRowAnimation:
deleteSections:withRowAnimation:
I remember the sample codes in this official document will teach how to use above methods. They don't reload all cells, but careless operations will result in crash easily.
If you have data stored in an array, then you would definitely have the count of how many cells you want.
Use the below code for your help
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return [array count];}
i believe this would have helped you.
Populate the tableView by using an array (as you should always do). When the delegate method cellForRowAtIndexPath ask your for the last cell, repopulate your array with new (more) data and make a [tableView reloadData].
you just want to add data in table?
Then, first you may need to add one more view, modal view. You should write some specification about what you want to add in this view.
Next you send a message to existing data array(Assume you use array)
[ExistingArrayData addObject:TemporalilyNewObject];
And you can sort the data by using NSSortDescriptor.
NSSortDescriptor *nameSorter = [[NSSortDescriptor alloc] initWithKey:KEY_VALUE ascending:YES selector:#selector(caseInsensitiveCompare:)];
[ExistingArrayData sortUsingDescriptors:[NSArray arrayWithObject:nameSorter]];
In this case, this method sorts the data by KEY_VALUE, ascending.
Finally, you shoule add this code in RootView's viewWillAppear method.
[self.tableView reloadData];
This code notifies app of change of data.
-(void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
int i=0;
i=indexPath.row;
int count=[urTablearray count];
if (count == (++i)) {
//do ur stuff here
here add object to urTablearray
[urTablearray addObject:#"vijay"];
}
}
Note: urTablearray is NSMutableArray type not NSArray
Related
I have a UITableView which I fill with CoreData fetched results. I want to add an single custom cell to the top of my UITableView and have managed to do so, however it requires me to have to call this:
return [sectionInfo numberOfObjects] + 1;
Then this:
NSIndexPath *path = [NSIndexPath indexPathForRow:(indexPath.row - 1) inSection:indexPath.section];
The second line has to be called in almost all of the UITableView Delegate methods to account for the additional cell at indexPath 0. However it causing a ton of problems which I won't list as every time i make changes here and there whatever it may be this is the root of my problem.
Is there any other method you would suggest to simply add my single custom cell to the top of my CoreData tableview?
Any help much appreciated.
If you are using this extra cell as a header, consider setting the tableView.tableHeaderView to a custom view.
I am trying to delete a row from UITableview outside the delegate method. I am calling a method when I click a button inside a table cell and trying to delete the row inside that method.
Here is the function I am using
UIButton *btn = (UIButton*)sender;
int tag = btn.tag;
UITableViewCell *buttonCell = (UITableViewCell*)[[btn superview] superview];
NSIndexPath *indexPath = [self.msgTbl indexPathForCell:buttonCell];
[deleg.rmessages removeObjectAtIndex:buttonRow];
[self.msgTbl deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];NSInteger buttonRow = indexPath.row;
[self.msgTbl reloadData];
Using this one or two rows get deleted but after that its crashing giving exception
Number of rows before and after deletion must be same
How can I do this in ios?
Thanks
Your problem is that the data that is being taken to populate your table isn't consistent with the table after deleting the cell. Make sure your dataSource methods provide the correct data after doing this (for example, if it is an array of objects you are using to populate the table, you must remove the object from the array as well)
The root issue is that this method:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
Must return the correct number of rows, and it isn't. When you remove the item from deleg.rmessages, is this the same object that is being used to supply the return value of the above method? (Something like [deleg.rmessages count]?)
Also, in my experience that exception often gives you more details, in particular:
How many items it had before
How many were added/deleted
How many it expects to have vs. how many it does have after the reload
Do you see anything like this being mentioned? If so, it would be worth including in your question.
Sidenote:
It's a bad idea to rely on:
UITableViewCell *buttonCell = (UITableViewCell*)[[btn superview] superview];
To return the UITableViewCell. You appear to assign the tag of the button to a local variable, but never use it. (Maybe this would be a good place to store the index of the UITableViewCell, and then subclass the cell to maintain an ivar to the button?) This is only part of the problem.
I have a UITableview which shows 10 rows currently which is fixed static. Now I want to add a feature into it. I want to add a more 10 rows to the table when user reach to the last row of the UITableView. I mean currently I am showing fixed 10 rows in the application.
But now I want to add 10 more rows whenever user reaches to the last row of previous UITableview.
Please give me any suggestions or any sample code to achieve my motive. Thanks in advance.
It is actually quite simple. What you need to do is implement the tableView:willDisplayCell:forRowAtIndexPath: method, which belongs to the UITableViewDelegate protocol. This method hits every time a cell is about to be displayed. So, it will let you know when the last cell is about to be displayed. Then you could do something like-
– (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *) cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == [self.array count] - 1) //self.array is the array of items you are displaying
{
//If it is the last cell, Add items to your array here & update the table view
}
}
Another (a bit mathematical) option is to implement UIScrollView delegate methods (UITableView is a subclass of UIScrollView), namely scrollViewDidEndScrollingAnimation: or scrollViewDidScroll:. These will let you know the y-position of the content the user is viewing. If it is found that the bottom most content is visible, you can add more items.
HTH,
Akshay
uitableview is derived from uiscrollview. To achieve your objective, you need to implement scrollViewDidEndDecelerating:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
float endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height;
if (endScrolling >= scrollView.contentSize.height)
{
// your code goes here
}
}
This will detect a "bouncing effect" like shifting up the visible rows to indicate that one would like to see more.
How would you exactly want to invoke the loading of the additional 10 rows? When a user just scrolls down to see the first 10 that are loaded by default he might not want to load 10 more already.
You may add a "add more" line as the last row of your table. When the user clicks on this one you add 10 more.
(I don't know how one would detect a "bouncing effect" like shifting up the visible rows to indicate that one would like to see more.)
The basic logic would look like this:
in cellForRowAtIndexPath you check if the user clicked on the last line and then invoke your code to add the 10
to actually add 10 more lines you have to call [myTable reloadData]
but before you call you need to increase the returned value of numberOfRowsInSection by 10 and make sure that cellForRowAtIndexPath will correctly return your new lines 11-20
ps if you REALLY want 10 additional rows to be loaded when the user reaches the end of the table you need to invoke the loading of 10 more in cellForRowAtIndexPath or willDisplayCell:forRowAtIndexPath: when it is called for your last line.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [categoriesList count];
}
Here categoriesList is an array. We can add objects to this array and call reloadData in the tableview.
Okidoke. Here's my problem: I have a series of complex UITableViewCells set up to display stories from a news feed (yawn). What I want to happen, is for the cell background image and height to change on selection (as a means of marking that the story has been read).
Now, prior to setting up dequeueing, I was able to do this with a simple [self.tableView reloadData]. That seems to be a no-go with dequeued cells; reloading the table view does not redraw the cells to match their changed state.
I've tried reloadRowsAtIndex- and while this works - beautifully - for the first cell a user clicks on, it goes wonky after that point: sometimes the cell reloads correctly, sometimes not.
Obviously, each story is an NSMutableDictionary object. I'm using an NSNumber object to track whether or not a story has been read.
I would post the code, and I will if anyone asks, but I'm looking for a generic solution that could be implemented in any UITableViewController (share the love).
So, simply put: how does one reliably redraw complex cells on selection?
Try giving each cell a unique ID in order for dequeuing to work, your cells should be coming back with their changed states if you use a unique id for each cell, so 20 cells = 20 ids, hope this helps
Assuming you have the index path, you can access the cell and manipulate it directly:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// handle the selection...
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
if (nil != cell) {
//
// now update the cell to reflect the new state
//
}
}
in iphone application.
I'm trying to get indexPath.row value (out of didselectedrowatindexpath method) to do something on the basis of row selected in programmatically created tableview.
i need to access indexpath.row out of didselectedrowatindexpath method where if/else will define the action on the basis of indexpath.row.
there are 7 cards images in application and one [menu list]table view. whenever user will click on row of table view,then need to touch the image
I'm trying this code to get the IndexPath.row value. The problem is indexPath.row value is not updating everytime. It's just taking the old value. Please sugggest how to solve this issue.
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
NSUInteger nSection =[myTableView numberOfSections]-1 ;
NSUInteger nRow = [myTableView numberOfRowsInSection:nSection];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:nRow inSection:nSection];
NSLog(#"No of sections in my table view %d",nSection);
NSLog(#"No of rows in my table view %d",nRow);
NSLog(#"Value of selected indexPath Row %d", [indexPath.row]);
NSLog(#"VAlue of Array arrOperationChk %d",[arrOperationChk count]);
}
This code appears to respond to something (the table?) being touched. You then ask the table how many rows it has in its last section and create an indexpath to that.
The table caches the number of rows in each section. If you have changed the number of rows, you need to tell the table, either by calling -insert/deleteRowsAtIndexPaths:withRowAnimation:, or by calling -reloadData. Otherwise the table has no way to know that it needs to re-query its datasource (which you provide).
Unless I'm reading this code wrong, aren't you just getting the index path to the last cell+1 of the last section? I wouldn't expect that to change.
If you want to get the selected cell, use the
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
method in your UITableViewController object.
As other people have said, there's nothing in your code that would change the indexPath variable you've just created.
Also, the syntax [indexPath.row] looks wrong - you don't need the square brackets there unless you're calling a method. When you use the dot syntax like that on a pointer in Objective-C, you don't think of it as a method call (even though there is one, implicitly), but rather as a pseudo-instance variable as of a struct.
What is your big picture goal? If we understood what you are trying to achieve / what is the desired behavior, maybe a more useful answer will arise.