UItableView load data 10 10 records on scroll - ios

I am getting the data from the web-service and I have to display it in UITableView. But the condition here is I have to display only 10 records initially,then once the user scroll down I have to load more records it contains image also.I tried searching it but didn't get any useful answer.
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { }
display the value,but how will I fetch only 10 records initially ce and then other record based on scroll. Please provide some points or sample code

In your backend link keep an ' index' field. When index=0, get the 10 records from backed then increment index to 1, get another 10 records,etc...
keep the code also to call link when scroll the tableView at the end ,
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
NSInteger currentOffset = scrollView.contentOffset.y;
NSInteger maximumOffset = scrollView.contentSize.height- scrollView.frame.size.height;
if (maximumOffset - currentOffset <= 0) {
index =index +1;
// Call your link here
}
}

Inside your cellForRowAtIndexPath: method you could always check if the current row equals the count of your data - 1:
if(indexPath.row == tableData.count - 1)
{
[self getMoreData];
}

I assume that in your web service you will get page number and 10
record as per page
when you scroll in tablview it will call willDisplayCell and check
current Array count.
if your scroll reach equal to array count or last record it will request data again with page number.
//Declare variable
NSInteger currentPageNumber;
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == arrData.count-1) {
currentPageNumber++;
//Call your Webservice
}
}
-(void)webserviceCall{
//pass page number in your web service you will get data with page number
// After getting data from web service you need to add data in your array, so you will have total records.
if([[jsonResponse objectForKey:#"status"] intValue] == 1){
[arrData addObjectsFromArray:arrData];
}
}

Related

UITableView showing inconsistent number of rows compared to data source

I'm trying to make a UITableView present a determined number of rows for a section, but even when I verify that its data source is returning x number of rows for numberOfRowsInSection, the table view shows x-1.
The exception to this unexpected behavior is if the numberOfRowsInSection is less than 3.
I've even put a breakpoint in cellForRowAtIndexPath and I confirmed it's being called for the row that is not appearing.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == SectionNumber_One) {
return 6;
} else {
return self.numberOfProjectRows; // This returns x, but x-1 rows are being shown
}
}
For example, if self.numberOfProjectRows is 5, only 4 rows are shown for the second section.
If I increase it manually to 6, it shows 5 rows but the data that should be in the 5th position, isn't there.
It doesn't seem to be related to screen size as I tested it on an iPad with same results.
Why is this happening? Is there some other possible modifier of the number of rows in a section?
I'm attaching an screenshot if it's of any help.
EDIT - Here are my delegate methods:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Cell with reuse identifier setup
if (section == SectionNumber_One) {
// cell setup for section one that's showing up ok
} else if (section == SectionNumber_Two) {
UITextField *projectField = cell.projectTextField;
if ([self.userProjectKeys count] > row) {
projectField.text = self.availableProjects[self.userProjectKeys[row]];
}
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Hide the password row for existing users
if (indexPath.row == FieldTag_Password && ![self.user.key vol_isStringEmpty]) {
return 0.0f;
} else {
return UITableViewAutomaticDimension;
}
}
The problem is probably not in your Datasource methods, but your Delegate methods, tableView(_:heightForRowAt:).
If you do not return a correct height for the cell, it won't show up.
It doesn't matter if you write 1000 cells in your datasource. If you don't return the height, they wont show up.
You are not comforming to the MVC pattern in implementing the table. You must return the count of the tableView's datasource, not variables of it.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == SectionNumber_One) {
return 6;
} else {
return [_displayingArray count]; // <-- here
}
}
If you want different items for each sections, then declare different datasource (ie array) for each of them.
EDIT: Even returning constant 6 is dangerous in the other section - you ought to add items to another fixed array and return that array's count in this delegate.

iOS Objective C : How to increase number of rows after given condition

I am very new to iOS, Living in a very small village with no help on iOS, I need help in my code where I can increase number of rows once I reach to row number 20.
I actually have more than 6000 lines, when try to show all of them in tableview, it takes lot of time, so I want to load all rows in efficient way, like increasing it like +20, +50 etc
here is my code:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return a;
}
and I am trying to increase rows like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 20)
{
[_myTable reloadData];
[self.myTable beginUpdates];
a= a +50;
[self.myTable endUpdates];
}
if (indexPath.row > 60)
{
[self.myTable beginUpdates];
a= a +100;
[self.myTable endUpdates];
}
}
I declared myTable as property
I am sorry if my post is looking foolish I am at very basic position and sorry for my bad English.
The numbers of rows to be displayed in a tableView depends on data available i.e., the data to be displayed in the UITableView.
Let an array "Countries" containing list of 3 countries:
NSArray *countries;
countries = #[#"India",#"USA",#"Germany",nil];
so, now the UITableView has 3 rows, so use this:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return countries.count;
}
so if the countries list increased later, then it will work.
No need to increase number of rows in table manually.
If the response is from server, then use this:
NSArray *dataArray = [responseObject objectForKey:#"countriesJson"];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return dataArray.count;
}
Sample Project:
Please check my GitHub link below:
https://github.com/k-sathireddy/TableRowCountDynamic
Note: More images are loaded if we reach a certain limit.
You have to follow below algorithm or logic,
1)First just initialize your array with the 20 objects and that array will use for the display in a UITableView as a datasource.
2)Then you need to implement the UIScrollView delegate method, - (void)scrollViewDidScroll:(UIScrollView *)aScrollView in which you can write a some code like this:
- (Void) scrollViewDidScroll: (UIScrollView *) aScrollView
{
self.tbleSerachResult.frame=self.tbleSerachResult.frame;
if (aScrollView==self.tblOutlet) {
[currentTextfield resignFirstResponder];
CGPoint offset = aScrollView.contentOffset;
CGRect bounds = aScrollView.bounds;
CGSize size = aScrollView.contentSize;
UIEdgeInsets inset = aScrollView.contentInset;
float y = offset.y + bounds.size.height - inset.bottom;
float h = size.height;
float reload_distance = 10;
if(y > h + reload_distance)
{
//add more 20 records to your existing array which used for the UITableView data source and reload the UITableView.
//Put your load more data method here...
}
}
}
3) after this, you doesn't require any other thing to maintain this. Just implement the UITableView delegate and datasource methods as normally. It will work.
Try this way, if still facing any issue let me know I will give you example code.
Hope it works for you!! Happy coding :)

Preloading data from network in UITableView

I have a page that support pagination when loading data from network.
I'm using a UITableview to display list.
I want to preload next page when user scroll near the end of current page.
For example, each page has 10 items. When item 8 is visible in the screen, I shall start loading of next page immediately.
Which delegate method of UITableView is the best choice for this task?
Try the following method, It will get to know the display cell
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Webservice Call for next 10 display data
}
Discussion
A table view sends this message to its delegate just before it uses cell to draw a row, thereby permitting the delegate to customize the cell object before it is displayed. This method gives the delegate a chance to override state-based properties set earlier by the table view
UITableView is a subclass of UIScrollView, so you can use it delegate methods. I suggest you to use this two:
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
if (!decelerate) {
NSSet *visibleRows = [NSSet setWithArray:[self.view.tableView indexPathsForVisibleRows]];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
NSSet *visibleRows = [NSSet setWithArray:[self.view.tableView indexPathsForVisibleRows]];
}
Check your clause after you get visibleRows and preload your data if, for example, last indexPath.row in NSSet is equal to your datasource array count (or is equal to [array count] - some_number_you_want )
To archive, when tableView start scrolling, you can implement your preload logic here:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
NSSet *visibleRows = [NSSet setWithArray:[self.view.tableView indexPathsForVisibleRows]];
// your update code here
}
Hope this helps.
add this method in the UITableViewDelegate:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGFloat height = scrollView.frame.size.height;
CGFloat yOffset = scrollView.contentOffset.y;
CGFloat distanceFromBottom = scrollView.contentSize.height - yOffset;
if(distanceFromBottom < height)
{
NSLog(#"end of the table and call web service or load more data");
}
}
Use UITableViewDataSourcePrefetching or UICollectionViewDataSourcePrefetching to preload data from network and have your cells ready when displayed to the user

Why tableview scroll when insert rows?

I'm trying to insert new rows from my Core Data on the bottom of the tableview, everything works fine, except that my tableview scroll a random rows to the top
My table view has variable height (each rows has different height)
I want that when the user scroll on the bottom of the table view, it load 10 more rows from core data but the scroll must stay on the same
my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [_data count] - 1 && !loadingData) {
loadingData = YES;
[self loadMoreData];
}
//Create Cell
}
-(void)loadMoreData {
int from = (int)[_data count];
NSArray *temp = [Functions loadNewDataFrom:from];
if ([temp count] > 0) {
[_data addObjectsFromArray:temp];
[self.tableView reloadData];
loadingData = NO;
}
}
What I'm doing wrong?
Edit: I already try allot of solutions on google & stackoverflow and always its the same,
and I'm trying it on iOS 7 simulator 4 inch
Thanks!

ios table with dynamic sections and two different prototype cells

I am new to ios programming so bear with me if the question is simple. I have a core data table mapped to a table view controller. The data in it currently looks as follows - there is one prototype cell:
I need to sum up the data by dates and show the details of each date in a different section with the summed up total coming up as the first row. Something like:
My question is is this doable? I am thinking I need to create sections and two prototype cells within each table cell. Would appreciate quick feedback.
Thanks all!
The easy way to do this is using section headers. You can either use a single string (#"%#: %#", date, total) or a wrapper view with a label on the left for the date and on the right for the total.
-(NSString *) tableView:(UITableView *)tv titleForHeaderInSection:(NSInteger)s
{
NSString *dateString = [self dateStringForSection:s];
float total = [self totalForSection:s];
return [NSString stringWithFormat:#"%#: %0.2f", dateString, total];
}
Or
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
return [self wrappedHeaderForSection:s];
}
You'll have to implement dateStringForSection: or wrappedHeaderForSection: appropriately, of course.
The easiest way is to style your UITableView to 'UITableViewStyleGrouped'.
UITableView *tab = [[UITableView alloc] initWithFrame:rect style:UITableViewStyleGrouped];
Or you can go to interface builder and in Table View change style from plain to grouped.
The style 'Grouped' divides your table into multiple sections.
The using UITableViewDelegate methods specify all the parameters.
// Tell the number of section in table
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return numberOfSections;
}
//Tell the number of rows in each section
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
{
return 2;
} else if(section == 1)...
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0)
{
//Show Amount for Jul 02, 2013
cell.textLabel.text = #"Jul 02, 2013";
cell.detailTextLabel = #"20.35";
}
// Do the same for all rows and section in table.
}
For further reference -
http://mobisoftinfotech.com/iphone-uitableview-tutorial-grouped-table/
You should also definitely check out the Sensible TableView framework. Saves me tons of time when working with Core Data.

Resources