In my app I build a collection view based on a dataset. When I perform a clean install all header titles show up correct. After reopening the app, the first header title disappears. And calling reloadData in the viewWillAppear method is not fixing the problem.
My code:
#import "ChapterViewController.h"
#import "XMLParser.h"
#import "ChapterStore.h"
#import "Chapter.h"
#import "Section.h"
#import "Word.h"
#import "ChapterViewCell.h"
#interface ChapterViewController ()
#property (nonatomic, strong) IBOutlet UICollectionView *collectionView;
#property (nonatomic, strong) NSArray *dataArray;
#end
#implementation ChapterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
[[self navigationItem] setTitle:#"Chapters"];
self.navigationController.navigationBar.translucent = NO;
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if ( ![userDefaults valueForKey:#"version"] )
{
[[ChapterStore sharedStore] doParse];
[self spaceTrimmer:[ChapterStore sharedStore]];
// Adding version number to NSUserDefaults for first version:
[userDefaults setFloat:[[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"] floatValue] forKey:#"version"];
}
if ([[NSUserDefaults standardUserDefaults] floatForKey:#"version"] == [[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"] floatValue] )
{
/// Same Version so dont run the function
}
else
{
// Call Your Function;
// Update version number to NSUserDefaults for other versions:
[userDefaults setFloat:[[[[NSBundle mainBundle] infoDictionary] objectForKey:#"CFBundleVersion"] floatValue] forKey:#"version"];
}
}
return self;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
[[self collectionView] reloadData];
}
- (NSInteger)numberOfChapters {
return [[[ChapterStore sharedStore] allChapters] count];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *chapters = [[NSMutableArray alloc] init];
for (int i = 0; i < [self numberOfChapters]; i++) {
[chapters addObject:[[[ChapterStore sharedStore] allChapters] objectAtIndex:i]];
}
if ([self respondsToSelector:#selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
self.dataArray = chapters;
UINib *cellNib = [UINib nibWithNibName:#"ChapterViewCell" bundle:nil];
[self.collectionView registerNib:cellNib forCellWithReuseIdentifier:#"cvCell"];
[self.collectionView registerNib:[UINib nibWithNibName:#"ChapterViewHeader" bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:#"cvHeader"];
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
[flowLayout setItemSize:CGSizeMake(159, 159)];
[flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[flowLayout setMinimumInteritemSpacing:2];
[flowLayout setMinimumLineSpacing:2];
[flowLayout setHeaderReferenceSize:CGSizeMake(0, 50)];
[self.collectionView setCollectionViewLayout:flowLayout];
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
UICollectionReusableView *header = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:#"cvHeader" forIndexPath:indexPath];
Chapter *data = [self.dataArray objectAtIndex:indexPath.section];
NSString *chapterName = [data CHAPTER_NAME];
UILabel *titleLabel = (UILabel *)[header viewWithTag:99];
[titleLabel setText:chapterName];
return header;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
Chapter *data = [self.dataArray objectAtIndex:indexPath.section];
Section *section = [[data sections]objectAtIndex:indexPath.row];
NSString *cellData = [section SECTION_NAME];
static NSString *cellIdentifier = #"cvCell";
ChapterViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
int i = [indexPath indexAtPosition:0] + 1;
int j = [indexPath indexAtPosition:1] + 1;
NSString *imageName = [NSString stringWithFormat:#"c%ds%d.jpg", i,j];
UIImage *image = [UIImage imageNamed:imageName];
[cell setController:self];
[cell setCollectionView:collectionView];
[[cell sectionLabel] setText:cellData];
[[cell imageView]setImage:image];
return cell;
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return [self.dataArray count];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
Chapter *sectionArray = [self.dataArray objectAtIndex:section];
return [[sectionArray sections] count];
}
It seemed to be a caching or an IOS 7 upgrade issue. I completely uninstalled the app, restarted xcode and the simulator and the issue is now gone.
Related
In my class for my TableView, I populate the rows with the names of all files within a given folder of my app. I am just now changing it over to UISearchBar, and I'm having some issues with my logic. The search bar appears, but the tableview simply goes blank.
In my .h file I have:
#interface DevoSongs : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchResultsUpdating >{
NSArray *files;
NSIndexPath *thepath;
NSString *filenames;
NSArray *try2;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
IBOutlet UITableView *tableView;
}
#property (nonatomic, retain) UITableView *tableView;
#property (strong, nonatomic) UISearchController *searchController;
#property (nonatomic, retain) NSArray *files;
#property (nonatomic, retain) NSString *filenames;
#property (nonatomic, retain) NSIndexPath *thepath;
#property (nonatomic, retain) NSArray *try2;
#property (nonatomic, retain) NSMutableArray *searchResults;
#property (nonatomic, copy) NSString *savedSearchTerm;
- (void)handleSearchForTerm:(NSString *)searchTerm;
#end
For my implementation:
-(void)viewDidLoad {
[super viewDidLoad];
self.searchController = [[UISearchController alloc]
initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.tableView.tableHeaderView = self.searchController.searchBar;
self.definesPresentationContext = YES;
[self.searchController.searchBar sizeToFit];
}
- (void)viewWillAppear:(BOOL)animated {
NSBundle *bundle = [NSBundle mainBundle];
self.files = [bundle pathsForResourcesOfType:#"pdf" inDirectory:#"thepdfpowerpoints"];
NSString *documentsDirectoryPath = [self.files objectAtIndex:thepath.row];
self.title = #"Devo Songs";
self.filenames = [[documentsDirectoryPath lastPathComponent] stringByDeletingPathExtension];
NSMutableArray *names = [NSMutableArray arrayWithCapacity:[self.files count]];
for (NSString *path in self.files) {
[names addObject:[[path lastPathComponent] stringByDeletingPathExtension]];
}
self.files = [names sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.backgroundColor = [UIColor darkGrayColor];
self.view.backgroundColor = [UIColor grayColor];
[super viewWillAppear:animated];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (self.searchController.isActive) {
return [searchResults count];
}
else {
return [self.files count];
}
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *filename = [[[self.files objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
NSInteger row = [indexPath row];
NSString *contentForThisRow = nil;
contentForThisRow = filename;
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ) {
[[cell textLabel] setText:contentForThisRow];
cell.textLabel.font = [UIFont fontWithName:#"Roboto-Bold" size:38];
cell.textLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor blackColor];
return cell;
}
else {
[[cell textLabel] setText:contentForThisRow];
cell.textLabel.font = [UIFont fontWithName:#"Roboto-Bold" size:22];
cell.textLabel.textColor = [UIColor whiteColor];
cell.backgroundColor = [UIColor darkGrayColor];
return cell;
}
}
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope{
[self updateSearchResultsForSearchController:self.searchController];
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString *searchString = self.searchController.searchBar.text;
NSPredicate *resultPredicate;
resultPredicate = [NSPredicate predicateWithFormat:#"SELF contains[c] %#",searchString];
searchResults = [self.files filteredArrayUsingPredicate:resultPredicate];
NSLog(#"results %lu", (unsigned long)[self.files count]);
[self.tableView reloadData];
}
Remove below code or comment below
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope{
[self updateSearchResultsForSearchController:self.searchController];}
Added the another searchController delegate method in your called show below.
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange (NSRange)range replacementText:(NSString *)text {
[self updateSearchResultsForSearchController:self.searchController];}
This should work. Hope it help :)
I've tried using ASyncImageView for this purpose, but I'm a bit confused as to how I'd implement it for my specific case. I currently have a MatchCenterViewController that contains a table inside of it. It's loading the images for the cells synchronously, which is causing a lot of lag when scrolling through the table. How can I modify the way I'm loading the remote images so that it's done asynchronously? My code is below:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#import "MatchCenterCell.h"
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#property (nonatomic, assign) BOOL matchCenterDone;
#property (nonatomic, assign) BOOL hasPressedShowMoreButton;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_matchCenterDone = NO;
_hasPressedShowMoreButton = NO;
// Set up MatchCenter table
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,70,320,self.view.frame.size.height-100);
self.edgesForExtendedLayout = UIRectEdgeAll;
self.matchCenter.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
self.expandedSection = -1;
_matchCenterArray = [[NSArray alloc] init];
// Refresh button
UIImageView *refreshImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"refresh.png"]];
refreshImageView.frame = CGRectMake(280, 30, 30, 30);
refreshImageView.userInteractionEnabled = YES;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(refreshPressed:)];
[refreshImageView addGestureRecognizer:tapGesture];
[self.view addSubview:refreshImageView];
// Preparing for MC and indicating loading
self.matchCenterArray = [[NSArray alloc] init];
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
_matchCenterDone = NO;
// Disable ability to scroll until table is MatchCenter table is done loading
self.matchCenter.scrollEnabled = NO;
[PFCloud callFunctionInBackground:#"MatchCenter3"
withParameters:#{}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[activityIndicator stopAnimating];
[_matchCenter reloadData];
_matchCenterDone = YES;
self.matchCenter.scrollEnabled = YES;
NSLog(#"Result: '%#'", result);
}
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return _matchCenterArray.count;
}
//the part where i setup sections and the deleting of said sections
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 21.0f;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 40;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
//code snipped out for conciseness
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
//Header code snipped out for conciseness
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *currentSectionDictionary = _matchCenterArray[section];
NSArray *top3ArrayForSection = currentSectionDictionary[#"Top 3"];
return (top3ArrayForSection.count-1 < 1) ? 1 : top3ArrayForSection.count-1;
}
// Cell layout
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"MatchCenterCell";
MatchCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[MatchCenterCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
//[cell.contentView addSubview:cell.priceLabel];
[cell.contentView addSubview:cell.conditionLabel];
// No cell seperators = clean design
tableView.separatorColor = [UIColor clearColor];
NSDictionary *currentSectionDictionary = _matchCenterArray[indexPath.section];
NSArray *top3ArrayForSection = currentSectionDictionary[#"Top 3"];
if (top3ArrayForSection.count-1 < 1) {
// title of the item
cell.textLabel.text = #"No items found, but we'll keep a lookout for you!";
cell.textLabel.font = [UIFont systemFontOfSize:12];
}
else {
// title of the item
cell.textLabel.text = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Title"];
cell.textLabel.font = [UIFont systemFontOfSize:14];
// price + condition of the item
NSString *price = [NSString stringWithFormat:#"$%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Price"]];
NSString *condition = [NSString stringWithFormat:#"%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Item Condition"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%# - %#", price, condition];
cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
// image of the item
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
cell.imageView.layer.masksToBounds = YES;
cell.imageView.layer.cornerRadius = 2.5;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == self.expandedSection || indexPath.row <= 3) {
return 65;
}
return 0;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (_matchCenterDone == YES) {
self.itemURL = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row+1][#"Item URL"];
[self performSegueWithIdentifier:#"WebViewSegue" sender:self];
}
}
#end
#implementation MoreButton
#end
// Use background thread to avoid the laggy tableView
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// Download or get images here
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"url"]];
UIImage *cellImage = [[UIImage alloc] initWithData:imageData];
// Use main thread to update the view. View changes are always handled through main thread
dispatch_async(dispatch_get_main_queue(), ^{
// Refresh image view here
[cell.imageView setImage:cellImage];
[cell.imageView.layer setMasksToBounds:YES];
[cell.imageView.layer setCornerRadius:2.5f];
[cell setNeedsLayout];
});
});
The most common solution to this is AFNetworking's AFImageView. It handles this situation perfectly. It should take you no time at all to implement, so give it a go.
Guy Kogus' answer works great. He's right, I got into all kinds of issues like he mentions in the comment above, doing similar things like the first answer.
Still, here's an example on how to use AFNetworking's UIImageView category. Assuming the code below is in a Cell (or something inheriting from a UIView).
First import the class:
#import "UIImageView+AFNetworking.h"
Then add this code in your UITableViewCell:
NSString *url = #"http://www.domain.www/some_image.jpg";
[self.productImage setImageWithURL:[NSURL URLWithString:url]
placeholderImage:[UIImage imageNamed:#"placeholderImg.png"]];
[self setNeedsLayout];
Not 100% sure if setNeedsLayout is necessary in this case. Feel free to correct this.
I'm trying to implement a UISearchBar in a custom UITableViewController and done programmatically (not using IB). I got the search function to work and return the correct fields, but it is displaying the searched cells over the full list cells:
As you can see, the new searched field is scrollable and selectable. Its just not removing the old cells.
here is my .h file:
#interface TestTableViewController : UITableViewController <UISearchBarDelegate, UISearchDisplayDelegate>
#property (strong, nonatomic) NSArray *boundaries;
#end
.m file:
#import "TestTableViewController.h"
#import "Boundary.h"
#interface TestTableViewController ()
#property (strong, nonatomic) UISearchDisplayController *searchController;
#property (strong, nonatomic) NSMutableArray *filteredBoundaries;
#end
#implementation TestTableViewController
-(instancetype) initWithStyle:(UITableViewStyle)style {
self = [super initWithStyle:style];
if (self) {
self.filteredBoundaries = [NSMutableArray array];
}
return self;
}
-(void)viewDidLoad {
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:TRUE selector:#selector(caseInsensitiveCompare:)];
NSArray *sortDescriptors = #[sortDescriptor];
self.boundaries = [self.boundaries sortedArrayUsingDescriptors:sortDescriptors];
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.delegate = self;
searchBar.placeholder = #"Search Fields";
searchBar.showsCancelButton = TRUE;
self.tableView.tableHeaderView = searchBar;
self.searchController = [[UISearchDisplayController alloc] initWithSearchBar:searchBar contentsController:self];
self.searchController.delegate = self;
self.searchController.searchResultsDataSource = self;
self.searchController.searchResultsDelegate = self;
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Setup Filter Data Source
-(void)filterContentForSearchText:(NSString *)searchText scope:(NSString *)scope {
[self.filteredBoundaries removeAllObjects];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name contains[c] %#", searchText];
self.filteredBoundaries = [NSMutableArray arrayWithArray:[self.boundaries filteredArrayUsingPredicate:predicate]];
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Table view data source
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == self.searchDisplayController.searchResultsTableView) {
return self.filteredBoundaries.count;
}
else {
return self.boundaries.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
Boundary *boundary = [self.filteredBoundaries objectAtIndex:indexPath.row];
cell.textLabel.text = boundary.name;
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
else {
Boundary *boundary = [self.boundaries objectAtIndex:indexPath.row];
cell.textLabel.text = boundary.name;
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.userInteractionEnabled = TRUE;
}
return cell;
}
// ------------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark UISearchDisplayController Delegates
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString {
[self filterContentForSearchText:searchString scope:[[self.searchController.searchBar scopeButtonTitles] objectAtIndex:self.searchController.searchBar.selectedScopeButtonIndex]];
return TRUE;
}
#end
And how I call the table view:
TestTableViewController *tableViewController = [[TestTableViewController alloc] initWithStyle:UITableViewStylePlain];
tableViewController.boundaries = [group.boundaries allObjects];
tableViewController.contentSizeForViewInPopover = POPOVER_SIZE;
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.navigationBar.barStyle = UIBarStyleBlack;
self.myPopoverController = [[UIPopoverController alloc] initWithContentViewController:navController];
self.myPopoverController.delegate = self;
[self.myPopoverController presentPopoverFromRect:button.frame inView:button.superview permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Any ideas what I might be doing wrong or missing?
The problem is that UISearchDisplayController is using another UITableView rather than the view controller's own. You can verify that by logging tableView in -tableView:cellForRowAtIndexPath:.
You can use a UISearchBar without a UISearchDisplayController, to have more control over search and display logic.
Also, if your app doesn't support any version prior to iOS 8, consider using UISearchController. I haven't tried it but it seems to give you more control. Check a sample UISearchDisplayControllerhas been deprecated in iOS 8.
Try this
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 41.0)];
[self.view addSubview:searchBar];
searchBar.delegate=self;
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (isSearching) {
return [filteredContentList count];
}
else {
return [titlearray count];
}
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
if (isSearching)
{
cell.nameLabel.text = [filteredContentList objectAtIndex:indexPath.row];
cell.thumbnailImageView.image =[filteredImgArray objectAtIndex:indexPath.row];
}
else
{
cell.thumbnailImageView.image = [imagearray objectAtIndex:indexPath.row];
cell.nameLabel.text = [titlearray objectAtIndex:indexPath.row];
}
return cell;
}
- (void)searchTableList {
NSString *searchString = searchBar.text;
for (int i=0; i<titlearray.count; i++) {
NSString *tempStr=[titlearray objectAtIndex:i];
NSComparisonResult result = [tempStr compare:searchString options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) range:NSMakeRange(0, [searchString length])];
if (result == NSOrderedSame)
{
[filteredContentList addObject:tempStr];
[filteredImgArray addObject:[imagearray objectAtIndex:i]];
}
}
}
#pragma mark - Search Implementation
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSLog(#"Text change - %d",isSearching);
//Remove all objects first.
[filteredContentList removeAllObjects];
[filteredImgArray removeAllObjects];
if([searchText length] != 0) {
isSearching = YES;
[self searchTableList];
//tblContentList.hidden=NO;
}
else {
isSearching = NO;
// tblContentList.hidden=YES;
}
[tblContentList reloadData];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Cancel clicked");
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSLog(#"Search Clicked");
[self searchTableList];
}
I hope it's help for you
You should implement correct datasource.
Create new array of items for filtered data for first.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger count = ([filteredItems count] > 0) ? [filteredItems count] : [self.allItems count];
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier: #"id"];
MyCustomItem *item = ([filteredItems count] > 0) ? filteredItems[indexPath.row] : self.allItems[indexPath.row];
[self configureCell:cell forItem:item];
return cell;
}
Configure searching:
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchText = searchController.searchBar.text;
if ([searchText length] == 0)
{
[filteredItems removeAllObjects];
[self.tableView reloadData];
return;
}
NSMutableArray *searchResults = [self.allItems mutableCopy];
// SKIP ALL BODY OF SEARCHING
filteredPeoples = searchResults;
[self.tableView reloadData];
}
Will work pretty.
IOS 8 delegate has been deprecated not sure if that's the problem.
The method
here's [a link]https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UISearchDisplayDelegate_Protocol/index.html#//apple_ref/occ/intfm/UISearchDisplayDelegate/searchDisplayControS 8 delegate has been deprecated not sure if that's the problem.
The method
try this property instead
#property(nonatomic, assign) id< UISearchResultsUpdating > searchResultsUpdater
another better link [a link]https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Listings/TableSearch_obj_c_TableSearch_APLResultsTableController_m.html
i have a table view with section and i would like to start the table view with all section grouped like this:
Section1
Section2
Section3
When i tap on a section title, it expand the rows
Section1
Row1
Row2
Row3
Section2
Section3
i requested to all please see the answer if you dont like,just comment
this is for beginners....
this code also refered from net only and i changed few things
this link
creat class file...
ViewController.h file should be
#import <UIKit/UIKit.h>
#import "oneViewController.h"
#import "secondViewController.h"
#import "thirdViewController.h"
#interface ViewController : UIViewController
{
oneViewController *one;
secondViewController *second;
thirdViewController *third;
}
#end
ViewController.m file should be
#import "ViewController.h"
#import "Cell1.h"
#import "Cell2.h"
#interface ViewController()<UITableViewDataSource,UITableViewDelegate>
{
NSMutableArray *dataList;
}
#property (assign)BOOL isOpen;
#property (nonatomic,retain)NSIndexPath *selectIndex;
#property (nonatomic,retain)IBOutlet UITableView *expansionTableView;
#end
#implementation ViewController
#synthesize isOpen,selectIndex;
- (void)dealloc
{
[dataList release];
dataList= nil;
self.expansionTableView = nil;
self.isOpen = NO;
self.selectIndex = nil;
[super dealloc];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nil];
if (self) {
one=[[oneViewController alloc]init ];
second=[[secondViewController alloc]init];
third=[[thirdViewController alloc]init];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"array" ofType:#"plist"];
dataList = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSLog(#"%lu",(unsigned long)dataList.count);
self.expansionTableView.sectionFooterHeight = 0;
self.expansionTableView.sectionHeaderHeight = 0;
self.isOpen = NO;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [dataList count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (self.isOpen) {
if (self.selectIndex.section == section) {
return [[[dataList objectAtIndex:section] objectForKey:#"list"] count]+1;
}
}
return 1;
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 40;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",[[dataList objectAtIndex:indexPath.section]objectForKey:#"list"] );
if (self.isOpen&&indexPath.section == indexPath.section&&indexPath.row!=0) {
static NSString *CellIdentifier = #"Cell2";
Cell2 *cell = (Cell2*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
if ([[dataList objectAtIndex:indexPath.section]objectForKey:#"list"])
{
NSArray *list = [[dataList objectAtIndex:indexPath.section] objectForKey:#"list"];
cell.titleLabel.text = [list objectAtIndex:indexPath.row-1];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
return cell;
}
return cell;
}else
{
static NSString *CellIdentifier = #"Cell1";
Cell1 *cell = (Cell1*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil] objectAtIndex:0];
}
NSString *name = [[dataList objectAtIndex:indexPath.section] objectForKey:#"name"];
cell.titleLabel.text = name;
//[cell changeArrowWithUp:([indexPath isEqual:indexPath]?YES:NO)];
if ([indexPath isEqual:indexPath])
{
[cell changeArrowWithUp:YES];
}
else
{
[cell changeArrowWithUp:NO];
}
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == 0) {
if ([indexPath isEqual:self.selectIndex]) {
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:YES];
self.isOpen = NO;
[self didSelectCellRowFirstDo:NO nextDo:NO];
self.selectIndex = nil;
}else
{
if (!self.selectIndex) {
self.selectIndex = indexPath;
[self didSelectCellRowFirstDo:YES nextDo:NO];
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:NO];
}else
{
NSIndexPath *tempIndex=indexPath;
if (tempIndex)
{
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:tempIndex];
[cell changeArrowWithUp:NO];
}
Cell1 *cell = (Cell1 *)[self.expansionTableView cellForRowAtIndexPath:self.selectIndex];
[cell changeArrowWithUp:YES];
[self didSelectCellRowFirstDo:NO nextDo:YES];
}
}
}else
{
NSDictionary *dic = [dataList objectAtIndex:indexPath.section];
NSArray *list = [dic objectForKey:#"list"];
NSString *item = [list objectAtIndex:indexPath.row-1];
UIAlertView *alert=[[UIAlertView alloc]initWithTitle:#"sample tree" message:item delegate:self cancelButtonTitle:#"ok" otherButtonTitles:nil];
[alert show];
// NSArray* temp=[NSArray arrayWithObjects:one,second,third,nil];
// [self viewPresent:[temp objectAtIndex:indexPath.row-1] sectionAt:item];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
//method for pushing view controller
-(void)viewPresent:(UIViewController *)viewName sectionAt:(NSString *)sectionValue
{
[[self navigationController]pushViewController:viewName animated:YES];
}
- (void)didSelectCellRowFirstDo:(BOOL)firstDoInsert nextDo:(BOOL)nextDoInsert
{
self.isOpen = firstDoInsert;
[self.expansionTableView beginUpdates];
int section = self.selectIndex.section;
int contentCount = [[[dataList objectAtIndex:section] objectForKey:#"list"] count];
NSMutableArray* rowToInsert = [[NSMutableArray alloc] init];
for (NSUInteger i = 1; i < contentCount + 1; i++) {
NSIndexPath* indexPathToInsert = [NSIndexPath indexPathForRow:i inSection:section];
[rowToInsert addObject:indexPathToInsert];
}
if (firstDoInsert)
{ [self.expansionTableView insertRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
else
{
[self.expansionTableView deleteRowsAtIndexPaths:rowToInsert withRowAnimation:UITableViewRowAnimationTop];
}
[rowToInsert release];
[self.expansionTableView endUpdates];
if (nextDoInsert) {
self.isOpen = YES;
self.selectIndex = [self.expansionTableView indexPathForSelectedRow];
[self didSelectCellRowFirstDo:YES nextDo:NO];
}
// if (self.isOpen) [self.expansionTableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}
#end
then create two cell with subclass of UITableViewCell
the first cell should be
.h file
#import <UIKit/UIKit.h>
#interface Cell1 : UITableViewCell
#property (nonatomic,retain)IBOutlet UILabel *titleLabel;
#property (nonatomic,retain)IBOutlet UIImageView *arrowImageView;
- (void)indication:(BOOL)up;
#end
.m file
#import "Cell1.h"
#implementation Cell1
#synthesize titleLabel,arrowImageView;
- (void)dealloc
{
self.titleLabel = nil;
self.arrowImageView = nil;
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
- (void)indication:(BOOL)up
{
if (up) {
self.arrowImageView.image = [UIImage imageNamed:#"UpAccessory.png"];
}else
{
self.arrowImageView.image = [UIImage imageNamed:#"DownAccessory.png"];
}
}
the second cell should be
.h file
#import <UIKit/UIKit.h>
#interface Cell2 : UITableViewCell
#property (nonatomic,retain)IBOutlet UILabel *titleLabel;
#end
.m file
#import "Cell2.h"
#implementation Cell2
#synthesize titleLabel;
- (void)dealloc
{
self.titleLabel = nil;
[super dealloc];
}
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
// Configure the view for the selected state
}
for learning purpose my values are like below
(
{
list = (
1,
2,
3
);
name = Numbers;
},
{
list = (
a,
b,
c
);
name = Alaphabets;
},
{
list = (
India,
China,
Australia
);
name = Countries;
}
)
In my iPhone app I just parse the JSON from a url and save it to arrays. After completing JSON parsing my UICollectionView should be updated with the new array values. But my UICollectionView isn't updating. Please look through my following coding
#interface SpecialPgms ()
#property (strong, nonatomic) IBOutlet UICollectionView *collecSpecial;
#end
#implementation SpecialPgms
NSMutableArray *arrTitle,*arrUrl,*arrImg;
UICollectionViewCell *cell ;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_sidebarButton.tintColor = [UIColor colorWithWhite:0.1f alpha:0.9f];
_sidebarButton.target = self.revealViewController;
_sidebarButton.action = #selector(revealToggle:);
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
self.collecSpecial.delegate=self;
self.collecSpecial.dataSource=self;
[self loadJSON];
}
-(void)loadJSON{
arrTitle=[[NSMutableArray alloc]init];
arrUrl=[[NSMutableArray alloc]init];
arrImg=[[NSMutableArray alloc]init];
[pro startAnimating];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
JSONDecoder *decoder = [JSONDecoder decoderWithParseOptions:JKParseOptionStrict];
NSData *immutableItemList = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:#"https://gdata.youtube.com/feeds/api/videos?author=jiljilmedia&v=2&alt=jsonc"]];
NSData *data =immutableItemList;
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData* data1 = [string dataUsingEncoding:NSUTF8StringEncoding];
NSArray *returnedData = (NSArray *) [[[decoder objectWithData:data1] objectForKey:#"data"] objectForKey:#"items"];
for(NSDictionary * student in returnedData){
NSString *strTitle=[student objectForKey:#"title"];
NSDictionary *Thumbnail=[student objectForKey:#"thumbnail"];
NSString *strImg = Thumbnail[#"sqDefault"];
NSDictionary *player = student[#"player"];
NSString *strdefaultUrl = player[#"default"];
NSString *strMobileUrl=player[#"mobile"];
[arrTitle addObject:strTitle];
//NSLog(#"%#",strImg);
if(strMobileUrl.length==0){
[arrUrl addObject:strdefaultUrl];
}
else{
[arrUrl addObject:strMobileUrl];
}
[arrImg addObject:strImg];
}
[self performSelectorOnMainThread:#selector(setProgramTableView:) withObject:[NSArray arrayWithObjects: nil] waitUntilDone:YES];
});
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return arrTitle.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"Cell";
cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:[arrImg objectAtIndex:indexPath.row]];
UILabel *lab = (UILabel *)[cell viewWithTag:101];
lab.text= [arrImg objectAtIndex:indexPath.row];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"photo-frame.png"]];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%d",indexPath.row);
}
////// JSON Parsing for video links////////////////////
- (void)setProgramTableView: (NSArray*)array
{
dispatch_async(dispatch_get_main_queue(), ^{
[ self.collecSpecial reloadData];
[ self.collecSpecial.collectionViewLayout invalidateLayout];
});
[pro stopAnimating];
}