I try to make a little program to learn more about searching a tableview about a searchbar. Meanwhile i'm in the third week trying to do this. I found many examples in different ways in the internet. The most with a searchdisplaycontroller but this way is only for a viewcontroller. i prefer a way that also works with an uiview and so i use the searchbar delegatemethod to filter my data dictionary. Normally i try as long i get handle such things by myself. But this is my nemesis. I really can't find a way to get this problem solved. Can anyone help me with my code?
Here it is.
#import "FilterDemoTableViewController.h"
#implementation FilterDemoTableViewController
#synthesize filteredTableData;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize tableContents;
#synthesize Keys;
- (void)viewDidLoad
{
[super viewDidLoad];
searchBar.delegate = (id)self;
//-----------------------My TableView Data ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
//--------------------------------------------------------------------------
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered) {
return [filteredTableData count];
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
int rowCount;
if(self.isFiltered)
rowCount = filteredTableData.count;
else
rowCount = [listData count];
return rowCount;
}
- (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];
NSDictionary* sectionDictionary;
if (isFiltered) {
sectionDictionary = [filteredTableData objectAtIndex:indexPath.section];
} else {
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
}
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
//I think here is something wrong but i don't know what
isFiltered = true;
filteredTableData = [[NSMutableArray alloc] init];
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (NSDictionary *dictionary in tableContents) //dictionary read
{
NSArray *array = [dictionary objectForKey:Keys]; //section of dictionary read
[searchArray addObjectsFromArray:array];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
[filteredTableData addObject:sTemp];
}
}
[self.tableView reloadData];
}
- (void)viewDidUnload{
[self setSearchBar:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Now i post a complete refreshed code. I tested each component of the code step by step. It works and the search is also fine (in a UITableViewController). But in this example the hole code is in a UIView. The reason, on this way it is possible to create non full-size tableviews and instanzes of tableviews. Much better for a clear Viewcontroller. I know that an UIView has no method like this reloadData but it is necessary.
Near the code end you can see the problem line. And for this last step i have no idea how i can solve this. [self.tableView reloadData];
#import "TableView.h"
#import <QuartzCore/QuartzCore.h>
#interface TableView ()
#end
#implementation TableView
#synthesize delegate;
#synthesize dropDownHeight;
#synthesize labelText;
#synthesize enabled;
#synthesize tableContents;
#synthesize Keys;
#synthesize searchBar;
#synthesize isFiltered;
#synthesize filteredTableData;
- (void)__show {
viewControl.alpha = 0.0f;
UIWindow *mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:viewControl];
[UIView animateWithDuration:0.3f
animations:^{
viewControl.alpha = 1.0f;
}
completion:^(BOOL finished) {}];
}
- (void)__hide {
[UIView animateWithDuration:0.2f
animations:^{
viewControl.alpha = 0.0f;
}
completion:^(BOOL finished) {
[viewControl removeFromSuperview];
}];
}
- (void) setLabelText:(NSString *)_labelText{
[button setTitle:labelText forState:UIControlStateNormal];
}
- (void) setEnable:(BOOL)_enabled{
enabled = _enabled;
[button setEnabled:_enabled];
}
- (void) setArrayData:(NSArray *)_arrayData{
[table reloadData];
}
- (void) buttonPressed{
[self __show];
}
- (void) controlPressed{
//[viewControl removeFromSuperview];
[self __hide];
}
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
button = [UIButton buttonWithType:UIButtonTypeCustom];
[button setFrame:CGRectMake(10, 0, 280, 30)];
[button setTitle:#"--Auswahl--" forState:UIControlStateNormal];
[button setBackgroundImage:[UIImage imageNamed:#"combo_bg.png"] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button.titleLabel setFont:[UIFont fontWithName:#"Helvetica" size:14]];
[self addSubview:button];
dropDownHeight = 706;
viewControl = [[UIControl alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
[viewControl addTarget:self action:#selector(controlPressed) forControlEvents:UIControlEventTouchUpInside];
CGFloat x = self.frame.origin.x;
CGFloat y = (viewControl.frame.size.height - dropDownHeight)/2;
table = [[UITableView alloc] initWithFrame:CGRectMake(x, y, frame.size.width, dropDownHeight) style:UITableViewStyleGrouped];
table.dataSource = self;
table.delegate = self;
searchBar = [[UISearchBar alloc] init];
[searchBar sizeToFit];
searchBar.delegate = (id)self;
table.tableHeaderView = searchBar;
CALayer *layer = table.layer;
layer.masksToBounds = YES;
layer.cornerRadius = 2.0f;
layer.borderWidth = 1.0f;
[layer setBorderColor:[UIColor darkGrayColor].CGColor];
[viewControl addSubview:table];
CGAffineTransform rotateTable = CGAffineTransformMakeRotation(M_PI_2);
table.transform = rotateTable;
table.frame = CGRectMake(-2, -1, table.frame.size.width, table.frame.size.height);
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"gradientBackground.png"]];
[tempImageView setFrame:self->table.frame];
table.backgroundView = tempImageView;
//----------------------- TableView Daten ------------------------------
NSArray *array1 = [[NSArray alloc]initWithObjects:#"Berlin",#"München",#"Stuttgart",#"Hamburg",nil];
NSArray *array2 = [[NSArray alloc]initWithObjects:#"Paris",#"Bordeaux",#"Marseille",#"Toulouse",nil];
NSArray *array3 = [[NSArray alloc]initWithObjects:#"London",#"Portsmouth",#"Oxford",#"York",#"Dover",nil];
NSArray *array4 = [[NSArray alloc]initWithObjects:#"Rom" ,#"Genua",#"Mailand",#"Florenz",nil];
NSArray *array5 = [[NSArray alloc]initWithObjects:#"Madrid",#"Barcelona",#"Toledo",#"Saragossa",#"Pamplona",nil];
NSDictionary *dictionary =[[NSDictionary alloc]initWithObjectsAndKeys:array1,#"Deutschland",array2,#"Frankreich",array3,#"Großbritannien",array4,#"Italien",array5,#"Spanien",nil];
self.tableContents = dictionary;
self.Keys = [self.tableContents allKeys];
// ---------------------------------------------------------------------
}
return self;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if ([self tableView:tableView titleForHeaderInSection:section] != nil) {
return 40;
}
else {
return 0;
}
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
if (sectionTitle == nil) {
return nil;
}
// Create label with section title
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(20, 6, 300, 30);
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
label.shadowColor = [UIColor grayColor];
label.shadowOffset = CGSizeMake(0.0, 1.0);
label.font = [UIFont boldSystemFontOfSize:16];
label.text = sectionTitle;
// Create header view and add label as a subview
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
[view addSubview:label];
return view;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60.0;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
return [self.Keys objectAtIndex:section];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (self.isFiltered)
{
return 1;
} else {
return [Keys count];}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int rowCount;
if(self.isFiltered)
{
rowCount = [filteredTableData count];
}
else
{
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:section]];
rowCount = [listData count];
}
return rowCount;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier];
}
if (isFiltered)
{
NSString * stadt = [filteredTableData objectAtIndex:indexPath.row];
cell.textLabel.text = stadt;
}
else
{
NSDictionary* sectionDictionary;
sectionDictionary = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
NSArray* sectionEntries = [self.tableContents objectForKey:[self.Keys objectAtIndex:indexPath.section]];
cell.textLabel.text = [sectionEntries objectAtIndex:indexPath.row];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *listData =[self.tableContents objectForKey:[self.Keys objectAtIndex:[indexPath section]]];
NSUInteger row = [indexPath row];
NSString *rowValue = [listData objectAtIndex:row];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndex = [indexPath row];
[self __hide];
[button setTitle:[[NSString alloc] initWithFormat:rowValue] forState:UIControlStateNormal];
}
- (NSInteger) selectedIndex {
return selectedIndex;
}
-(void)searchBar:(UISearchBar*)searchBar textDidChange:(NSString*)text
{
if(text.length == 0)
{
isFiltered = FALSE;
}
else
{
isFiltered = true;
[filteredTableData removeAllObjects];
for (NSString* key in self.tableContents)
{
NSArray *staedte = [self.tableContents objectForKey:key];
for (NSString *stadt in staedte)
{
NSRange titleResultsRange = [stadt rangeOfString:text options:NSCaseInsensitiveSearch];
if (titleResultsRange.length != 0)
{
[filteredTableData addObject:stadt];
}
}
}
}
[self.tableView reloadData]; //Here is the error
}
-(void)didChangeTableViewValue:(TableView *)TableView selectedIndex:(NSInteger)selectedIndex {
}
#end
Related
I am new in iOS developer. When I run the the app than time iI
but I will get this type of output.
Here is my code
- (void) iterateItems:(NSArray*) array
{
level++;
for (int i = 0; i < [array count]; i++)
{
commentInfo = [array objectAtIndex:i];
//NSLog(#"data=%#",commentInfo);
Item *item = [[Item alloc] init];
item.Id = [[[commentInfo objectForKey:#"sub_items"]objectAtIndex:0]objectForKey:#"name"];
item.parentId = [[[commentInfo objectForKey:#"sub_items"]objectAtIndex:0]objectForKey:#"name"];
if (item.level == 0)
{
item.title =[commentInfo objectForKey:#"dates"];
item.title1 =[commentInfo objectForKey:#"id"];
}
else
{
item.title=#"abc";
}
//NSLog(#"title is=%#",[commentInfo objectForKey:#"status"]);
item.level = level;
item.visibility = #"normal";
item.childVisibility = #"normal";
[items addObject:item];
[self iterateItems:[commentInfo objectForKey:#"sub_items"]];
}
level--;
}
- (float) cellHeightForRow:(int) row
{
Item *item = [items objectAtIndex:row];
if ([item.visibility isEqualToString:#"hidden"])
{
return 0.0f;
}
else
{
return 50.0f;
}
}
- (void) hideCompleteNode:(UISwipeGestureRecognizer*) gestureRecognizer
{
UITableViewCell *cell = (UITableViewCell*) [[gestureRecognizer view] superview];
NSIndexPath *indexPath = [self.tblView indexPathForCell:cell];
Item *item = [items objectAtIndex:indexPath.row];
if (item.level == 0)
{
if ([item.childVisibility isEqualToString:#"normal"])
{
[self hideChilds:indexPath];
}
}
else
{
int prevIndex = indexPath.row-1;
if (prevIndex >= 0)
{
Item *parentItem = [items objectAtIndex:prevIndex];
while (parentItem.level != 0)
{
prevIndex--;
if (prevIndex >= 0)
parentItem = [items objectAtIndex:prevIndex];
else
break;
}
}
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:prevIndex inSection:0];
[self hideChilds:indexPath];
}
}
- (void) hideChilds:(NSIndexPath*) indexPath
{
NSMutableArray *indexPaths = [[NSMutableArray alloc] initWithObjects:indexPath, nil];
Item *item = [items objectAtIndex:indexPath.row];
BOOL shouldHide = [item.childVisibility isEqualToString:#"hidden"]?NO:YES;
item.childVisibility = shouldHide?#"hidden":#"normal";
int nextIndex = indexPath.row+1;
if (nextIndex < [items count])
{
Item *childItem = [items objectAtIndex:nextIndex];
while (childItem.level > item.level)
{
childItem.visibility = shouldHide?#"hidden":#"normal";
childItem.childVisibility = shouldHide?#"hidden":#"normal";
[indexPaths addObject:[NSIndexPath indexPathForRow:nextIndex inSection:0]];
nextIndex++;
if (nextIndex < [items count])
childItem = [items objectAtIndex:nextIndex];
else
break;
}
}
[self.tblView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
}
#pragma mark -
#pragma mark - UITableView Datasource and Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [items count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self cellHeightForRow:indexPath.row];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"itemCell";
UITableViewCell *cell = [self.tblView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
UIImageView *arrowImgView = [[UIImageView alloc] init];
[arrowImgView setBackgroundColor:[UIColor clearColor]];
[arrowImgView setTag:1];
[cell.contentView addSubview:arrowImgView];
UILabel *titleLbl = [[UILabel alloc] init];
[titleLbl setFont:[UIFont fontWithName:#"HelveticaNeue" size:13.0f]];
[titleLbl setTextColor:[UIColor blackColor]];
titleLbl.textAlignment = NSTextAlignmentCenter;
[titleLbl setTag:2];
[titleLbl setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:titleLbl];
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(hideCompleteNode:)];
[swipeGesture setDirection:UISwipeGestureRecognizerDirectionLeft];
[cell.contentView addGestureRecognizer:swipeGesture];
}
Item *item = [items objectAtIndex:indexPath.row];
if (item.level == 0)
{
[cell.contentView setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cell_background.png"]]];
}
else
{
[cell.contentView setBackgroundColor:[UIColor clearColor]];
}
UIImageView *arrowImgView = (UIImageView*) [cell viewWithTag:1];
UILabel *titleLbl = (UILabel*) [cell viewWithTag:2];
if ([item.visibility isEqualToString:#"hidden"])
{
[titleLbl setFrame:CGRectZero];
[arrowImgView setFrame:CGRectZero];
}
else
{
[arrowImgView setFrame:CGRectMake(5.0f+(20.0f*item.level), 20.0f, 10.0f, 10.0f)];
if ([item.childVisibility isEqualToString:#"hidden"])
{
[arrowImgView setImage:[UIImage imageNamed:#"closeArrow"]];
}
else
{
[arrowImgView setImage:[UIImage imageNamed:#"openArrow"]];
}
[titleLbl setFrame:CGRectMake(20.0f+(20.0f*item.level), 10.0f, 320.0f - (20.0f+(20.0f*item.level)), 30.0f)];
[titleLbl setText:item.title];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.layer.shadowOpacity = 0.3;
cell.layer.shadowColor = [UIColor blueColor].CGColor;
cell.layer.shadowOffset = CGSizeMake(0.0, 4);
[tblView setSeparatorColor:[UIColor redColor]];
tblView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
[tblView setSeparatorColor:[UIColor blackColor]];
tblView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
// [self hideChilds:indexPath];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell *)[self.tblView cellForRowAtIndexPath:indexPath];
cell.contentView.backgroundColor = [UIColor colorWithRed:0.004 green:0.482 blue:0.776 alpha:1];
[self hideChilds:indexPath];
Item *item = [items objectAtIndex:indexPath.row];
if (item.level == 0)
{
}
else
{
Item *item = [items objectAtIndex:indexPath.row];
NSLog(#"value=%#",[NSString stringWithFormat:#"%#",item.title1]);
approveleaseoffer *secondViewController =
[self.storyboard instantiateViewControllerWithIdentifier:#"approveleaseofferpage"];
secondViewController.offer_number=[NSString stringWithFormat:#"%#",item.title1];
[self.navigationController pushViewController:secondViewController animated:YES];
}
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cell respondsToSelector:#selector(setSeparatorInset:)]) {
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if ([cell respondsToSelector:#selector(setLayoutMargins:)]) {
[cell setLayoutMargins:UIEdgeInsetsZero];
}
}
-(void)viewDidLayoutSubviews
{
if ([tblView respondsToSelector:#selector(setSeparatorInset:)]) {
[tblView setSeparatorInset:UIEdgeInsetsZero];
}
if ([tblView respondsToSelector:#selector(setLayoutMargins:)]) {
[tblView setLayoutMargins:UIEdgeInsetsZero];
}
}
Try changing the line item.childVisibility = #"normal"; to item.childVisibility = #"hidden";
in iterateItems method.
New to iOS...i am trying to do a search with a downloaded NSMutableArray table using searchbar or do need to get search from mysql table...its driving me nuts here is code below...any help would be appreciated
#import "VendorViewController.h"
#import "VendLocation.h"
#import "VendorDetailController.h"
#interface VendorViewController ()
{
VendorModel *_VendorModel; NSMutableArray *_feedItems; VendLocation *_selectedLocation; UIRefreshControl *refreshControl;
}
#property (nonatomic, weak) IBOutlet UISearchBar *searchBar;
#end
#implementation VendorViewController
//#synthesize item;
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = #"Vendors";
self.searchBar.hidden = YES;
self.searchBar.delegate = self;
self.searchBar.barTintColor = [UIColor clearColor];
//self.searchBar.barTintColor = [UIColor orangeColor];
_feedItems = [[NSMutableArray alloc] init];
_VendorModel = [[VendorModel alloc] init];
_VendorModel.delegate = self;
[_VendorModel downloadItems];
#pragma mark Bar Button
UIBarButtonItem *searchItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:#selector(searchButton:)];
NSArray *actionButtonItems = #[searchItem];
self.navigationItem.rightBarButtonItems = actionButtonItems;
#pragma mark Table Refresh
UIView *refreshView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[self.tableView insertSubview:refreshView atIndex:0]; //the tableView is a IBOutlet
refreshControl = [[UIRefreshControl alloc] init];
refreshControl.backgroundColor = [UIColor grayColor];
refreshControl.tintColor = [UIColor whiteColor];
[refreshControl addTarget:self action:#selector(reloadDatas) forControlEvents:UIControlEventValueChanged];
NSMutableAttributedString *refreshString = [[NSMutableAttributedString alloc] initWithString:#"Refreshing"];
//add date to refresh
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"MMM d, h:mm a"];
NSString *lastUpdated = [NSString stringWithFormat:#"Last updated on %#", [formatter stringFromDate:[NSDate date]]];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdated];
[refreshString addAttributes:#{NSForegroundColorAttributeName : [UIColor whiteColor]} range:NSMakeRange(0, refreshString.length)];
[refreshView addSubview:refreshControl];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
**#pragma mark - Search
- (void)searchButton:(id)sender{
[self.searchBar becomeFirstResponder];
self.searchBar.hidden = NO;
//[self.listTableView resignFirstResponder];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar{
self.searchBar.hidden = YES;
}
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0)
{
isFilltered = NO;
} else {
isFilltered = YES;
filteredString = [[NSMutableArray alloc]init];
for(NSString *vendorName in _feedItems)
{
NSRange vendorNameRange = [vendorName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(vendorNameRange.location != NSNotFound) {
[filteredString addObject:vendorName];
}
}
}
[self.listTableView reloadData];
}**
#pragma mark - Table
-(void)reloadDatas {
[refreshControl endRefreshing];
}
-(void)itemsDownloaded:(NSMutableArray *)items
{ // This delegate method will get called when the items are finished downloading
_feedItems = items;
[self.listTableView reloadData];
}
#pragma mark Table Delete Button
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView
editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleDelete;
}
- (void) setEditing:(BOOL)editing
animated:(BOOL)animated{
[super setEditing:editing
animated:animated];
[self.listTableView setEditing:editing
animated:animated];
}
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[_feedItems removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView reloadData];
/*
NSError *error = nil;
if (![tableView save:&error]) {
NSLog(#"Can't Delete! %# %#", error, [error localizedDescription]);
return;
} */
}
}
#pragma mark TableView Delegate Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (isFilltered) {
return [filteredString count];
}
return _feedItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
VendLocation *item = _feedItems[indexPath.row];
static NSString *CellIdentifier = #"BasicCell";
UITableViewCell *myCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
myCell.layer.cornerRadius = 5;
myCell.layer.masksToBounds = YES;
if (myCell == nil) {
myCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; }
if (!isFilltered) {
myCell.textLabel.text = item.vendorName;
myCell.detailTextLabel.text = item.vendorNo;
//Retreive an image
UIImage *myImage = [UIImage imageNamed:#"DemoCellImage"];
[myCell.imageView setImage:myImage];
} else {
myCell.textLabel.text = [filteredString objectAtIndex:indexPath.row];
myCell.detailTextLabel.text = nil;
}
return myCell;
}
#pragma mark Tableheader
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
return 55.0;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *newString = [NSString stringWithFormat:#"VENDOR \n%lu", (unsigned long) _feedItems.count];
NSString *newString1 = [NSString stringWithFormat:#"NASDAQ \n4,727.35"];
NSString *newString2 = [NSString stringWithFormat:#"DOW \n17,776.80"];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 0)];
tableView.tableHeaderView = view; //makes header move with tablecell
[view setBackgroundColor:[UIColor clearColor]];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(12, 3, tableView.frame.size.width, 45)];
[label setFont:[UIFont systemFontOfSize:12]];
[label setTextColor:[UIColor whiteColor]];
label.numberOfLines = 0;
NSString *string = newString;
[label setText:string];
[view addSubview:label];
UIView* separatorLineView = [[UIView alloc] initWithFrame:CGRectMake(12, 45, 60, 1.5)];
separatorLineView.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView];
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(85, 3, tableView.frame.size.width, 45)];
label1.numberOfLines = 0;
[label1 setFont:[UIFont systemFontOfSize:12]];
[label1 setTextColor:[UIColor whiteColor]];
NSString *string1 = newString1;
[label1 setText:string1];
[view addSubview:label1];
UIView* separatorLineView1 = [[UIView alloc] initWithFrame:CGRectMake(85, 45, 60, 1.5)];
separatorLineView1.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView1];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(158, 3, tableView.frame.size.width, 45)];
label2.numberOfLines = 0;
[label2 setFont:[UIFont systemFontOfSize:12]];
[label2 setTextColor:[UIColor whiteColor]];
NSString *string2 = newString2;
[label2 setText:string2];
[view addSubview:label2];
UIView* separatorLineView2 = [[UIView alloc] initWithFrame:CGRectMake(158, 45, 60, 1.5)];
separatorLineView2.backgroundColor = [UIColor redColor];
[view addSubview:separatorLineView2];
return view;
}
here is my header
#import <UIKit/UIKit.h>
#import "VendorModel.h"
#interface VendorViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, VendorModelProtocol>
{
// NSMutableArray *_feedItems;
NSMutableArray *filteredString;
BOOL isFilltered;
}
#property (weak, nonatomic) IBOutlet UITableView *listTableView;
#property (weak, nonatomic) IBOutlet UITableView *tableView;
#end
Changed Code to textDidChange
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if(searchText.length == 0)
{
isFilltered = NO;
} else {
isFilltered = YES;
filteredString = [[NSMutableArray alloc]init];
for(VendLocation* vendor in _feedItems)
{
NSRange stringRange = [vendor.vendorName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location != NSNotFound) {
[filteredString addObject:vendor];
}
}
}
[self.tableView reloadData];
}
i changed filter too this code still no luck hit a key and crash
if(searchText.length == 0)
{
isFilltered = NO;
[filteredString removeAllObjects];
[filteredString addObjectsFromArray:_feedItems];
} else {
isFilltered = YES;
// filteredString = [[NSMutableArray alloc]init];
[filteredString removeAllObjects];
for(NSString* string in _feedItems)
{
NSRange stringRange = [string rangeOfString:searchText options:NSCaseInsensitiveSearch];
if(stringRange.location != NSNotFound) {
[filteredString addObject:string];
}
}
}
[self.tableView reloadData];
If you already have a downloaded NSMutableArray with data in it then your search can consist of merely searching through the array and filtering out entries that do not match. You do not have to go back to MySQL.
I am trying to show a UIActivityIndicatorView while my table view is loading data and have it disappear once loading is finished. The loading indicator never appears. What am I doing wrong?
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
#define storeURL [NSURL URLWithString: #"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=PL9DC706DCCCE00188&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"]
#import "BBYoutubeVideosTableViewController.h"
#import "Reachability.h"
#import "TSMessage.h"
#import "TSMessageView.h"
#import "YoutubeCell.h"
#import "KFBYoutubeVideoView.h"
#import "KFBAppDelegate.h"
#interface BBYoutubeVideosTableViewController ()
{
UIActivityIndicatorView *loadingIndicator;
}
#end
#implementation BBYoutubeVideosTableViewController
#synthesize title, videoID, thumbURL, descriptionString, url, titleArray, videoIDArray, thumbArray, descriptionArray;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"" style:UIBarButtonItemStylePlain target:nil action:nil];
UIImageView *backgroundImage = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"plain_app-background.png"]];
CGFloat width = [[UIScreen mainScreen]bounds].size.width;
CGFloat height = [[UIScreen mainScreen]bounds].size.height;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(width / 2, height / 2, 37, 37)];
loadingIndicator.center = CGPointMake(width / 2, height / 2 - 37);
}
else
{
loadingIndicator = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(142, 365, 37, 37)];
}
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleGray;
loadingIndicator.hidesWhenStopped = YES;
Reachability *networkReachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [networkReachability currentReachabilityStatus];
if(networkStatus == NotReachable)
{
[TSMessage showNotificationWithTitle:#"Network Error" subtitle:#"No active network connection!" type:TSMessageNotificationTypeError];
[loadingIndicator stopAnimating];
}
else {
[self.tableView addSubview:loadingIndicator];
[loadingIndicator startAnimating];
}
self.title = #"Bluegrass & Backroads";
self.tableView = [[UITableView alloc]initWithFrame:CGRectZero style:UITableViewStyleGrouped];
self.tableView.backgroundView = backgroundImage;
url = [NSURL URLWithString:#"https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=25&playlistId=PL9DC706DCCCE00188&key=AIzaSyBS4do208_KPGHAhszfVkHadSvtfSgr7Mo"];
dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:url];
if (data == nil)
{
NSLog(#"data is nil");
}
else
{
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
}
});
}
- (void)viewDidDisappear:(BOOL)animated
{
[loadingIndicator stopAnimating];
}
- (void)fetchedData:(NSData *)responseData
{
NSError *error;
titleArray = [[NSMutableArray alloc]init];
videoIDArray = [[NSMutableArray alloc]init];
thumbArray = [[NSMutableArray alloc]init];
descriptionArray = [[NSMutableArray alloc]init];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray *items = [json objectForKey:#"items"];
for (NSDictionary *item in items)
{
NSDictionary *snippet = [item objectForKey:#"snippet"];
title = [snippet objectForKey:#"title"];
videoID = [[snippet objectForKey:#"resourceId"] objectForKey:#"videoId"];
thumbURL = [[[snippet objectForKey:#"thumbnails"] objectForKey:#"default"] objectForKey:#"url"];
descriptionString = [snippet objectForKey:#"description"];
[titleArray addObject:title];
[videoIDArray addObject:videoID];
UIImage *thumbnailImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:thumbURL]]];
[thumbArray addObject:thumbnailImage];
[descriptionArray addObject:descriptionString];
}
[self.tableView reloadData];
[loadingIndicator stopAnimating];
}
- (IBAction)morePressed:(id)sender
{
NSURL *kyfbVideos = [NSURL URLWithString:#"https://www.youtube.com/playlist?list=PL9DC706DCCCE00188"];
[[UIApplication sharedApplication] openURL:kyfbVideos];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [titleArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 215;
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
return 60;
}
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
{
UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
UIView *footerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height)];
footerView.backgroundColor = [UIColor clearColor];
CGFloat width = footerView.frame.size.width;
UIButton *moreButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
moreButton.backgroundColor = [UIColor clearColor];
[moreButton setTitle:#"More" forState:UIControlStateNormal];
[moreButton setTitleColor:kfbBlue forState:UIControlStateNormal];
moreButton.titleLabel.textAlignment = NSTextAlignmentCenter;
moreButton.titleLabel.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:25.0];
moreButton.frame = CGRectMake(width / 2 - 25, 0, 50, 50);
moreButton.layer.cornerRadius = 25.0;
moreButton.layer.borderWidth = 2.0f;
moreButton.layer.borderColor = kfbBlue.CGColor;
moreButton.clipsToBounds = YES;
moreButton.backgroundColor = [UIColor clearColor];
[moreButton addTarget:self action:#selector(morePressed:) forControlEvents:UIControlEventTouchUpInside];
[footerView addSubview:moreButton];
return footerView;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
YoutubeCell *cell = [tableView dequeueReusableCellWithIdentifier:#"youtubeCell"];
if (!cell)
{
NSArray *nibs =[[NSBundle mainBundle] loadNibNamed:#"YoutubeCell" owner:self options:NULL];
cell = [nibs firstObject];
}
cell.videoTitle.text = [titleArray objectAtIndex:indexPath.row];
cell.videoDescription.text = [descriptionArray objectAtIndex:indexPath.row];
cell.videoThumbnail.image = [thumbArray objectAtIndex:indexPath.row];
cell.videoTitle.textColor = kfbBlue;
cell.videoDescription.textColor = kfbBlue;
cell.videoTitle.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:22.0];
cell.videoDescription.font = [UIFont fontWithName:#"FranklinGothicStd-ExtraCond" size:16.0];
cell.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
KFBYoutubeVideoView *videoView = [[KFBYoutubeVideoView alloc]init];
videoView.videoIDString = [videoIDArray objectAtIndex:indexPath.row];
videoView.videoTitle = [titleArray objectAtIndex:indexPath.row];
videoView.videoDescription = [descriptionArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:videoView animated:YES];
}
else
{
KFBYoutubeVideoView *videoView = [[KFBYoutubeVideoView alloc]initWithNibName:nil bundle:nil];
videoView.videoIDString = [videoIDArray objectAtIndex:indexPath.row];
videoView.videoTitle = [titleArray objectAtIndex:indexPath.row];
videoView.videoDescription = [descriptionArray objectAtIndex:indexPath.row];
NSMutableArray *details = [self.splitViewController.viewControllers mutableCopy];
UINavigationController *detailNav = [[UINavigationController alloc]initWithRootViewController:videoView];
[details replaceObjectAtIndex:1 withObject:detailNav];
KFBAppDelegate *appDelegate = (KFBAppDelegate *)[[UIApplication sharedApplication]delegate];
appDelegate.splitViewController.viewControllers = details;
appDelegate.window.rootViewController = self.splitViewController;
appDelegate.splitViewController.delegate = videoView;
[appDelegate.splitViewController viewWillAppear:YES];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
I figured it out. tableView was being initialized after adding loadingIndicator as a subview.
I want every delete button to be tagged with its associated section's headerLabel.text.
This way, when pressing the delete button runs the deleteButtonPressed method, the deleteFromMatchCenter Parse function will use the section's headerLabel.text value as the parameter. I've tried to do it as below, but this doesn't seem to be recognizing the header title properly.
How can I properly associate each delete button with its respective sections header title, and send that over as the parameter?
MatchCenterViewController.m:
#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>
#interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) UITableView *matchCenter;
#end
#implementation MatchCenterViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
self.matchCenter.frame = CGRectMake(0,50,320,self.view.frame.size.height-100);
_matchCenter.dataSource = self;
_matchCenter.delegate = self;
[self.view addSubview:self.matchCenter];
_matchCenterArray = [[NSArray alloc] init];
}
- (void)viewDidAppear:(BOOL)animated
{
self.matchCenterArray = [[NSArray alloc] init];
[PFCloud callFunctionInBackground:#"MatchCenter"
withParameters:#{
#"test": #"Hi",
}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
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;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 21)];
headerView.backgroundColor = [UIColor lightGrayColor];
_searchTerm = [[[[_matchCenterArray objectAtIndex:section] objectForKey:#"Top 3"] objectAtIndex:3]objectForKey:#"Search Term"];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(8, 0, 250, 21)];
headerLabel.text = [NSString stringWithFormat:#"%#", _searchTerm];
headerLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]];
headerLabel.textColor = [UIColor whiteColor];
headerLabel.backgroundColor = [UIColor lightGrayColor];
[headerView addSubview:headerLabel];
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeCustom];
deleteButton.tag = section;
deleteButton.frame = CGRectMake(300, 2, 17, 17);
[deleteButton setImage:[UIImage imageNamed:#"xbutton.png"] forState:UIControlStateNormal];
[deleteButton addTarget:self action:#selector(deleteButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[headerView addSubview:deleteButton];
return headerView;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 3;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Initialize cell
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
// if no cell could be dequeued create a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
// No cell seperators = clean design
tableView.separatorColor = [UIColor clearColor];
// title of the item
cell.textLabel.text = _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Title"];
cell.textLabel.font = [UIFont boldSystemFontOfSize:14];
// price of the item
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#", _matchCenterArray[indexPath.section][#"Top 3"][indexPath.row][#"Price"]];
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][#"Image URL"]]];
[[cell imageView] setImage:[UIImage imageWithData:imageData]];
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 65;
}
- (void)deleteButtonPressed:(id)sender
{
// Define the sections title
NSString *sectionName = [self titleForHeaderInSection:indexPath.section];
// Run delete function with respective section header as parameter
[PFCloud callFunctionInBackground:#"deleteFromMatchCenter"
withParameters:
#{#"searchTerm": sectionName,}
block:^(NSDictionary *result, NSError *error) {
if (!error) {
NSLog(#"Result: '%#'", result);
[_matchCenter reloadData];
}
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
You haven't linked your titleForHeaderInSection: method, but you're trying to pass indexPath.section when you don't have access to your indexPath.
Try this
UIButton *deleteButton = (UIButton *)sender;
NSString *sectionName = [self titleForHeaderInSection:deleteButton.tag];
or
NSString *sectionName = _searchTerm = [[[[_matchCenterArray objectAtIndex:deleteButton.tag] objectForKey:#"Top 3"] objectAtIndex:3]objectForKey:#"Search Term"];
I am currently using this custom/ expandable tableview code called SKSTableView which can be found at Here
Here's the issue, when I fill the table with over 10 rows, the UI Locks up and the scrolling begins to be extremely laggy. I can't seem to be able to track down the issue, but I am thinking it has something to do with reusing the cell.
Here's some code that will hopefully help.
-SKSTableView hasn't changed
-Below is the implementation in the actual file /Home Screen of app
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Bar *bar = [bars objectAtIndex:indexPath.row];
NSArray *friendsAtBar = (NSArray*)bar.friends;
static NSString *cellIdentifier = #"SKSTableViewCell";
SKSTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell){//If no cell, create a new one
cell = [[SKSTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
UIColor *cellBackgroundColor = [UIColor colorWithWhite:( 30/255.0) alpha:1.0];
UIColor *cellTextColor = [UIColor colorWithWhite:0.80 alpha:1.0];
UIImageView *bottomLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 73, 320, 2)];
bottomLine.backgroundColor = [UIColor colorWithWhite:( 50/255.0) alpha:1.0];
cell.nameLabel.textColor = cellTextColor;
cell.friendsLabel.textColor = cellTextColor;
cell.backgroundColor = cellBackgroundColor;
cell.selectionBanner.backgroundColor = cellBackgroundColor;
[cell addSubview:bottomLine];
[cell.goingButton addTarget:self
action:#selector(goingButtonPressed:)
forControlEvents:UIControlEventTouchUpInside];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.nameLabel.frame = nameStartFrame;
}
if (friendsAtBar != nil && friendsAtBar.count != 0)
cell.isExpandable = YES;
else
cell.isExpandable = NO;
cell.nameLabel.text = bar.name;
//cell.userInteractionEnabled = YES;
if (friendsAtBar.count == 1) // If only 1 friend is going, say friend, if more than 1 friend is going say friends
cell.friendsLabel.text = [NSString stringWithFormat:#"%lu friend going",(unsigned long)friendsAtBar.count];
else if (friendsAtBar.count > 1)
cell.friendsLabel.text = [NSString stringWithFormat:#"%lu friends going",(unsigned long)friendsAtBar.count];
else {
cell.friendsLabel.text = #"";
//cell.nameLabel.frame = CGRectMake(20, 26, 200, 23);
}
//cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.tag = indexPath.row;
[self deselectGoingButton:cell.goingButton];
if ([bar.objectID isEqualToString:[currentUser objectForKey:#"currentBarID"]] && [self under15Hours:[currentUser objectForKey:#"barTimeStamp"]])
{
goingToBarID = bar.objectID; // HERE
//NSLog(#"goingToBarID from cell: %#",goingToBarID);
selectedGoingToButton = cell.goingButton;
[self selectGoingButton:cell.goingButton];
}
cell.goingButton.tag = indexPath.row;
cell.selectionBanner.tag = indexPath.row;
return cell;
}
#pragma mark - TableView - Subrow
- (NSInteger)tableView:(SKSTableView *)tableView numberOfSubRowsAtIndexPath:(NSIndexPath *)indexPath {
if (bars != nil && bars.count != 0) {
Bar *bar = [bars objectAtIndex:indexPath.row];
return bar.friends.count;
}
else
return 0;
} // PARSE IMPACTED
- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubRowAtIndexPath:(NSIndexPath *)indexPath {
//NSMutableDictionary *bar = [bars objectAtIndex:indexPath.row];
Bar *bar = [bars objectAtIndex:indexPath.row];
NSArray *friendsAtBar = (NSArray*)bar.friends;
//UIColor *cellBackgroundColor = [UIColor colorWithWhite:( 20/255.0) alpha:1.0];
//UIColor *cellTextColor = [UIColor colorWithWhite:0.85 alpha:1.0];
UIImageView *bottomLine = [[UIImageView alloc] initWithFrame:CGRectMake(0, 73, 320, 2)];
bottomLine.backgroundColor = [UIColor colorWithWhite:( 50/255.0) alpha:1.0];
static NSString *cellIdentifier = #"FriendsGoingCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UIView *cellView;
UILabel *nameLabel;
UILabel *usernameLabel;
UIButton *callButton;
UIButton *textButton;
if (!cell){//If no cell, make a new one
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cellView = [self createSubRowView];
nameLabel = [cellView.subviews objectAtIndex:1];
usernameLabel = [cellView.subviews objectAtIndex:2];
usernameLabel.textColor = [UIColor colorWithWhite:0.7 alpha:1.0];
callButton = [cellView.subviews objectAtIndex:3];
textButton = [cellView.subviews objectAtIndex:4];
[cell addSubview:cellView];
[cell addSubview:bottomLine];
}
//cell.backgroundColor = cellBackgroundColor;
cell.tag = 2;
//PFUser *user = [friendsAtBar objectAtIndex:indexPath.subRow-1];
Friend *user = [friendsAtBar objectAtIndex:indexPath.subRow-1];
//UILabel *nameLabel = [cellView.subviews objectAtIndex:1];
//nameLabel.text = [[friendsAtBar objectAtIndex:indexPath.subRow-1] objectForKey:#"username"];
nameLabel.text = [NSString stringWithFormat:#"%#",user.compositeName];
//nameLabel.textColor = cellTextColor;
// UILabel *usernameLabel = [cellView.subviews objectAtIndex:2];
usernameLabel.text = user.userName;
//UIButton *callButton = [cellView.subviews objectAtIndex:3];
callButton.tag = indexPath.subRow-1;
//UIButton *textButton = [cellView.subviews objectAtIndex:4];
textButton.tag = indexPath.subRow-1;
return cell;
}
[self createSubView]
- (UIView *)createSubRowView {
UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, [rowHeight floatValue])];
UIColor *fontColor = [UIColor colorWithWhite:0.85 alpha:1.0];
UIView* bgview = [[UIView alloc] initWithFrame:cellView.frame];
bgview.backgroundColor = [UIColor colorWithWhite:0.15 alpha:1.0];
[cellView addSubview:bgview];
UILabel *nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 16, 180, 23)];
nameLabel.textColor = fontColor;
nameLabel.font = [UIFont boldSystemFontOfSize:17];
[cellView addSubview:nameLabel];
UILabel *goingTimeStampLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 41, 180, 16)];
goingTimeStampLabel.textColor = fontColor;
goingTimeStampLabel.font = [UIFont systemFontOfSize:13];
[cellView addSubview:goingTimeStampLabel];
CGFloat x = 200;
CGFloat width = 55;
CGFloat height = [rowHeight floatValue];
CGFloat y = ([rowHeight floatValue] - height)/2;
UIButton *callButton = [[UIButton alloc] initWithFrame:CGRectMake(x, y, width, height)];
UIImage *callIcon = [UIImage imageNamed:#"call.png"];
[callButton setImage:callIcon forState:UIControlStateNormal];
[callButton addTarget:self
action:#selector(clickedCallButton:)
forControlEvents:UIControlEventTouchUpInside];
[cellView addSubview:callButton];
UIButton *textButton = [[UIButton alloc] initWithFrame:CGRectMake(x+width, y, width, height)];
UIImage *textIcon = [UIImage imageNamed:#"text.png"];
[textButton setImage:textIcon forState:UIControlStateNormal];
[textButton addTarget:self
action:#selector(clickedTextButton:)
forControlEvents:UIControlEventTouchUpInside];
[cellView addSubview:textButton];
return cellView;
}
SKSTableView.m
#import "SKSTableView.h"
#import "SKSTableViewCell.h"
#import "SKSTableViewCellIndicator.h"
#import <objc/runtime.h>
#pragma mark - NSArray (SKSTableView)
#interface NSMutableArray (SKSTableView)
- (void)initiateObjectsForCapacity:(NSInteger)numItems;
#end
#implementation NSMutableArray (SKSTableView)
- (void)initiateObjectsForCapacity:(NSInteger)numItems
{
for (NSInteger index = [self count]; index < numItems; index++) {
NSMutableArray *array = [NSMutableArray array];
[self addObject:array];
}
}
#end
#pragma mark - SKSTableView
#interface SKSTableView () <UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, strong) NSMutableArray *expandedIndexPaths;
#property (nonatomic, strong) NSMutableDictionary *expandableCells;
#end
#implementation SKSTableView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_shouldExpandOnlyOneCell = NO;
}
return self;
}
- (void)setSKSTableViewDelegate:(id<SKSTableViewDelegate>)SKSTableViewDelegate
{
self.dataSource = self;
self.delegate = self;
[self setSeparatorColor:[UIColor colorWithRed:236.0/255.0 green:236.0/255.0 blue:236.0/255.0 alpha:1.0]];
if (SKSTableViewDelegate)
_SKSTableViewDelegate = SKSTableViewDelegate;
}
- (void)setSeparatorColor:(UIColor *)separatorColor
{
[super setSeparatorColor:separatorColor];
[SKSTableViewCellIndicator setIndicatorColor:separatorColor];
}
- (NSMutableArray *)expandedIndexPaths
{
if (!_expandedIndexPaths)
_expandedIndexPaths = [NSMutableArray array];
return _expandedIndexPaths;
}
- (NSMutableDictionary *)expandableCells
{
if (!_expandableCells)
_expandableCells = [NSMutableDictionary dictionary];
return _expandableCells;
}
#pragma mark - UITableViewDataSource
#pragma mark - Required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_SKSTableViewDelegate tableView:tableView numberOfRowsInSection:section] + [[[self expandedIndexPaths] objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (![self.expandedIndexPaths[indexPath.section] containsObject:indexPath]) {
NSIndexPath *tempIndexPath = [self correspondingIndexPathForRowAtIndexPath:indexPath];
SKSTableViewCell *cell = (SKSTableViewCell *)[_SKSTableViewDelegate tableView:tableView cellForRowAtIndexPath:tempIndexPath];
if ([[self.expandableCells allKeys] containsObject:tempIndexPath])
[cell setIsExpanded:[[self.expandableCells objectForKey:tempIndexPath] boolValue]];
[cell setSeparatorInset:UIEdgeInsetsZero];
if (cell.isExpandable) {
[self.expandableCells setObject:[NSNumber numberWithBool:[cell isExpanded]]
forKey:indexPath];
UIButton *expandableButton = (UIButton *)cell.accessoryView;
[expandableButton addTarget:tableView
action:#selector(expandableButtonTouched:event:)
forControlEvents:UIControlEventTouchUpInside];
if (cell.isExpanded) {
cell.accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
if ([cell containsIndicatorView])
[cell removeIndicatorView];
}
} else {
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cell removeIndicatorView];
cell.accessoryView = nil;
}
return cell;
} else {
NSIndexPath *indexPathForSubrow = [self correspondingIndexPathForSubRowAtIndexPath:indexPath];
UITableViewCell *cell = [_SKSTableViewDelegate tableView:(SKSTableView *)tableView cellForSubRowAtIndexPath:indexPathForSubrow];
cell.backgroundView = nil;
cell.backgroundColor = [self separatorColor];
cell.indentationLevel = 2;
return cell;
}
}
#pragma mark - Optional
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ([_SKSTableViewDelegate respondsToSelector:#selector(numberOfSectionsInTableView:)]) {
NSInteger numberOfSections = [_SKSTableViewDelegate numberOfSectionsInTableView:tableView];
if ([self.expandedIndexPaths count] != numberOfSections)
[self.expandedIndexPaths initiateObjectsForCapacity:numberOfSections];
return numberOfSections;
}
return 1;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:titleForHeaderInSection:)])
return [_SKSTableViewDelegate tableView:tableView titleForHeaderInSection:section];
return nil;
}
#pragma mark - UITableViewDelegate
#pragma mark - Optional
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:didSelectRowAtIndexPath:)])
[_SKSTableViewDelegate tableView:tableView didSelectRowAtIndexPath:indexPath];
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:didDeselectRowAtIndexPath:)])
[_SKSTableViewDelegate tableView:tableView didDeselectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
SKSTableViewCell *cell = (SKSTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if ([cell isKindOfClass:[SKSTableViewCell class]] && cell.isExpandable) {
cell.isExpanded = !cell.isExpanded;
NSIndexPath *_indexPath = indexPath;
if (cell.isExpanded && self.shouldExpandOnlyOneCell) {
_indexPath = [self correspondingIndexPathForRowAtIndexPath:indexPath];
[self collapseCurrentlyExpandedIndexPaths];
}
NSInteger numberOfSubRows = [self numberOfSubRowsAtIndexPath:_indexPath];
NSMutableArray *indexPaths = [NSMutableArray array];
NSInteger row = _indexPath.row;
NSInteger section = _indexPath.section;
for (NSInteger index = 1; index <= numberOfSubRows; index++) {
NSIndexPath *expIndexPath = [NSIndexPath indexPathForRow:row+index inSection:section];
[indexPaths addObject:expIndexPath];
}
if (cell.isExpanded) {
[self setIsExpanded:YES forCellAtIndexPath:_indexPath];
[self insertExpandedIndexPaths:indexPaths forSection:_indexPath.section];
} else {
[self setIsExpanded:NO forCellAtIndexPath:_indexPath];
[self removeExpandedIndexPaths:indexPaths forSection:_indexPath.section];
}
[self accessoryViewAnimationForCell:cell];
}
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:accessoryButtonTappedForRowWithIndexPath:)])
[_SKSTableViewDelegate tableView:tableView accessoryButtonTappedForRowWithIndexPath:indexPath];
[self.delegate tableView:tableView didSelectRowAtIndexPath:indexPath];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
CGFloat height = 0;
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:heightForHeaderInSection:)])
height = [_SKSTableViewDelegate tableView:tableView heightForHeaderInSection:section];
return height;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view = [[UIView alloc] init];
if ([_SKSTableViewDelegate respondsToSelector:#selector(tableView:viewForHeaderInSection:)])
view = [_SKSTableViewDelegate tableView:tableView viewForHeaderInSection:section];
return view;
}
#pragma mark - SKSTableViewUtils
- (IBAction)expandableButtonTouched:(id)sender event:(id)event
{
NSSet *touches = [event allTouches];
UITouch *touch = [touches anyObject];
CGPoint currentTouchPosition = [touch locationInView:self];
NSIndexPath *indexPath = [self indexPathForRowAtPoint:currentTouchPosition];
if (indexPath)
[self tableView:self accessoryButtonTappedForRowWithIndexPath:indexPath];
}
- (NSInteger)numberOfSubRowsAtIndexPath:(NSIndexPath *)indexPath
{
return [_SKSTableViewDelegate tableView:self numberOfSubRowsAtIndexPath:[self correspondingIndexPathForRowAtIndexPath:indexPath]];
}
- (NSIndexPath *)correspondingIndexPathForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger index = 0;
NSInteger row = 0;
while (index < indexPath.row) {
NSIndexPath *tempIndexPath = [self correspondingIndexPathForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:indexPath.section]];
BOOL isExpanded = [[self.expandableCells allKeys] containsObject:tempIndexPath] ? [[self.expandableCells objectForKey:tempIndexPath] boolValue] : NO;
if (isExpanded) {
NSInteger numberOfExpandedRows = [_SKSTableViewDelegate tableView:self numberOfSubRowsAtIndexPath:tempIndexPath];
index += (numberOfExpandedRows + 1);
} else
index++;
row++;
}
return [NSIndexPath indexPathForRow:row inSection:indexPath.section];
}
- (NSIndexPath *)correspondingIndexPathForSubRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger index = 0;
NSInteger row = 0;
NSInteger subrow = 0;
while (1) {
NSIndexPath *tempIndexPath = [self correspondingIndexPathForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:indexPath.section]];
BOOL isExpanded = [[self.expandableCells allKeys] containsObject:tempIndexPath] ? [[self.expandableCells objectForKey:tempIndexPath] boolValue] : NO;
if (isExpanded) {
NSInteger numberOfExpandedRows = [_SKSTableViewDelegate tableView:self numberOfSubRowsAtIndexPath:tempIndexPath];
if ((indexPath.row - index) <= numberOfExpandedRows) {
subrow = indexPath.row - index;
break;
}
index += (numberOfExpandedRows + 1);
} else
index++;
row++;
}
return [NSIndexPath indexPathForSubRow:subrow inRow:row inSection:indexPath.section];
}
- (void)setIsExpanded:(BOOL)isExpanded forCellAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *correspondingIndexPath = [self correspondingIndexPathForRowAtIndexPath:indexPath];
[self.expandableCells setObject:[NSNumber numberWithBool:isExpanded] forKey:correspondingIndexPath];
}
- (void)insertExpandedIndexPaths:(NSArray *)indexPaths forSection:(NSInteger)section
{
NSIndexPath *firstIndexPathToExpand = indexPaths[0];
NSIndexPath *firstIndexPathExpanded = nil;
if ([self.expandedIndexPaths[section] count] > 0) firstIndexPathExpanded = self.expandedIndexPaths[section][0];
__block NSMutableArray *array = [NSMutableArray array];
if (firstIndexPathExpanded && firstIndexPathToExpand.section == firstIndexPathExpanded.section && firstIndexPathToExpand.row < firstIndexPathExpanded.row) {
[self.expandedIndexPaths[section] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSIndexPath *updated = [NSIndexPath indexPathForRow:([obj row] + [indexPaths count])
inSection:[obj section]];
[array addObject:updated];
}];
[array addObjectsFromArray:indexPaths];
self.expandedIndexPaths[section] = array;
} else {
[self.expandedIndexPaths[section] addObjectsFromArray:indexPaths];
}
[self sortExpandedIndexPathsForSection:section];
// Reload TableView
[self insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
}
- (void)removeExpandedIndexPaths:(NSArray *)indexPaths forSection:(NSInteger)section
{
NSUInteger index = [self.expandedIndexPaths[section] indexOfObject:indexPaths[0]];
[self.expandedIndexPaths[section] removeObjectsInArray:indexPaths];
if (index == 0) {
__block NSMutableArray *array = [NSMutableArray array];
[self.expandedIndexPaths[section] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSIndexPath *updated = [NSIndexPath indexPathForRow:([obj row] - [indexPaths count])
inSection:[obj section]];
[array addObject:updated];
}];
self.expandedIndexPaths[section] = array;
}
[self sortExpandedIndexPathsForSection:section];
// Reload Tableview
[self deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
}
- (void)collapseCurrentlyExpandedIndexPaths
{
NSArray *expandedCells = [self.expandableCells allKeysForObject:[NSNumber numberWithBool:YES]];
if (expandedCells.count > 0) {
NSIndexPath *indexPath = [expandedCells firstObject];
[self.expandableCells setObject:[NSNumber numberWithBool:NO] forKey:indexPath];
[self removeExpandedIndexPaths:[self.expandedIndexPaths[indexPath.section] copy] forSection:indexPath.section];
SKSTableViewCell *cell = (SKSTableViewCell *)[self cellForRowAtIndexPath:indexPath];
cell.isExpanded = NO;
[self accessoryViewAnimationForCell:cell];
}
}
- (void)sortExpandedIndexPathsForSection:(NSInteger)section
{
[self.expandedIndexPaths[section] sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
if ([obj1 section] < [obj2 section])
return (NSComparisonResult)NSOrderedAscending;
else if ([obj1 section] > [obj2 section])
return (NSComparisonResult)NSOrderedDescending;
else {
if ([obj1 row] < [obj2 row])
return (NSComparisonResult)NSOrderedAscending;
else
return (NSComparisonResult)NSOrderedDescending;
}
}];
}
- (void)accessoryViewAnimationForCell:(SKSTableViewCell *)cell
{
__block SKSTableViewCell *_cell = cell;
[UIView animateWithDuration:0.2 animations:^{
if (_cell.isExpanded) {
_cell.accessoryView.transform = CGAffineTransformMakeRotation(M_PI);
} else {
_cell.accessoryView.transform = CGAffineTransformMakeRotation(0);
}
} completion:^(BOOL finished) {
if (!_cell.isExpanded)
[_cell removeIndicatorView];
}];
}
#end
#pragma mark - NSIndexPath (SKSTableView)
static void *SubRowObjectKey;
#implementation NSIndexPath (SKSTableView)
#dynamic subRow;
- (NSInteger)subRow
{
id subRowObj = objc_getAssociatedObject(self, SubRowObjectKey);
return [subRowObj integerValue];
}
- (void)setSubRow:(NSInteger)subRow
{
id subRowObj = [NSNumber numberWithInteger:subRow];
objc_setAssociatedObject(self, SubRowObjectKey, subRowObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (NSIndexPath *)indexPathForSubRow:(NSInteger)subrow inRow:(NSInteger)row inSection:(NSInteger)section
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
indexPath.subRow = subrow;
return indexPath;
}
#end