UITableViewWith Paging Prev,next button - iphone

I have one NSMutableArray that has number of records (suppose 52).
for (int i=0;i<=52;i++) {
[arrSavedCalculation addObject:[NSString stringWithFormat:#"Bianca lb,Red %d",i]];
}
I want to give a paging Prev and Next button at bottom of tableview. and each page display 6 record.How can i do this. i also see this document but not success
http://www.ke-cai.net/2011/04/pagination-with-uitableview-in-ios.html

Try with these. Tested and found working. Can be improved.
#interface ViewController (){
//pageNumber will hold the current page index
NSInteger _pageNumber;
//keeping the max page number for ease of calculation
NSUInteger _maxPageNumber;
//the batch size
NSUInteger _numberOfVisibleRows;
}
#end
#implementation ViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//Main data array is formed
NSUInteger rows = 0;
NSMutableArray *tempArray = [NSMutableArray array];
while (rows<52) {
[tempArray addObject:[NSString stringWithFormat:#"Item %d",rows+1]];
rows++;
}
self.mainArray = [NSArray arrayWithArray:tempArray];
_pageNumber = 0;
_numberOfVisibleRows = 5;
_maxPageNumber = [self.mainArray count]/_numberOfVisibleRows;
self.subArray = [self subArrayForPageNumber:_pageNumber];
}
- (NSArray *)subArrayForPageNumber:(NSUInteger)pageNumber{
NSRange range = NSMakeRange(_pageNumber*_numberOfVisibleRows, _numberOfVisibleRows);
if (range.location+range.length>[self.mainArray count]) {
range.length = [self.mainArray count]-range.location;
}
return [self.mainArray subarrayWithRange:range];
}
- (IBAction)buttonPressed:(UIBarButtonItem *)button{
//Same method is used for calculating the page numbers
if (button.tag ==1) {
_pageNumber= MIN(_maxPageNumber, _pageNumber+1);
}else{
_pageNumber = MAX(0, _pageNumber-1);
}
self.subArray = [self subArrayForPageNumber:_pageNumber];
[self.tableView reloadData];
}
Source Code

you should take two array.
1) Your MAIN ARRAY containing all of objects.
2) A Temporary array contain only 6 objects.
While loading tableview use that Temporary Array.
keep a page counter which will count your current page.
According to your 52 objects you can have 52/6 = 9 page but last page contain only 4 object.
like.
#define kNumberOfObjectInOnePage 6
set self.page=0 in "viewDidLoad" //self.page is the page counter.
-(void)nextPage:(id)sender{
self.page++;
take 6 objects from main array into temp array
reload your table view.
}
-(void)previous:(id)sender{
self.page--;
take 6 previous object into temp array
reload your table view.
}

A simple solution is if you are accessing records from web service then ask to him provide the total number of records in initial hits as well as first 6 records to display. If you want to do paging you should keep page 0 or 1 at initial hit to service and as you got 6 records on first page and you find that total records which are given from service is more than the 6 then you have to show previous and next button otherwise no need of these button.
As you accessing the records you have to put into in an NSArray or in Coredata. When you press next buttonyou have to increase the page count and fetch next 6 records and save to DB or array and reload the table.
if you press previous button you have to remove last 6 object from array or you can delete or check some kind last 6 records to display and reload table.
Hope this helps.

Related

Parse.com API: How to query for objects incrementally?

I have a table view controller that is fetching objects from a database hosted by parse.com. At the moment, I have the view controller fetch all the objects in the database for storage in an array. Right now, there are 100 objects in the database, and what I would like to do, is have the table view controller fetch 20 of those objects and display them, then have it fetch and display 20 more when the table scrolls to the bottom.
Here is my init method:
- (id)initWithStyle:(UITableViewStyle)style{
self = [super initWithStyle:style];
if (self) {
//create the array, set the table view size, then populate it.
listings = [[NSMutableArray alloc] init];
[self populateArrayWithListings];
}
return self;
}
[self populateArrayWithListings]; simply fills the array listings with the 100 objects in the database. I have this method to detect when the table view controller is scrolled to at the bottom:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y + scrollView.bounds.size.height > scrollView.contentSize.height * 0.9) {
}
}
Question is, what should I put inside those brackets to have it fetch the next 20 objects in the database?
I did the same thing what you needed.
FQuery *postQuery = [PFQuery queryWithClassName:#"Challenge"];
[postQuery addDescendingOrder:#"createdAt"];
[postQuery includeKey:#"userId"];
[postQuery setSkip:[mutArrPagingResponce count]];
[postQuery setLimit:20];
// Declare this array gloabally or keep it in another array
NSMutableArray *mutArrPagingResponce = [[postQuery findObjects] mutableCopy];
This will work as you are trying to achieve. Let me know if anything else required.

Search for strings in large array takes a long time

I'm implementing a search field that filters a UITableView according to the text the user enters.
The TableView is built from an array that holds NSStrings (the data to display and search) and may contain 6000+ items.
When the user starts the search, I'm implementing the -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText method.
My code works, however, when the data array is large, it is very slow and creating a really bad user experience (my iPhone 4s get stuck for a good few seconds).
The way I'm implementing the search (in the method mentioned above) is this:
NSMutableArray *discardedItems = [[NSMutableArray alloc] init]; // Items to be removed
searchResultsArray = [[NSMutableArray alloc] initWithArray:containerArray]; // The array that holds all the data
// Search for matching results
for (int i=0; i<[searchResultsArray count]; i++) {
NSString *data = [[containerArray objectAtIndex:i] lowercaseString];
NSRange r = [data rangeOfString:searchText];
if (r.location == NSNotFound) {
// Mark the items to be removed
[discardedItems addObject:[searchResultsArray objectAtIndex:i]];
}
}
// update the display array
[searchResultsArray removeObjectsInArray:discardedItems];
[myTableView reloadData];
I did not think that looping over an array with a few thousand items would cause any issue...
Any suggestion will be appreciated!
UPDATE
I've just realized that what takes most of the time is this:
[searchResultsArray removeObjectsInArray:discardedItems];
Try fast enumeration way, my snippet:
- (void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
self.isFiltered = NO;
}
else
{
self.isFiltered = YES;
self.searchArray = [NSMutableArray arrayWithCapacity:self.places.count];
for (PTGPlace* place in self.places)
{
NSRange nameRange = [place.name rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound)
{
[self.searchArray addObject:place];
}
}
}
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(self.isFiltered)
return self.searchArray.count;
else
return self.places.count;
}
In cellForRowAtIndexPath:
PTGPlace *place = nil;
if(self.isFiltered)
place = [self.searchArray objectAtIndex:indexPath.row];
else
place = [self.places objectAtIndex:indexPath.row];
// Configure the cell...
cell.textLabel.text = place.name;
cell.detailTextLabel.text = [place subtitle];
Try this:
for the first three positions, create 26 index sets, each representing the array index of items with that letter (just lower case). That is, say a entry at idx=100 starts with "formula". The index set representing "f" in the first position will contain the index "100". The index set for the second character 'o' will contain the index 100, and the index set for the third character 'r' will contain 100.
When the user types the character 'f', you immediately have the index set of all array items starting with 'f' (and can create a subset of your major array quickly). When an 'o' is typed next, you can find the intersection of indexes in the first match with the second match. Ditto for the third. Now make a subarray of the major array that had the first three indexes match - you can just use the index sets for this.
Using this drastically reduced array, you can now do brute force matching as you were doing originally.

Tables are not getting refreshed

I have the problem in refreshing the table. I create the table like this
for (int i = 0; i < 4; i++)
{
DetailsTable = [[UITableView alloc] initWithFrame:CGRectMake(i*768, 45, 768, 1024) style:UITableViewStyleGrouped];
DetailsTable.dataSource = self;
DetailsTable.delegate = self;
DetailsTable.tag = i + 1;
[scrollView addSubview:DetailsTable];
[DetailsTable release];
}
Whenever I am refreshing the table like this [DetailsTable reloadData]; it refresh the last table only. And other table is not getting refresh
How can refresh all table view in iphone
this is because in DetailsTable the last table reference is retain so that this occurs
Try this
add this in .h file
NSMutableArray *tblArr;
add this in .m file
tblArr=[[NSMutableArray alloc] init];
for (int i = 0; i < 4; i++)
{
UITableView *DetailsTable = [[UITableView alloc] initWithFrame:CGRectMake(i*768, 45, 768, 1024) style:UITableViewStyleGrouped];
DetailsTable.dataSource = self;
DetailsTable.delegate = self;
DetailsTable.tag = i + 1;
[scrollView addSubview:DetailsTable];
[tblArr addObject:DetailsTable];
[DetailsTable release];
}
and when you want to relaod all table use this
for (int i = 0; i < 4; i++)
{
[(UITableView *)[tblArr objectAtIndex:i] reloadData];
}
You keep overwriting the value of the PersonDetailsTable property in the loop. Therefore the value of that property is the 4th one after the loop exits. You call reloadData against that property which points to the 4th instance of the table you added.
To make that work, you would need an NSMutableArray of table views (instead of the one property reference) and reloading all of them would could be looping with reloadData calls. Of course in your UITableView datasource callbacks, you need to distinguish between which table view is calling you back for data since self is the datasource and delegate for all of them.
you are creating 4 tableView not four cells, and every time you are creating a new instance of the table so when you call the [DetailsTable reloadData]; it refrences the most recent instance of DetailsTable i.e the last table.
The variable DetailsTable is being replaced with a new one every time in the for loop.
You should create an array of tables instead, like this:
//Declaration
UITableView *DetailsTable[4];
//Implementation
for (int i = 0; i < 4; i++)
{
DetailsTable[i] = [[UITableView alloc] initWithFrame:CGRectMake(i*768, 45, 768, 1024) style:UITableViewStyleGrouped];
...
}
//And to refresh them
for(int i = 0; i < 4; i++)
[DetailsTable[i] reloadData];
put in for loop where you are going to create
DetailsTable.tag=i
and then for example of edit method of delegate method use this
- (void)tableView:(UITableView *)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (tableView.tag)
{
case 0:
{
//write your code here
break;
}
// like this do all for other remaining tableview
default:
break;
}
}
You can not add tables like this. Your next tableView will replace the pre tableView. You should impliment this by init four single tables.

Getting a List of 5 recent items filled in UITextField

Getting a List of 5 recent items filled in Text Field, from where if i select any item will get populated in the Text Field. Open for any suggestions/solution.
Thanks in Advance.
I agree with Paul Peelen but his solution is incomplete. You want to have five different items, so the code is the following:
#define CAPACITY 5
[...]
self.recents = [NSMutableArray arrayWithCapacity:CAPACITY + 1];
[...]
- (void)addItem:(NSString*)addItem {
//item won't be twice in the list
[self.recents removeObject:item];
//recently used items are at the beginning of the list
[self.recents insertObject:item atIndex:0];
//remove the sixth item
if ([self.recents count] == CAPACITY + 1) {
[self.recents removeLastObject];
}
}
Create a NSMutableArray and listen to the UITextField's delegate. Whenever the user presses "Return" or the field is resigned, add the current value to the NSMutableArray ([myArray addObject:textField.text];)
When you want to show the data in the array:
for (NSString *value in myArray)
{
NSLog(#"String value: %#", value);
}

Show UIAlertView if UITableView is empty

I have RSS, and the UITableView loads data from it, how can I show UIAlertView if the UITableView is empty, but not by count of an array because the array is different every time it is refreshed, is there some kind of function which will check if UITableView is empty after it completes drawing?
You can query the UITableView itself. So assuming you have a single section you could do the following ...
// Reload the tableview
[tableView reloadData];
// Test the number of rows in the first section
if ([tableView numberofRowsInSection:0] == 0) {
// Display UIAlertView here
}
EDIT; Based on the comments below ...
In your header file (.h) iVar declarations ...
int feedCount;
int feedsParsed;
In your implementation ...
- (void)refresh {
feedCount = 0;
feedsParsed = 0;
[feedParser stopParsing];
self.title = #"Refreshing...";
[parsedItems removeAllObjects];
for (NSString *imePredmeta in [Data variables].mojiPredmeti) {
... // I've removed these lines for brevity but they are still required
[feedParser parse];
feedCount += 1;
}
// Delete everything else after this line
}
- (void)feedParserDidFinish:(MWFeedParser *)parser {
feedsParsed += 1;
if (feedsParsed == feedCount) {
[self.tableView reloadData];
if ([self.tableView numberofRowsInSection:0] == 0) {
// Fade out tableview and display alert here as we now know for
// sure that there are no more feeds to parse and we definitely
// have nothing to display
}
}
}
You will need to loop round the array and check to determine if there are no results.
Please post your existing tableview code if you want a more explicit answer.
edit: micpringle answer above is better.