Add only SOME items from XML to TableView - ios

Using this tutorial, I made an iPhone blog app. It uses the count of the array created to setup the number of rows. I don't want to do every single item, because there are over 200 right now and growing. When I return any number for rows in section, it always crashes with the error about 0 beyond bounds of empty array. What else do I need to tweak from this tutorial to only allow the first 20 items to show in tableview?
UPDATE: I think I am making some progress. In the reqeustFinished method where it sorts the array, I edited it to make it this:
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[entries removeLastObject];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
NSLog(#"%#", entries);
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
Adding the line to removeLastObject for entries, removed the first item (which is ideally the ONLY one I would want on the first day). Are there other methods that would allow me to remove a range of objects at Index?
Here is the code I have for the Table View Class and DataSources.
- (void)refresh {
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:#"addressofxmlfile",
nil];
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:#selector(refreshInvoked:forState:) forControlEvents:UIControlEventValueChanged];
[self refresh];
}
-(void) refreshInvoked:(id)sender forState:(UIControlState)state {
// Refresh table here...
[_allEntries removeAllObjects];
[self.tableView reloadData];
[self refresh];
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = [item valueForChild:#"guid"];
NSString *articleDateString = [item valueForChild:#"pubdate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSString *articleImage = [item valueForChild:#"description"];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *dateofarticle = [dateFormatter stringFromDate:articleDate];
NSString *days = [articleImage substringFromIndex:7];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate
articleImage:articleImage
date:thedate] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
}else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
}
}];
}
}];
[self.refreshControl endRefreshing];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"Error: %#", error);
[self refresh];
}
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// [tableView setBackgroundColor:[UIColor redColor]];
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_allEntries count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[Cell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
CALayer * l = [cell.imageView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:11];
[l setBorderWidth:2.0];
[l setBorderColor:[[UIColor blackColor] CGColor]];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
[dateFormatter setDateStyle:NSDateFormatterShortStyle];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
UIFont *cellFont = [UIFont fontWithName:#"Papyrus" size:19];
UIFont *cellFont2 = [UIFont fontWithName:#"Papyrus" size:17];
// cell.imageView.image = [UIImage imageNamed:#"icon#2x.png"];
cell.textLabel.text = entry.date;
cell.detailTextLabel.text = entry.articleTitle;
cell.detailTextLabel.textColor = [UIColor blackColor];
cell.textLabel.font = cellFont;
cell.detailTextLabel.font = cellFont2;
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 73.4;
}

You are assigning allEntries to new Array in the Refresh method here:
- (void)refresh {
self.allEntries = [NSMutableArray array];
The tutorial only does this in the ViewDidLoad Method. Not sure if this is a problem as i don't know exactly when/how refresh is called.
Found this answer that shows how to hide cells/rows here.

Related

not able to search the data?

I have added search bar for collection view using programatically .But when i enter the names to search nothing shows.I have some section also and each section contains some data.
Here is my code:
#interface ViewController ()
{
NSMutableArray *arrayPDFName;
NSMutableArray *titleArray;
}
#property (nonatomic,strong) NSArray *dataSourceForSearchResult;
#property (nonatomic) BOOL searchBarActive;
#property (nonatomic) float searchBarBoundsY;
#property (nonatomic,strong) UISearchBar *searchBar;
#property (nonatomic,strong) UIRefreshControl *refreshControl;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataSourceForSearchResult = [NSArray new];
titleArray = [NSMutableArray array];
[self getdata];
self.mycollectionView.dataSource = self;
self.mycollectionView.delegate = self;
[self.mycollectionView reloadData];
}
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:#"%02x",result[i]];
}
return ret;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self prepareUI];
}
-(void)getdata {
NSString *userName = #“username#yahoo.com";
NSString *password = #“password”;
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://api.exampleport/user/orderid/files";
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
// basic authendication
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
//header-field
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64Encoding]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError * error;
self->arrayPDFName = [[NSMutableArray alloc]init];
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dictOriginal = jsonResults[#“dark”];
[titleArray addObject:[NSString stringWithFormat:#"dark(%#)”, dictOriginal[#"count"]]];
NSDictionary *dictOriginal2 = jsonResults[#"orange”];
[titleArray addObject:[NSString stringWithFormat:#"orange(%#)”, dictOriginal2[#"count"]]];
NSDictionary *dictOriginal3 = jsonResults[#"pencill”];
[titleArray addObject:[NSString stringWithFormat:#"pencill(%#)”, dictOriginal3[#"count"]]];
NSDictionary *dictOriginal4 = jsonResults[#"smart”];
[titleArray addObject:[NSString stringWithFormat:#"smart(%#)”, dictOriginal4[#"count"]]];
NSArray *arrayFiles = [NSArray arrayWithObjects: dictOriginal, dictOriginal2, dictOriginal3, dictOriginal4, nil];
NSLog(#"str: %#", titleArray);
for (NSDictionary *dict in arrayFiles) {
NSMutableArray *arr = [NSMutableArray array];
NSArray *a = dict[#"files"];
for(int i=0; i < a.count; i ++) {
NSString *strName = [NSString stringWithFormat:#"%#",[[dict[#"files"] objectAtIndex:i] valueForKey:#"name"]];
// NSLog(#"str: %#", strName);
[arr addObject:strName];
}
[arrayPDFName addObject:arr];
}
//Get plist path
NSString *errorDesc;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory1 stringByAppendingPathComponent:#"SampleData.plist"];
//NSLog(#"plistPath : %#",plistPath);
//Save data from json to plist
NSString *error1;
returnData = [NSPropertyListSerialization dataFromPropertyList:jsonResults
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
if(returnData ) {
if ([returnData writeToFile:plistPath atomically:YES]) {
NSLog(#"Data successfully saved.");
}else {
NSLog(#"Did not managed to save NSData.");
}
}
else {
NSLog(#"%#",errorDesc);
}
// NSArray *stringsArray = [NSArray arrayWithContentsOfFile:plistPath];
NSDictionary *stringsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
// NSLog(#"str: %#", stringsDictionary);
}
//delegate method for header
-(UICollectionReusableView*) collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
HeaderView * header = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"myHeader" forIndexPath:indexPath];
header.myHeaderLabel.text = titleArray[indexPath.section];
return header;
}
#pragma mark - UICollectionView Datasource
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return titleArray.count;
}
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
if (self.searchBarActive) {
return self.dataSourceForSearchResult.count;
}
NSArray *a = arrayPDFName[section];
if (a.count == 0)
{
return 1;
}
else
{
return a.count;
}
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
return CGSizeMake(0, 80);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath: (NSIndexPath *)indexPath {
VenueCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"mycell" forIndexPath:indexPath];
cell.backgroundColor = [UIColor whiteColor];
cell.imgV.image = [UIImage imageNamed:#"doc1.png"];
if (self.searchBarActive) {
cell.myLabel.text = _dataSourceForSearchResult[indexPath.section][indexPath.row];
}else{
NSArray *a = arrayPDFName[indexPath.section];
if (a.count == 0) {
cell.myLabel.text = #"NO DATA";
return cell;
}
cell.myLabel.text = a[indexPath.row];
}
return cell;
}
//////////////////////////for search bar //////////
#pragma mark - actions
-(void)refreashControlAction{
[self cancelSearching];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// stop refreshing after 2 seconds
[self.mycollectionView reloadData];
[self.refreshControl endRefreshing];
});
}
#pragma mark - search
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"self contains[c] %#", searchText];
self.dataSourceForSearchResult = [self->arrayPDFName filteredArrayUsingPredicate:resultPredicate];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText{
// user did type something, check our datasource for text that looks the same
if (searchText.length>0) {
// search and reload data source
self.searchBarActive = YES;
[self filterContentForSearchText:searchText
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
[self.mycollectionView reloadData];
}else{
// if text lenght == 0
// we will consider the searchbar is not active
self.searchBarActive = NO;
}
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
[self cancelSearching];
[self.mycollectionView reloadData];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
self.searchBarActive = YES;
[self.view endEditing:YES];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
// we used here to set self.searchBarActive = YES
// but we'll not do that any more... it made problems
// it's better to set self.searchBarActive = YES when user typed something
[self.searchBar setShowsCancelButton:YES animated:YES];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar{
// this method is being called when search btn in the keyboard tapped
// we set searchBarActive = NO
// but no need to reloadCollectionView
self.searchBarActive = NO;
[self.searchBar setShowsCancelButton:NO animated:YES];
}
-(void)cancelSearching{
self.searchBarActive = NO;
[self.searchBar resignFirstResponder];
self.searchBar.text = #"";
}
#pragma mark - prepareVC
-(void)prepareUI{
[self addSearchBar];
[self addRefreshControl];
}
-(void)addSearchBar{
if (!self.searchBar) {
self.searchBarBoundsY = self.navigationController.navigationBar.frame.size.height + [UIApplication sharedApplication].statusBarFrame.size.height;
self.searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0,self.searchBarBoundsY, [UIScreen mainScreen].bounds.size.width, 50)];
self.searchBar.searchBarStyle = UISearchBarStyleMinimal;
self.searchBar.tintColor = [UIColor whiteColor];
self.searchBar.barTintColor = [UIColor whiteColor];
self.searchBar.delegate = self;
self.searchBar.placeholder = #"Search here";
[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setTextColor:[UIColor whiteColor]];
// add KVO observer.. so we will be informed when user scroll colllectionView
[self addObservers];
}
if (![self.searchBar isDescendantOfView:self.view]) {
[self.view addSubview:self.searchBar];
}
}
-(void)addRefreshControl{
if (!self.refreshControl) {
self.refreshControl = [UIRefreshControl new];
self.refreshControl.tintColor = [UIColor whiteColor];
[self.refreshControl addTarget:self
action:#selector(refreashControlAction)
forControlEvents:UIControlEventValueChanged];
}
if (![self.refreshControl isDescendantOfView:self.mycollectionView]) {
[self.mycollectionView addSubview:self.refreshControl];
}
}
-(void)startRefreshControl{
if (!self.refreshControl.refreshing) {
[self.refreshControl beginRefreshing];
}
}
Where i am doing mistake and what i need to change to work.Thanks in advance!
It seems your arrayPDFName have array object and each array object have string object. There are two ways to filter you array.
Way - 1
If you want to get the list of array which has the search string the use SUBQUERY with your predicate. Like below.
NSArray *a1 = #[#"a1", #"a2", #"a3"];
NSArray *a2 = #[#"a1", #"a2", #"a3"];
NSArray *a3 = #[#"a1", #"a2", #"a3"];
NSArray *a4 = #[#"a2", #"a3"];
NSArray *allA = #[a1, a2, a3, a4];
NSPredicate *pre = [NSPredicate predicateWithFormat:#"SUBQUERY(SELF, $a, $a == %#).#count > 0", #"a1"];
NSArray *a = [allA filteredArrayUsingPredicate:pre];
Way - 2
If you want to get the search string alone from each array object then follow the below,
NSMutableArray *fa = [[NSMutableArray alloc] init];
for (NSArray *a in allA) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"self CONTAINS[c] %#", #"a3"];
[fa addObjectsFromArray:[a filteredArrayUsingPredicate:p]];
}
Note: Above code done with same sample data. Replace it as you want.
As per your code replace the below code
-(void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
NSMutableArray *fa = [[NSMutableArray alloc] init];
for (NSArray *a in arrayPDFName) {
NSPredicate *p = [NSPredicate predicateWithFormat:#"self CONTAINS[c] %#", searchText];
[fa addObjectsFromArray:[a filteredArrayUsingPredicate:p]];
}
self.dataSourceForSearchResult = [NSArray arrayWithArray:fa];
}
-(NSInteger) numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
if(self.searchBarActive)
return 1;
return titleArray.count;
}
In cellForItemAtIndexPath
cell.myLabel.text = _dataSourceForSearchResult[indexPath.row];

Xcode Table view Data is getting duplicated when I pull to refresh

Hi My data is getting duplicated every time I use the pull to refresh.. for eg. 5 initial entries in the table view are doubled to 10 with one pull to refresh and adding 5 more in the subsequent pull to refresh. How can I stop the duplication.. I would like to make sure that only new items are downloaded and existing data in the table is not downloaded again.
#implementation RootViewController
#synthesize allEntries = _allEntries;
#synthesize feeds = _feeds;
#synthesize queue = _queue;
#synthesize webViewController = _webViewController;
#pragma mark -
#pragma mark View lifecycle
- (void)addRows {
RSSEntry *entry1 = [[[RSSEntry alloc] initWithBlogTitle:#"1"
articleTitle:#"1"
articleUrl:#"1"
articleDate:[NSDate date]] autorelease];
RSSEntry *entry2 = [[[RSSEntry alloc] initWithBlogTitle:#"2"
articleTitle:#"2"
articleUrl:#"2"
articleDate:[NSDate date]] autorelease];
RSSEntry *entry3 = [[[RSSEntry alloc] initWithBlogTitle:#"3"
articleTitle:#"3"
articleUrl:#"3"
articleDate:[NSDate date]] autorelease];
[_allEntries insertObject:entry1 atIndex:0];
[_allEntries insertObject:entry2 atIndex:0];
[_allEntries insertObject:entry3 atIndex:0];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Songs";
self.allEntries = [NSMutableArray array];
self.queue = [[[NSOperationQueue alloc] init] autorelease];
self.feeds = [NSArray arrayWithObjects:
#"http://hindisongs.bestofindia.co/?feed=rss2",
nil];
self.refreshControl = [UIRefreshControl new];
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:#"Pull to refresh"];
[self.refreshControl addTarget:self action:#selector(bindDatas) forControlEvents:UIControlEventValueChanged];
[self bindDatas]; //called at the first time
}
-(void)bindDatas
{
//GET YOUR DATAS HERE…
for (NSString *feed in _feeds) {
NSURL *url = [NSURL URLWithString:feed];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[_queue addOperation:request];
}
//update the tableView
[self.tableView reloadData];
if(self.refreshControl != nil && self.refreshControl.isRefreshing == TRUE)
{
[self.refreshControl endRefreshing];
}
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = [item valueForChild:#"link"];
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseAtom:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSString *blogTitle = [rootElement valueForChild:#"title"];
NSArray *items = [rootElement elementsForName:#"entry"];
for (GDataXMLElement *item in items) {
NSString *articleTitle = [item valueForChild:#"title"];
NSString *articleUrl = nil;
NSArray *links = [item elementsForName:#"link"];
for(GDataXMLElement *link in links) {
NSString *rel = [[link attributeForName:#"rel"] stringValue];
NSString *type = [[link attributeForName:#"type"] stringValue];
if ([rel compare:#"alternate"] == NSOrderedSame &&
[type compare:#"text/html"] == NSOrderedSame) {
articleUrl = [[link attributeForName:#"href"] stringValue];
}
}
NSString *articleDateString = [item valueForChild:#"updated"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC3339];
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:articleTitle
articleUrl:articleUrl
articleDate:articleDate] autorelease];
[entries addObject:entry];
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
[self parseAtom:rootElement entries:entries];
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:entry atIndex:insertIdx];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:insertIdx inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
}
}];
}
}];
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSError *error = [request error];
NSLog(#"Error: %#", error);
}
/*
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
*/
/*
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
*/
/*
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
}
*/
/*
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
}
*/
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/
#pragma mark -
#pragma mark Table view data source
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_allEntries count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
NSDateFormatter * dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSString *articleDateString = [dateFormatter stringFromDate:entry.articleDate];
cell.textLabel.text = entry.articleTitle;
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - %#", articleDateString, entry.blogTitle];
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source.
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
self.webViewController = nil;
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[_allEntries release];
_allEntries = nil;
[_queue release];
_queue = nil;
[_feeds release];
_feeds = nil;
[_webViewController release];
_webViewController = nil;
[super dealloc];
}
The issue is that you keep inserting object to _allEntries without ever reseting it. You will want to empty it out at some point, either when the user pulls to refresh or when the new data comes in before you add any new objects to it.
[_allEntries removeAllObjects];
Try putting it at the start of bindDatas.

UICollectionView Cells Loading Same Items too many times

Here is the layout of my app. I have a UICollectionView in a Tab Bar Controller. I have two different XML files located on server. Depending on subscription purchases, one of two xmls will be parsed, and each item gets added to an array, which the UICollectionView in turn displays. I use MKiCloudSync to store the NSUserDefault values across iCloud as the method to determine if a subscription is still valid or not, so the user can access the app on multiple devices.
I call [MKiCloudSync start]; on didFinishLaunchingWithOptions in the AppDelegate implementation file.
In the UICollectionViewController file, the layout is essentially this:
viewDidLoad adds listener for MKiCloudSync changes. If change is made, it runs the code to update the UI. viewWillAppear checks the NSUserDefaults to see if it should load paid or free XML, and parses based off of that. If user does not have subscription, the right bar button item allows them to purchase it, which calls the code to do so. Upon successful code, it runs the code refreshpaid which parses the paid xml.
That is the setup in theory. I ran the app on my device from Ad Hoc build, and purchased the subscription in sandbox environment. The UI Updated as it should to show the additional content available in the Paid XML.
I then deleted the app, restarted the device, and reinstalled the ad hoc build to ensure the iCloud sync was working. When the app started, it showed 11 cells for every single item (assuming somehow code to refresh got called 11 times somehow). If I navigate to another tab and come back, or click on a cell and pop back, it corrects itself and just shows 1 cell per item in the XML.
Now, here is the full code from my UICollectionView.m file:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(updatetheui) name: NSUserDefaultsDidChangeNotification object: nil];
UINib *cellNib = [UINib nibWithNibName:#"NibCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
self.collectionView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"shelves.png"]];
}
-(void)updatetheui {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *status = [defaults objectForKey:#"Pay?"];
NSString *expirationdate = [defaults objectForKey:#"expiration"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
NSDate *date = [dateFormat dateFromString:expirationdate];
NSLog(#"Date: %#", [dateFormat stringFromDate:date]);
if ([status isEqualToString:#"PaidUp"]|([date timeIntervalSinceNow] > 0.0)) {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Status" style:UIBarButtonItemStyleBordered target:self action:#selector(statusofsubscription)];
self.navigationItem.leftBarButtonItem = nil;
NSLog(#"UPDATEUI PAY");
[_allEntries removeAllObjects];
[self.collectionView reloadData];
[self refreshpaid];
} else {
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Subscribe" style:UIBarButtonItemStyleBordered target:self action:#selector(buyButtonTapped:)];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Restore" style:UIBarButtonItemStyleBordered target:self action:#selector(timetorestore)];
[_allEntries removeAllObjects];
[self.collectionView reloadData];
[self refreshfree];
NSLog(#"UPDATEUI FREE");
}
}
- (void)viewWillAppear:(BOOL)animated {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *status = [defaults objectForKey:#"Pay?"];
NSString *expirationdate = [defaults objectForKey:#"expiration"];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MM/dd/yyyy"];
NSDate *date = [dateFormat dateFromString:expirationdate];
NSLog(#"Date: %#", [dateFormat stringFromDate:date]);
if ([status isEqualToString:#"PaidUp"]|([date timeIntervalSinceNow] > 0.0)) {
[self refreshpaid];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Status" style:UIBarButtonItemStyleBordered target:self action:#selector(statusofsubscription)];
self.navigationItem.leftBarButtonItem = nil;
NSLog(#"WILLAPPEARPAID");
}
else {
[self refreshfree];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Subscribe" style:UIBarButtonItemStyleBordered target:self action:#selector(buyButtonTapped:)];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Restore" style:UIBarButtonItemStyleBordered target:self action:#selector(timetorestore)];
}
//[self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)timetorestore {
[MKiCloudSync start];
UIAlertView *syncing = [[UIAlertView alloc]initWithTitle:#"Syncing" message:#"Now attempting to restore your subscription from iCloud. If unsuccessful, your subscription may have expired, or you may need to try again in a stronger network." delegate:self cancelButtonTitle:#"Okay" otherButtonTitles: nil];
[syncing show];
[syncing release];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
NSLog(#"1");
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [_allEntries count];
NSLog(#"2");
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:5.0
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^{
NSLog(#"animation start");
[cell setBackgroundColor:[UIColor colorWithRed: 180.0/255.0 green: 238.0/255.0 blue:180.0/255.0 alpha: 1.0]];
}
completion:^(BOOL finished){
NSLog(#"animation end");
[cell setBackgroundColor:[UIColor whiteColor]];
}
];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
if (_webViewController2 == nil) {
self.webViewController2 = [[[WebViewController2 alloc] initWithNibName:#"WebViewController2" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController2.entry = entry;
[self.navigationController pushViewController:_webViewController2 animated:YES];
}
else {
if (_webViewController == nil) {
self.webViewController = [[[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]] autorelease];
}
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
_webViewController.entry = entry;
[self.navigationController pushViewController:_webViewController animated:YES];
}
#endif
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
static NSString *cellIdentifier = #"cvCell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
UIImageView *titleLabel = (UIImageView *)[cell viewWithTag:100];
UILabel *titleLabel2 = (UILabel *)[cell viewWithTag:200];
NSString *thearticleImage = entry.articleImage;
[titleLabel setImageWithURL:[NSURL URLWithString:entry.articleImage] placeholderImage:[UIImage imageNamed:#"icon#2x.png"]];
// [titleLabel2 setText:entry.articleTitle];
return cell;
}
- (void)parseRss:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
NSArray *channels = [rootElement elementsForName:#"channel"];
for (GDataXMLElement *channel in channels) {
NSString *blogTitle = [channel valueForChild:#"title"];
NSArray *items = [channel elementsForName:#"item"];
for (GDataXMLElement *item in items) {
NSString *issueTitle = [item valueForChild:#"title"];
NSString *issueURL = [item valueForChild:#"link"];
NSString *articleDateString = [item valueForChild:#"pubDate"];
NSDate *articleDate = [NSDate dateFromInternetDateTimeString:articleDateString formatHint:DateFormatHintRFC822];
NSString *issueCoverArt = [item valueForChild:#"guid"];
NSLog(#"Title%#", issueTitle);
NSLog(#"Link%#", issueURL);
NSLog(#"Date%#", articleDateString);
NSLog(#"CoverArt%#", issueCoverArt);
RSSEntry *entry = [[[RSSEntry alloc] initWithBlogTitle:blogTitle
articleTitle:issueTitle
articleUrl:issueURL
articleDate:articleDate
articleImage:issueCoverArt] autorelease];
[entries addObject:entry];
}
}
}
- (void)parseFeed:(GDataXMLElement *)rootElement entries:(NSMutableArray *)entries {
if ([rootElement.name compare:#"rss"] == NSOrderedSame) {
[self parseRss:rootElement entries:entries];
} else if ([rootElement.name compare:#"feed"] == NSOrderedSame) {
[self parseAtom:rootElement entries:entries];
} else {
NSLog(#"Unsupported root element: %#", rootElement.name);
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
[_queue addOperationWithBlock:^{
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:[request responseData]
options:0 error:&error];
if (doc == nil) {
NSLog(#"Failed to parse %#", request.url);
} else {
NSMutableArray *entries = [NSMutableArray array];
[self parseFeed:doc.rootElement entries:entries];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
for (RSSEntry *entry in entries) {
int insertIdx = [_allEntries indexForInsertingObject:entry sortedUsingBlock:^(id a, id b) {
RSSEntry *entry1 = (RSSEntry *) a;
RSSEntry *entry2 = (RSSEntry *) b;
return [entry1.articleDate compare:entry2.articleDate];
}];
[_allEntries insertObject:entry atIndex:insertIdx];
[self.collectionView reloadData];
}
}];
}
}];
}
One possibility: you should always make sure that what get displayed is always what you intended. Take this as an example: (from my WFAsyncImageCell for iOS, it is largely the same principle on OS X.)
- (void)loadImage
{
if ([self.lastLoadedURL isEqual:self.imageURL])
{
return; // The current image URL is being reloaded. Ignore.
}
self.imageView.image = nil;
NSURL *loadURL = self.imageURL;
dispatch_group_async(WFBackgroundTasks,
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0),
^
{
// Get the image data. Possible check cached data
NSData *imageData = [NSData dataWithContentsOfURL:loadURL];
UIImage *image = [[UIImage alloc] initWithData:imageData];
if (!image)
{
// Oops, image file downloaded is bad.
image = [UIImage imageNamed:#"defaultFallback"];
}
else
{
// Cache it. Not gonna implement here in the demo.
}
dispatch_async(dispatch_get_main_queue(),
^
{
if ([loadURL isEqual:self.imageURL])
{
self.imageView.image = image;
}
else
{
// Oops, reload.
[self loadImage];
}
});
});

UITableview Delegate methods are not executing

i tried the following code for searching in epub ,Its not working the reason is
1.The table delegate methode executing at startup so the default value of search results is 0 ,so i give one dummy array with 4 elements in viewdidload method.So now tableview displaying only 4 thode elements in dummy array and when i scroll the tableview it displaying correct search results but still it showing only 4 elemets in that search results because number of rows methode is not execute while scrolling.
when i click search button it will call this methode in first class
SearchResultsViewController *searchRes=[[SearchResultsViewController alloc]initWithNibName:#"SearchResultsViewController" bundle:nil];
NSString *searchQuery=[search text];
sharedManager=[Mymanager sharedManager];
sharedManager.searchQuery=searchQuery;
// UITextField *textField = [NSString stringWithFormat:#"%#",searchQuery];
// [textField setFont:[UIFont fontWithName:#"BL-Ruthika-Bold" size:15]];
[searchRes searchString:searchQuery];
[self.navigationController pushViewController:searchRes animated:YES];
then it calls following methods in searchresult class
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"%d",[results count]);
if([results count]>0)
{
return [results count];
}
else
{
return [test count];
}
}
//executes only at the startup time ,so the value of results always become zero
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if([results count]>0) {
// cell.textLabel.adjustsFontSizeToFitWidth = YES;
hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
cell.textLabel.text = [NSString stringWithFormat:#"...%#...", hit.neighboringText];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];
cell.textLabel.font = [UIFont fontWithName:#"Trebuchet MS" size:13];
cell.textLabel.textColor = [UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
cell.detailTextLabel.textColor=[UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
cell.detailTextLabel.font= [UIFont fontWithName:#"Trebuchet MS" size:10];
return cell;
}
else
{
cell.textLabel.text=[test objectAtIndex:indexPath.row];
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sharedManager=[Mymanager sharedManager];
hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
sharedManager.searchFlag=YES;
sharedManager.hitPageNumber=hit.pageIndex;
sharedManager.hitChapter=hit.chapterIndex;
sharedManager.hit=hit;
// [fvc loadSpine:hit.chapterIndex atPageIndex:hit.pageIndex highlightSearchResult:hit];
[self.navigationController popViewControllerAnimated:YES];
}
- (void) searchString:(NSString*)query{
currentQuery=sharedManager.searchQuery;
[self searchString:currentQuery inChapterAtIndex:0];
[[self resultsTableView]reloadData];
}
- (void) searchString:(NSString *)query inChapterAtIndex:(int)index{
currentChapterIndex = index;
sharedManager=[Mymanager sharedManager];
Chapter* chapter = [sharedManager.spineArray objectAtIndex:index];
NSRange range = NSMakeRange(0, chapter.text.length);
NSLog(#"%#",sharedManager.searchQuery);
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
int hitCount=0;
while (range.location != NSNotFound) {
range = NSMakeRange(range.location+range.length, chapter.text.length-(range.location+range.length));
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
hitCount++;
}
if(hitCount!=0){
UIWebView* webView = [[UIWebView alloc] initWithFrame:chapter.windowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:chapter.spinePath]];
[webView loadRequest:urlRequest];
} else {
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching = NO;
}
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
// NSLog(#"%#", error);
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView{
sharedManager=[Mymanager sharedManager];
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",[[sharedManager.spineArray objectAtIndex:currentChapterIndex] fontPercentSize]];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView highlightAllOccurencesOfString:sharedManager.searchQuery];
NSString* foundHits = [webView stringByEvaluatingJavaScriptFromString:#"results"];
NSLog(#"%#", foundHits);
NSMutableArray* objects = [[NSMutableArray alloc] init];
NSArray* stringObjects = [foundHits componentsSeparatedByString:#";"];
for(int i=0; i<[stringObjects count]; i++){
NSArray* strObj = [[stringObjects objectAtIndex:i] componentsSeparatedByString:#","];
if([strObj count]==3){
[objects addObject:strObj];
}
}
NSArray* orderedRes = [objects sortedArrayUsingComparator:^(id obj1, id obj2){
int x1 = [[obj1 objectAtIndex:0] intValue];
int x2 = [[obj2 objectAtIndex:0] intValue];
int y1 = [[obj1 objectAtIndex:1] intValue];
int y2 = [[obj2 objectAtIndex:1] intValue];
if(y1<y2){
return NSOrderedAscending;
} else if(y1>y2){
return NSOrderedDescending;
} else {
if(x1<x2){
return NSOrderedAscending;
} else if (x1>x2){
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
}];
[objects release];
for(int i=0; i<[orderedRes count]; i++){
NSArray* currObj = [orderedRes objectAtIndex:i];
SearchResult* searchRes = [[SearchResult alloc] initWithChapterIndex:currentChapterIndex pageIndex:([[currObj objectAtIndex:1] intValue]/webView.bounds.size.height) hitIndex:0 neighboringText:[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"unescape('%#')", [currObj objectAtIndex:2]]] originatingQuery:sharedManager.searchQuery];
[results addObject:searchRes];
[searchRes release];
}
[[self resultsTableView]reloadData];
//Print results
for(int i=0;i<[results count];i++)
{
hit = (SearchResult*)[results objectAtIndex:i];
}
[resultsTableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching= NO;
}
[[self resultsTableView]reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
resultsTableView=[[UITableView alloc]init];
[resultsTableView setDelegate:self];
[resultsTableView setDataSource:self];
sharedManager=[Mymanager sharedManager];
// Do any additional setup after loading the view from its nib.
results = [[NSMutableArray alloc] init];
test=[[NSArray alloc]initWithObjects:#"one",#"one",#"one",#"one",nil];
self.navigationItem.title=#"Search ";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
[[UINavigationBar appearance] setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeTextShadowColor: [UIColor lightGrayColor],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],
UITextAttributeFont: [UIFont fontWithName:#"Trebuchet MS" size:15.0f]
}];
[self searchString:sharedManager.searchQuery];
noMatchingSearch=[[NSArray alloc]initWithObjects:#"No Element Found", nil];
tableOfContents=[[NSMutableArray alloc]init];
for (id img in search.subviews)
{
if ([img isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[img removeFromSuperview];
}
}
tableOfContents=[sharedManager.List copy];
}
- (void)viewDidUnload
{
search = nil;
[super viewDidUnload];
resultsTableView.delegate=self;
resultsTableView.dataSource=self;
// Release any retained subviews of the main view.
self.resultsTableView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
When you have received your search results call
[self.tableView reloadData];
To tell the table view to update itself. I can see you have tried it a number of times in the large amount of code above. You only need to call it once, when you have your search results ready. Also, ensure your reference to the table view is valid when you call it.
Also, if you're creating a table view in an XIB file, then the second one you're creating in viewDidLoad and not showing (adding as a subview) is just confusing you and you're trying to reload the wrong table view.
If you still have problems, show the class properties and remove all the code tat isn't to do with the table view.
resultsTableView=[[UITableView alloc]init];
Try to use resultsTableView, with a property, and set it's to (nonatomic, strong).

UITableview cellForRowAtIndexPath method is not executing?

When i click search it executes a search class and after finding the results it executes numberOfRows method but then it is showing empty table. It is not executing cellForRowAtIndexPath method .
check my below code
code in viewcontroller.h
when i click search button this method will get executed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
SearchResultsViewController *searchRes=[[SearchResultsViewController alloc]initWithNibName:#"SearchResultsViewController" bundle:nil];
NSString *searchQuery=[search text];
sharedManager=[Mymanager sharedManager];
sharedManager.searchQuery=searchQuery;
[searchRes searchString:searchQuery];
[self.navigationController pushViewController:searchRes animated:YES];
}
in search class
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"%#",results);
return [results count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.adjustsFontSizeToFitWidth = YES;
NSLog(#"indexpath%d",indexPath.row);
NSLog(#"%#",[results objectAtIndex:[indexPath row]]);
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
NSLog(#"%#",hit.neighboringText);
cell.textLabel.text = [NSString stringWithFormat:#"...%#...", hit.neighboringText];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];
cell.textLabel.font = [UIFont fontWithName:#"Trebuchet MS" size:12];
cell.textLabel.textColor = [UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
// else
// {
//
// }
// [[self resultsTableView] reloadData];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
[fvc loadSpine:hit.chapterIndex atPageIndex:hit.pageIndex highlightSearchResult:hit];
}
- (void) searchString:(NSString*)query{
// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// {
self.results = [[NSMutableArray alloc] init];
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
//
[self searchString:currentQuery inChapterAtIndex:0];
//
// }else {
// currentQuery=sharedManager.searchQuery;
// [self searchString:currentQuery inChapterAtIndex:0];
//}
}
- (void) searchString:(NSString *)query inChapterAtIndex:(int)index{
currentChapterIndex = index;
sharedManager=[Mymanager sharedManager];
Chapter* chapter = [sharedManager.spineArray objectAtIndex:index];
NSLog(#"%d",chapter.text.length);
NSRange range = NSMakeRange(0, chapter.text.length);
NSLog(#"%#",sharedManager.searchQuery);
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
int hitCount=0;
while (range.location != NSNotFound) {
range = NSMakeRange(range.location+range.length, chapter.text.length-(range.location+range.length));
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
hitCount++;
}
if(hitCount!=0){
UIWebView* webView = [[UIWebView alloc] initWithFrame:chapter.windowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:chapter.spinePath]];
[webView loadRequest:urlRequest];
} else {
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching = NO;
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(#"%#", error);
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView{
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",[[sharedManager.spineArray objectAtIndex:currentChapterIndex] fontPercentSize]];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView highlightAllOccurencesOfString:sharedManager.searchQuery];
NSString* foundHits = [webView stringByEvaluatingJavaScriptFromString:#"results"];
NSLog(#"%#", foundHits);
NSMutableArray* objects = [[NSMutableArray alloc] init];
NSArray* stringObjects = [foundHits componentsSeparatedByString:#";"];
for(int i=0; i<[stringObjects count]; i++){
NSArray* strObj = [[stringObjects objectAtIndex:i] componentsSeparatedByString:#","];
if([strObj count]==3){
[objects addObject:strObj];
}
}
NSArray* orderedRes = [objects sortedArrayUsingComparator:^(id obj1, id obj2){
int x1 = [[obj1 objectAtIndex:0] intValue];
int x2 = [[obj2 objectAtIndex:0] intValue];
int y1 = [[obj1 objectAtIndex:1] intValue];
int y2 = [[obj2 objectAtIndex:1] intValue];
if(y1<y2){
return NSOrderedAscending;
} else if(y1>y2){
return NSOrderedDescending;
} else {
if(x1<x2){
return NSOrderedAscending;
} else if (x1>x2){
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
}];
[objects release];
NSLog(#"%#",currentQuery);
for(int i=0; i<[orderedRes count]; i++){
NSArray* currObj = [orderedRes objectAtIndex:i];
SearchResult* searchRes = [[SearchResult alloc] initWithChapterIndex:currentChapterIndex pageIndex:([[currObj objectAtIndex:1] intValue]/webView.bounds.size.height) hitIndex:0 neighboringText:[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"unescape('%#')", [currObj objectAtIndex:2]]] originatingQuery:currentQuery];
[results addObject:searchRes];
NSLog(#"%#",results);
[searchRes release];
}
//Print results
for(int i=0;i<[results count];i++)
{
SearchResult* hit = (SearchResult*)[results objectAtIndex:i];
NSLog(#"%#",hit.neighboringText);
}
[resultsTableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching= NO;
}
[[self resultsTableView] reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
//- (void)dealloc
////{
//// self.resultsTableView = nil;
//// //[results release];
//// //[currentQuery release];
//// [super dealloc];
//}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
resultsTableView=[[UITableView alloc]init];
[resultsTableView setDelegate:self];
[resultsTableView setDataSource:self];
sharedManager=[Mymanager sharedManager];
// Do any additional setup after loading the view from its nib.
results = [[NSMutableArray alloc] init];
self.navigationItem.title=#"Search ";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
[[UINavigationBar appearance] setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeTextShadowColor: [UIColor lightGrayColor],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],
UITextAttributeFont: [UIFont fontWithName:#"Trebuchet MS" size:15.0f]
}];
noMatchingSearch=[[NSArray alloc]initWithObjects:#"No Element Found", nil];
tableOfContents=[[NSMutableArray alloc]init];
for (id img in search.subviews)
{
if ([img isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[img removeFromSuperview];
}
}
tableOfContents=[sharedManager.List copy];
}
- (void)viewDidUnload
{
search = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
self.resultsTableView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
MY SEARCH RESULTS
"<SearchResult: 0x113482c0>",
"<SearchResult: 0x11348a20>",
"<SearchResult: 0x88c0a50>"
The problem is with the search method before search the array is reinitialised and hence 0 returned in the resultArray and hence no value in tables
- (void) searchString:(NSString*)query{
self.results = [[NSMutableArray alloc] init];//Here it becomes 0!!
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
}
To make it right ,After the search is performed i believe
[self searchString:currentQuery inChapterAtIndex:0];
load the value in the result array and then reload table.
Make sure
in .h add
<UITableViewDataSource,UITableViewDelegate>
in nib
connect datasource and delegate[if via nib]

Resources