I have a UITableview and I populate the rows with data from an api.
I have made code to update the label of the item in the cell row if more than on of the same item is added to the tableview. If a new item is added it populates a new cell row with the information.
I am trying now to use the UITableview editing method to delete rows from the UITableview.
I have no problem with deleting rows but My problem is that how can I delete the quantity if the item in the cell row is more than 1 and if the quantuty is only one delete the cell row.
I am getting a strange bug when trying to do this.
My code minuses to many times, please see my code and screenshots.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(#"Order ID: %ld", (long)self.orderId);
if ([self.prevVC isKindOfClass:[MyOrdersViewController class]]) {
NSLog(#"from my orders view");
[self.tableView reloadData];
}else {
NSLog(#"from my deli item view %#", self.deli.deliId);
NSLog(#"from my menu item view %ld", (long)self.menuItem.menuItemId);
NSLog(#"menu item array %#", self.menuItem);
self.viewOrderSummaryDictionary = [[NSMutableDictionary alloc] init];
[self.viewOrderSummaryDictionary setObject: [NSNumber numberWithInteger: self.menuItem.menuItemId] forKey: #"id"];
[self.viewOrderSummaryDictionary setObject: self.menuItem.menuItemDescription forKey: #"description"];
[self.viewOrderSummaryDictionary setObject: self.menuItem.menuItemImageURL forKey: #"imageUrlString"];
[self.viewOrderSummaryDictionary setObject: self.menuItem.menuItemPrice forKey: #"price"];
[self.viewOrderSummaryDictionary setObject: self.menuItem.menuItemCurrency forKey: #"currency"];
NSArray *arr = [self.newestViewOrderSummaryArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"id == %#", [NSNumber numberWithInteger: self.menuItem.menuItemId]]];
NSLog(#"arr arr arr %#", arr);
if (arr && arr.count == 1) {
NSMutableDictionary* foundMenuItem = (NSMutableDictionary*) [arr objectAtIndex: 0];
self.quantity = [[foundMenuItem objectForKey: #"quantity"] intValue];
self.quantity++;
[foundMenuItem setObject: [NSString stringWithFormat: #"%d", self.quantity] forKey: #"quantity"];
[self.newestViewOrderSummaryArray removeObject: foundMenuItem];
self.viewOrderSummaryArray = [[NSMutableArray alloc] initWithArray: self.newestViewOrderSummaryArray];
[self.viewOrderSummaryArray addObject: foundMenuItem];
}
else {
[self.viewOrderSummaryDictionary setObject: #"1" forKey: #"quantity"];
[self.viewOrderSummaryArray addObject: self.viewOrderSummaryDictionary];
[self.viewOrderSummaryArray addObjectsFromArray: self.newestViewOrderSummaryArray];
}
[self.tableView reloadData];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self showBackButton];
self.navBarBackLabel = [[UILabel alloc] initWithFrame: CGRectMake(65, 5, 200, 30)];
self.title = NSLocalizedString(#"View Order Summary", nil);
self.navBarBackLabel.textColor = [UIColor appRedColor];
self.navBarBackLabel.font = [UIFont fontWithName:#"SegoeWP" size:15];
[self.navigationController.navigationBar addSubview:self.navBarBackLabel];
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, self.tableView.bounds.size.width, 0.01f)];
self.tableView.contentInset = UIEdgeInsetsZero;
self.viewOrderSummaryArray = [[NSMutableArray alloc] init];
[self setupTableViewHeader];
}
#pragma mark - UITableViewDataSource
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30.0f;
}
- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGRect frame = tableView.frame;
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
self.headerView.backgroundColor = [UIColor appOrderScreenHeaderBackgroundColor];
self.headerViewWhite = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, 30.0f)];
self.headerViewWhite.backgroundColor = [UIColor appYellowColor];
[self.headerViewWhite addSubview:self.deliNameLabel];
[self.headerView addSubview:self.headerViewWhite];
return self.headerView;
}
- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
return nil;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 115;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.viewOrderSummaryArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ViewOrderSummaryCell *cell = (ViewOrderSummaryCell *)[tableView dequeueReusableCellWithIdentifier:#"ViewOrderSummaryCell"];
cell.separatorInset = UIEdgeInsetsZero;
self.tableView.separatorInset = UIEdgeInsetsZero;
self.edgesForExtendedLayout = UIRectEdgeNone;
//self.tableView.layoutMargins = UIEdgeInsetsZero;
//cell.layoutMargins = UIEdgeInsetsZero;
NSDictionary* currentItem = [self.viewOrderSummaryArray objectAtIndex: indexPath.row];
cell.productNameLabel.text = [currentItem objectForKey: #"description"];
cell.productPriceLabel.text = [NSString stringWithFormat: #"%#%# x %#",[currentItem objectForKey: #"currency"],[currentItem objectForKey: #"price"], [currentItem objectForKey: #"quantity"]]; // TODO: Must implement this later
[cell.productImageView sd_setImageWithURL:[currentItem objectForKey: #"imageUrlString"] placeholderImage:[UIImage imageNamed:#"appPlaceholderImage"]];
CALayer * l = [cell.productImageView layer];
[l setMasksToBounds:YES];
[l setCornerRadius:10.0];
float sumq = 0;
NSArray *array = [self.viewOrderSummaryArray valueForKey:#"price"];
for (NSNumber *num in array)
{
sumq += [num floatValue];
}
float currentPrice = [[currentItem objectForKey: #"price"] floatValue];
float quantity = [[currentItem objectForKey: #"quantity"] intValue];
sumPrice += (currentPrice * quantity);
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
// Return YES if you want the specified item to be editable.
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
//add code here for when you hit delete
NSLog(#"Selected row of section >> %ld",(long)indexPath.row);
NSLog(#"Selected row is %#", [self.viewOrderSummaryArray objectAtIndex:[indexPath row]] );
NSMutableDictionary* currentItem = [self.viewOrderSummaryArray objectAtIndex: indexPath.row];
if ([[currentItem objectForKey: #"quantity"] isEqualToString:#"1"]) {
[self.viewOrderSummaryArray removeObject:[self.viewOrderSummaryArray objectAtIndex:[indexPath row]]];
NSLog(#"Quantity label");
}
else {
self.quantity--;
[currentItem setObject: [NSString stringWithFormat: #"%d", self.quantity] forKey: #"quantity"];
[self.newestViewOrderSummaryArray removeObject: currentItem];
self.viewOrderSummaryArray = [[NSMutableArray alloc] initWithArray: self.newestViewOrderSummaryArray];
[self.viewOrderSummaryArray addObject: currentItem];
NSLog(#"Many label");
}
[self.tableView reloadData];
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
Related
I have a UITableView with search bar function. However, when i search for any keyword (Please refer to screenshot as attached), search result will be repeated and return more than 1 result.
My expected result should be search result will reflect accordingly based on keyword entered.
Your help is much appreciated. Please help, thank you.
#interface Friend_ViewController ()
#end
#implementation Friend_ViewController{
NSMutableArray *tableData;
UITableView *tableView;
BOOL isFiltered;
NSMutableArray *stateNamesArray;
NSArray *searchResult;
}
- (void)viewDidLoad {
[super viewDidLoad];
isFiltered =false;
UIImage* image3 = [UIImage imageNamed:#"Add_Friend"];
CGRect frameimg = CGRectMake(0,0, image3.size.width -10, image3.size.height);
UIButton *btn_add_friends = [[UIButton alloc] initWithFrame:frameimg];
[btn_add_friends setBackgroundImage:image3 forState:UIControlStateNormal];
[btn_add_friends addTarget:self action:#selector(addFriendButtonDidPressed:)
forControlEvents:UIControlEventTouchUpInside];
[btn_add_friends setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *btn_add_friends_item =[[UIBarButtonItem alloc] initWithCustomView:btn_add_friends];
self.navigationItem.rightBarButtonItem =btn_add_friends_item;
stateNamesArray = #[#"Alabama", #"Alaska", #"Arizona", #"Arkansas", #"California", #"Colorado", #"Connecticut", #"Delaware", #"Florida", #"Georgia", #"Hawaii", #"Idaho", #"Illinois", #"Indiana", #"Iowa", #"Kansas", #"Kentucky", #"Louisiana", #"Maine", #"Maryland", #"Massachusetts", #"Michigan",
#"Minnesota", #"Mississippi", #"Missouri", #"Montana", #"Nebraska", #"Nevada", #"New Hampshire",
#"New Jersey", #"New Mexico", #"New York", #"North Carolina", #"North Dakota", #"Ohio",
#"Oklahoma", #"Oregon", #"Pennsylvania", #"Rhode Island", #"South Carolina", #"South Dakota",
#"Tennessee", #"Texas", #"Utah", #"Vermont", #"Virginia", #"Washington", #"West Virginia",
#"Wisconsin", #"Wyoming"];
NSInteger indexLabelLettersCount = [[UILocalizedIndexedCollation currentCollation] sectionTitles].count;
NSMutableArray *allSections = [[NSMutableArray alloc] initWithCapacity:indexLabelLettersCount];
for (int i = 0; i < indexLabelLettersCount; i++) {
[allSections addObject:[NSMutableArray array]];
}
for(NSString *theState in stateNamesArray){
NSInteger sectionNumber = [[UILocalizedIndexedCollation currentCollation] sectionForObject:theState collationStringSelector:#selector(lowercaseString)];
[allSections[sectionNumber] addObject:theState];
}
NSMutableArray *sortedArray = [[NSMutableArray alloc] init];
self.activeSectionIndices = [NSMutableDictionary dictionary];
self.activeSectionTitles = [NSMutableArray array];
for (int i = 0; i < indexLabelLettersCount; i++) {
NSArray *statesForSection = allSections[i];
NSString *indexTitleForSection = [[UILocalizedIndexedCollation currentCollation] sectionTitles][i];
if (statesForSection.count > 0) {
[self.activeSectionTitles addObject:indexTitleForSection];
NSArray *tmpSectionStates = allSections[i];
tmpSectionStates = [tmpSectionStates sortedArrayUsingSelector:#selector(compare:)];
[sortedArray addObject:tmpSectionStates];
}
NSNumber *index = [NSNumber numberWithInt:MAX(self.activeSectionTitles.count - 1, 0)];
self.activeSectionIndices[indexTitleForSection] = index;
}
tableData = sortedArray;
self.tableView.sectionHeaderHeight = 25;
self.navigationController.navigationBar.translucent = NO;
tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
self.navigationController.navigationBar.translucent = NO;
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.searchResultsUpdater = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.hidesNavigationBarDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.definesPresentationContext = YES;
[self.searchController.searchBar sizeToFit];
[self.view addSubview:self.searchBar];
searchResult = [NSMutableArray arrayWithCapacity:[stateNamesArray count]];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(nonnull NSString *)searchText
{
if(searchText.length == 0)
{
isFiltered = NO;
}
else
{
isFiltered = YES;
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF CONTAINS %#",
searchText];
searchResult = [stateNamesArray filteredArrayUsingPredicate:resultPredicate];
}
[self.tableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{
return tableData.count;
}
- (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(isFiltered){
return searchResult.count;
}
else
{
NSArray *arr = tableData[section];
return arr.count;
}
}
- (UITableViewCell *) tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
if(isFiltered){
cell.textLabel.text = [searchResult objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:#"Home"];
}
else{
NSArray *arr = tableData[indexPath.section];//get the current section array
cell.textLabel.text = arr[indexPath.row];//get the row for the current section
cell.imageView.image = [UIImage imageNamed:#"Home"];
}
return cell;
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(isFiltered)
{
return nil;
}
return self.activeSectionTitles[section];
}
#end
</pre></code>
You are always returning tableData.count in numberOfSectionsInTableView so every row is repeated tableData.count times.
- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{
return isFiltered ? 1 : tableData.count;
}
- (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray sectionArray = (NSArray *)tableData[section];
return isFiltered ? 1 : sectionArray.count;
}
You are always returning tableData.count in numberOfSectionsInTableView so
You need to return proper section count.
- (NSInteger)numberOfSectionsInTableView: (UITableView *) tableView{
return isFiltered ? 1 : tableData.count;
}
I hope this will help you. :)
update this code
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(nonnull NSString *)searchText
{
//Add below line of code
[searchText removeAllObjects];
if(searchText.length == 0)
{
isFiltered = NO;
}
else
{
isFiltered = YES;
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF CONTAINS %#",
searchText];
searchResult = [stateNamesArray filteredArrayUsingPredicate:resultPredicate];
}
[self.tableView reloadData];
}
This method calls on every character, so it search and result store in array. You are not removing object from array so it keep adding object in it. That's why you are getting this result.
[searchText removeAllObjects];
This line of code remove all objects from array.
I am a newbie on iOS Development and I am sorting out how am I going to have a table view with a checkmark on the settings bundle like this:
Is there any way to do it? Or is this just only available for specific iOS approved apps?
Looking forward for an answer. Thanks.
You can achieve this through Multi Value Element. When the user taps a preference containing a multi-value element, the Settings application displays a new page with the possible values to choose from. Google it for the tutorials if needed (Multivalue option for the settings bundle).
Here are the details : PSMultiValueSpecifier
If I am guessing right and you want to know how to display settings outside your app and in the iOS Settings, then check out this tutorial. It should get you started.
Taken out of the link below:
I have been searching around and couldn't find a boilerplate solution so created my own code for doing this. It supports the setting types Title, Group, Text Field, Multi Value and Toggle Switch.
It does NOT SUPPORT Slider.
This solution does support portrait AND landscape mode and can also handle changing over device orientations.
First off all I'm assuming that you are using the following code to read out your default values from the Settings.bundle.
- (void) registerDefaultsFromSettingsBundle
{
NSLog(#"Registering default values from Settings.bundle");
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
[defs synchronize];
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: #"Settings" ofType: #"bundle"];
if(!settingsBundle)
{
NSLog(#"Could not find Settings.bundle");
return;
}
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: #"Root.plist"]];
NSArray *preferences = [settings objectForKey: #"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]];
for (NSDictionary *prefSpecification in preferences)
{
NSString *key = [prefSpecification objectForKey:#"Key"];
if (key)
{
// check if value readable in userDefaults
id currentObject = [defs objectForKey: key];
if (currentObject == nil)
{
// not readable: set value from Settings.bundle
id objectToSet = [prefSpecification objectForKey: #"DefaultValue"];
[defaultsToRegister setObject: objectToSet forKey: key];
NSLog(#"Setting object %# for key %#", objectToSet, key);
}
else
{
// already readable: don't touch
NSLog(#"Key %# is readable (value: %#), nothing written to defaults.", key, currentObject);
}
}
}
[defs registerDefaults: defaultsToRegister];
[defs synchronize];
}
Okay now you'll need 2 classes. SettingsTableViewController and MultiValueTableViewController.
SettingsTableViewController.h
//
// SettingsTableViewController.h
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import <UIKit/UIKit.h>
#import "MultiValueTableViewController.h"
#interface SettingsTableViewController : UITableViewController <MultiValueDelegate> {
NSMutableArray *labelViews;
NSMutableArray *textViews;
NSMutableArray *settingsKeys;
NSMutableArray *settingsTableSections;
NSMutableArray *settingsTableData;
}
#end
SettingsTableViewController.m
//
// SettingsTableViewController.m
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
////
#import "SettingsTableViewController.h"
#define labelCGRectX 25
#define labelCGRectY 25
#define labelCGRectWidth 140
#define labelCGRectHeight 21
#define typeGroup #"PSGroupSpecifier"
#define typeTitle #"PSTitleValueSpecifier"
#define typeToggleSwitch #"PSToggleSwitchSpecifier"
#define typeMultiValue #"PSMultiValueSpecifier"
#define typeTextField #"PSTextFieldSpecifier"
#interface SettingsTableViewController ()
#end
#implementation SettingsTableViewController
- (id)initWithStyle: (UITableViewStyle)style
{
self = [super initWithStyle: style];
if (self) {
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Track rotation changes
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceOrientationDidChange) name: UIDeviceOrientationDidChangeNotification object: nil];
// Avoid tab bar to overlap tableview
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
// Custom initialization
labelViews = [NSMutableArray arrayWithObjects: nil];
textViews = [NSMutableArray arrayWithObjects: nil];
settingsTableSections = [NSMutableArray arrayWithObjects: nil];
settingsTableData = [NSMutableArray arrayWithObjects: nil];
settingsKeys = [NSMutableArray arrayWithObjects: nil];
NSLog(#"Created arrays");
NSString *settingsBundle = [[NSBundle mainBundle] pathForResource: #"Settings" ofType: #"bundle"];
if(!settingsBundle) {
NSLog(#"Could not find Settings.bundle");
} else {
NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent: #"Root.plist"]];
NSArray *preferences = [settings objectForKey: #"PreferenceSpecifiers"];
NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity: [preferences count]];
for (NSDictionary *prefSpecification in preferences) {
NSLog(#"%#", prefSpecification);
NSString *title = [prefSpecification objectForKey: #"Title"];
NSString *type = [prefSpecification objectForKey: #"Type"];
if([type isEqualToString: typeGroup]) {
// Create new section
[settingsTableSections addObject: title];
NSMutableArray *newSection = [NSMutableArray arrayWithObjects: nil];
[settingsTableData addObject: newSection];
} else {
// Add specification to last section
[[settingsTableData objectAtIndex: ([settingsTableData count] - 1)] addObject:prefSpecification];
}
}
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger) numberOfSectionsInTableView: (UITableView *) tableView
{
// Return the number of sections.
return [settingsTableSections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[settingsTableData objectAtIndex: section] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [settingsTableSections objectAtIndex: section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Get the dictionary item
NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
NSString *title = [prefSpecification objectForKey: #"Title"];
NSString *key = [prefSpecification objectForKey: #"Key"];
NSString *type = [prefSpecification objectForKey: #"Type"];
// Define cell
UITableViewCell *cell;
// Keep tag of keys
[settingsKeys addObject: key];
int tag = [settingsKeys count] - 1;
if([type isEqualToString: typeTitle]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Set title
cell.textLabel.text = title;
// Add label
UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake(labelCGRectX, labelCGRectY, labelCGRectWidth, labelCGRectHeight)];
labelView.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];
labelView.textAlignment = NSTextAlignmentRight;
labelView.textColor = [UIColor grayColor];
cell.accessoryView = labelView;
}
if([type isEqualToString: typeToggleSwitch]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Set title
cell.textLabel.text = title;
// Add switch
UISwitch *switchView = [[UISwitch alloc] initWithFrame: CGRectZero];
cell.accessoryView = switchView;
switchView.tag = tag;
[switchView setOn: [[[NSUserDefaults standardUserDefaults] objectForKey: key] boolValue] animated: NO];
// Connect action to switch
[switchView addTarget: self action: #selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
}
if([type isEqualToString: typeTextField]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
int frameSize = self.view.frame.size.width;
UITextField *textField = [[UITextField alloc] initWithFrame: CGRectMake(15, 10, frameSize,labelCGRectHeight)];
textField.tag = tag;
textField.text = [[NSUserDefaults standardUserDefaults] objectForKey: key];
[textField addTarget: self
action: #selector(textFieldChanged:)
forControlEvents: UIControlEventEditingChanged];
[cell.contentView addSubview: textField];
// Tract text field
[textViews addObject: textField];
}
if([type isEqualToString: typeMultiValue]) {
// Create cell
cell = [tableView dequeueReusableCellWithIdentifier: #"MultiValueCell" forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// Get value
int value = [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSArray *titles = [prefSpecification objectForKey: #"Titles"];
NSString *multiValue = #"Unknown";
int index = [values indexOfObject: [NSString stringWithFormat: #"%d", value]];
if(index >= 0 && index < [values count]) {
multiValue = [titles objectAtIndex: index];
}
// Set title
cell.textLabel.text = title;
int frameSize = self.view.frame.size.width;
// Add label
UILabel *labelView = [[UILabel alloc] initWithFrame: CGRectMake((frameSize - labelCGRectWidth - 30), 12, labelCGRectWidth, labelCGRectHeight)];
labelView.textAlignment = NSTextAlignmentRight;
labelView.text = multiValue;
labelView.textColor = [UIColor grayColor];
[cell addSubview: labelView];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Track label
[labelViews addObject: labelView];
}
return cell;
}
- (void) switchChanged: (id) sender {
UISwitch* switchControl = sender;
NSString *key = [settingsKeys objectAtIndex: switchControl.tag];
NSNumber *numberValue = [NSNumber numberWithBool: switchControl.on];
[[NSUserDefaults standardUserDefaults] setObject: numberValue forKey: key];
}
- (void) textFieldChanged: (id) sender {
UITextField* textControl = sender;
NSString *key = [settingsKeys objectAtIndex: textControl.tag];
NSString *stringValue = textControl.text;
[[NSUserDefaults standardUserDefaults] setObject: stringValue forKey: key];
}
- (void) selectedMultiValue {
[self reloadTable];
}
- (void) deviceOrientationDidChange {
[self reloadTable];
}
- (void)prepareForSegue: (UIStoryboardSegue *) segue sender: (id) sender
{
if ([[segue identifier] isEqualToString: #"changeMultiValue"])
{
MultiValueTableViewController *multiValueViewController =
[segue destinationViewController];
NSIndexPath *indexPath = [self.tableView
indexPathForSelectedRow];
// Get the dictionary item
NSDictionary *prefSpecification = [[settingsTableData objectAtIndex: indexPath.section] objectAtIndex: indexPath.row];
multiValueViewController.prefSpecification = prefSpecification;
multiValueViewController.delegate = self;
}
}
- (void) reloadTable {
for (UILabel *labelView in labelViews) {
[labelView removeFromSuperview];
}
for (UITextField *textView in textViews) {
[textView removeFromSuperview];
}
// Remove references to objects for garbage collection
labelViews = [NSMutableArray arrayWithObjects: nil];
textViews = [NSMutableArray arrayWithObjects: nil];
[self.tableView reloadData];
}
- (void) dealloc {
// Remove observers
[[NSNotificationCenter defaultCenter] removeObserver: self];
}
#end
MultiValueTableViewController.h
//
// MultiValueTableViewController.h
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import <UIKit/UIKit.h>
#import "SettingsController.h"
#protocol MultiValueDelegate
- (void) selectedMultiValue;
#end
#interface MultiValueTableViewController : UITableViewController {
NSDictionary *prefSpecification;
}
#property (nonatomic) id<MultiValueDelegate> delegate;
#property (strong, nonatomic) NSDictionary *prefSpecification;
#end
MultiValueTableViewController.m
//
// MultiValueTableViewController.m
// Cochlear App
//
// Created by Gilles Lesire on 16/07/14.
// Free to use
//
#import "MultiValueTableViewController.h"
#interface MultiValueTableViewController ()
#end
#implementation MultiValueTableViewController
#synthesize prefSpecification;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *title = [prefSpecification objectForKey: #"Title"];
self.navigationItem.title = title;
// Avoid tab bar to overlap tableview
self.edgesForExtendedLayout = UIRectEdgeAll;
self.tableView.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSArray *values = [prefSpecification objectForKey: #"Values"];
// Return the number of rows in the section.
return [values count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: #"Cell" forIndexPath:indexPath];
NSString *key = [prefSpecification objectForKey: #"Key"];
NSArray *titles = [prefSpecification objectForKey: #"Titles"];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSString *title = [titles objectAtIndex: indexPath.row];
// Create cell
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Set title
cell.textLabel.text = title;
// If this is the selected value
if([[values objectAtIndex: indexPath.row] intValue] == [[[NSUserDefaults standardUserDefaults] objectForKey: key] intValue]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [prefSpecification objectForKey: #"Key"];
NSArray *values = [prefSpecification objectForKey: #"Values"];
NSNumber *value = [values objectAtIndex: indexPath.row];
[[NSUserDefaults standardUserDefaults] setObject: value forKey: key];
[self.delegate selectedMultiValue];
[self.tableView reloadData];
}
#end
Storyboard Now go the storyboard and create a TableViewController. Select the TableViewController and Choose "Editor" -> "Embed in" -> "Navigation controller".
Set the class of the TableViewController as SettingsTableViewController. Set the identifier of the cell as "Cell", add a second TableViewCell to the TableView and set it's identifier as "MultiValueCell". Add a second TableViewController, and CTRL+CLICK and drag from the MultiValueCell to the second TableViewController. Set the class of the second TableViewController as MultiValueTableViewController. Set the identifier of the cell in the second TableViewController as "Cell" too. That's it!
#import "SettingViewController.h"
NSInteger selectedIndex;
//Use this, it works for me
- (void)viewDidLoad
{
selectedIndex = 0;
[super viewDidLoad];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50.0f;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [_arrayForSaveSetting count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
if (indexPath.row==selectedIndex) {
cell.accessoryType =UITableViewCellAccessoryCheckmark;
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
selectedIndex=indexPath.row;
[_tblSaveSetting reloadData];
}
i tried the following code for searching in epub ,Its not working the reason is
1.The table delegate methode executing at startup so the default value of search results is 0 ,so i give one dummy array with 4 elements in viewdidload method.So now tableview displaying only 4 thode elements in dummy array and when i scroll the tableview it displaying correct search results but still it showing only 4 elemets in that search results because number of rows methode is not execute while scrolling.
when i click search button it will call this methode in first class
SearchResultsViewController *searchRes=[[SearchResultsViewController alloc]initWithNibName:#"SearchResultsViewController" bundle:nil];
NSString *searchQuery=[search text];
sharedManager=[Mymanager sharedManager];
sharedManager.searchQuery=searchQuery;
// UITextField *textField = [NSString stringWithFormat:#"%#",searchQuery];
// [textField setFont:[UIFont fontWithName:#"BL-Ruthika-Bold" size:15]];
[searchRes searchString:searchQuery];
[self.navigationController pushViewController:searchRes animated:YES];
then it calls following methods in searchresult class
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"%d",[results count]);
if([results count]>0)
{
return [results count];
}
else
{
return [test count];
}
}
//executes only at the startup time ,so the value of results always become zero
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if([results count]>0) {
// cell.textLabel.adjustsFontSizeToFitWidth = YES;
hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
cell.textLabel.text = [NSString stringWithFormat:#"...%#...", hit.neighboringText];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];
cell.textLabel.font = [UIFont fontWithName:#"Trebuchet MS" size:13];
cell.textLabel.textColor = [UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
cell.detailTextLabel.textColor=[UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
cell.detailTextLabel.font= [UIFont fontWithName:#"Trebuchet MS" size:10];
return cell;
}
else
{
cell.textLabel.text=[test objectAtIndex:indexPath.row];
return cell;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
sharedManager=[Mymanager sharedManager];
hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
sharedManager.searchFlag=YES;
sharedManager.hitPageNumber=hit.pageIndex;
sharedManager.hitChapter=hit.chapterIndex;
sharedManager.hit=hit;
// [fvc loadSpine:hit.chapterIndex atPageIndex:hit.pageIndex highlightSearchResult:hit];
[self.navigationController popViewControllerAnimated:YES];
}
- (void) searchString:(NSString*)query{
currentQuery=sharedManager.searchQuery;
[self searchString:currentQuery inChapterAtIndex:0];
[[self resultsTableView]reloadData];
}
- (void) searchString:(NSString *)query inChapterAtIndex:(int)index{
currentChapterIndex = index;
sharedManager=[Mymanager sharedManager];
Chapter* chapter = [sharedManager.spineArray objectAtIndex:index];
NSRange range = NSMakeRange(0, chapter.text.length);
NSLog(#"%#",sharedManager.searchQuery);
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
int hitCount=0;
while (range.location != NSNotFound) {
range = NSMakeRange(range.location+range.length, chapter.text.length-(range.location+range.length));
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
hitCount++;
}
if(hitCount!=0){
UIWebView* webView = [[UIWebView alloc] initWithFrame:chapter.windowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:chapter.spinePath]];
[webView loadRequest:urlRequest];
} else {
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching = NO;
}
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
// NSLog(#"%#", error);
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView{
sharedManager=[Mymanager sharedManager];
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",[[sharedManager.spineArray objectAtIndex:currentChapterIndex] fontPercentSize]];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView highlightAllOccurencesOfString:sharedManager.searchQuery];
NSString* foundHits = [webView stringByEvaluatingJavaScriptFromString:#"results"];
NSLog(#"%#", foundHits);
NSMutableArray* objects = [[NSMutableArray alloc] init];
NSArray* stringObjects = [foundHits componentsSeparatedByString:#";"];
for(int i=0; i<[stringObjects count]; i++){
NSArray* strObj = [[stringObjects objectAtIndex:i] componentsSeparatedByString:#","];
if([strObj count]==3){
[objects addObject:strObj];
}
}
NSArray* orderedRes = [objects sortedArrayUsingComparator:^(id obj1, id obj2){
int x1 = [[obj1 objectAtIndex:0] intValue];
int x2 = [[obj2 objectAtIndex:0] intValue];
int y1 = [[obj1 objectAtIndex:1] intValue];
int y2 = [[obj2 objectAtIndex:1] intValue];
if(y1<y2){
return NSOrderedAscending;
} else if(y1>y2){
return NSOrderedDescending;
} else {
if(x1<x2){
return NSOrderedAscending;
} else if (x1>x2){
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
}];
[objects release];
for(int i=0; i<[orderedRes count]; i++){
NSArray* currObj = [orderedRes objectAtIndex:i];
SearchResult* searchRes = [[SearchResult alloc] initWithChapterIndex:currentChapterIndex pageIndex:([[currObj objectAtIndex:1] intValue]/webView.bounds.size.height) hitIndex:0 neighboringText:[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"unescape('%#')", [currObj objectAtIndex:2]]] originatingQuery:sharedManager.searchQuery];
[results addObject:searchRes];
[searchRes release];
}
[[self resultsTableView]reloadData];
//Print results
for(int i=0;i<[results count];i++)
{
hit = (SearchResult*)[results objectAtIndex:i];
}
[resultsTableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching= NO;
}
[[self resultsTableView]reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
resultsTableView=[[UITableView alloc]init];
[resultsTableView setDelegate:self];
[resultsTableView setDataSource:self];
sharedManager=[Mymanager sharedManager];
// Do any additional setup after loading the view from its nib.
results = [[NSMutableArray alloc] init];
test=[[NSArray alloc]initWithObjects:#"one",#"one",#"one",#"one",nil];
self.navigationItem.title=#"Search ";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
[[UINavigationBar appearance] setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeTextShadowColor: [UIColor lightGrayColor],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],
UITextAttributeFont: [UIFont fontWithName:#"Trebuchet MS" size:15.0f]
}];
[self searchString:sharedManager.searchQuery];
noMatchingSearch=[[NSArray alloc]initWithObjects:#"No Element Found", nil];
tableOfContents=[[NSMutableArray alloc]init];
for (id img in search.subviews)
{
if ([img isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[img removeFromSuperview];
}
}
tableOfContents=[sharedManager.List copy];
}
- (void)viewDidUnload
{
search = nil;
[super viewDidUnload];
resultsTableView.delegate=self;
resultsTableView.dataSource=self;
// Release any retained subviews of the main view.
self.resultsTableView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
When you have received your search results call
[self.tableView reloadData];
To tell the table view to update itself. I can see you have tried it a number of times in the large amount of code above. You only need to call it once, when you have your search results ready. Also, ensure your reference to the table view is valid when you call it.
Also, if you're creating a table view in an XIB file, then the second one you're creating in viewDidLoad and not showing (adding as a subview) is just confusing you and you're trying to reload the wrong table view.
If you still have problems, show the class properties and remove all the code tat isn't to do with the table view.
resultsTableView=[[UITableView alloc]init];
Try to use resultsTableView, with a property, and set it's to (nonatomic, strong).
When i click search it executes a search class and after finding the results it executes numberOfRows method but then it is showing empty table. It is not executing cellForRowAtIndexPath method .
check my below code
code in viewcontroller.h
when i click search button this method will get executed
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar{
SearchResultsViewController *searchRes=[[SearchResultsViewController alloc]initWithNibName:#"SearchResultsViewController" bundle:nil];
NSString *searchQuery=[search text];
sharedManager=[Mymanager sharedManager];
sharedManager.searchQuery=searchQuery;
[searchRes searchString:searchQuery];
[self.navigationController pushViewController:searchRes animated:YES];
}
in search class
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"%#",results);
return [results count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.adjustsFontSizeToFitWidth = YES;
NSLog(#"indexpath%d",indexPath.row);
NSLog(#"%#",[results objectAtIndex:[indexPath row]]);
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
NSLog(#"%#",hit.neighboringText);
cell.textLabel.text = [NSString stringWithFormat:#"...%#...", hit.neighboringText];
cell.detailTextLabel.text = [NSString stringWithFormat:#"Chapter %d - page %d", hit.chapterIndex, hit.pageIndex+1];
cell.textLabel.font = [UIFont fontWithName:#"Trebuchet MS" size:12];
cell.textLabel.textColor = [UIColor colorWithRed:25/255.0 green:90/255.0 blue:100/255.0 alpha:1];
// else
// {
//
// }
// [[self resultsTableView] reloadData];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
SearchResult* hit = (SearchResult*)[results objectAtIndex:[indexPath row]];
[fvc loadSpine:hit.chapterIndex atPageIndex:hit.pageIndex highlightSearchResult:hit];
}
- (void) searchString:(NSString*)query{
// if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// {
self.results = [[NSMutableArray alloc] init];
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
//
[self searchString:currentQuery inChapterAtIndex:0];
//
// }else {
// currentQuery=sharedManager.searchQuery;
// [self searchString:currentQuery inChapterAtIndex:0];
//}
}
- (void) searchString:(NSString *)query inChapterAtIndex:(int)index{
currentChapterIndex = index;
sharedManager=[Mymanager sharedManager];
Chapter* chapter = [sharedManager.spineArray objectAtIndex:index];
NSLog(#"%d",chapter.text.length);
NSRange range = NSMakeRange(0, chapter.text.length);
NSLog(#"%#",sharedManager.searchQuery);
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
int hitCount=0;
while (range.location != NSNotFound) {
range = NSMakeRange(range.location+range.length, chapter.text.length-(range.location+range.length));
range = [chapter.text rangeOfString:sharedManager.searchQuery options:NSCaseInsensitiveSearch range:range locale:nil];
hitCount++;
}
if(hitCount!=0){
UIWebView* webView = [[UIWebView alloc] initWithFrame:chapter.windowSize];
[webView setDelegate:self];
NSURLRequest* urlRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:chapter.spinePath]];
[webView loadRequest:urlRequest];
} else {
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching = NO;
}
}
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
NSLog(#"%#", error);
[webView release];
}
- (void) webViewDidFinishLoad:(UIWebView*)webView{
NSString *varMySheet = #"var mySheet = document.styleSheets[0];";
NSString *addCSSRule = #"function addCSSRule(selector, newRule) {"
"if (mySheet.addRule) {"
"mySheet.addRule(selector, newRule);" // For Internet Explorer
"} else {"
"ruleIndex = mySheet.cssRules.length;"
"mySheet.insertRule(selector + '{' + newRule + ';}', ruleIndex);" // For Firefox, Chrome, etc.
"}"
"}";
NSString *insertRule1 = [NSString stringWithFormat:#"addCSSRule('html', 'padding: 0px; height: %fpx; -webkit-column-gap: 0px; -webkit-column-width: %fpx;')", webView.frame.size.height, webView.frame.size.width];
NSString *insertRule2 = [NSString stringWithFormat:#"addCSSRule('p', 'text-align: justify;')"];
NSString *setTextSizeRule = [NSString stringWithFormat:#"addCSSRule('body', '-webkit-text-size-adjust: %d%%;')",[[sharedManager.spineArray objectAtIndex:currentChapterIndex] fontPercentSize]];
[webView stringByEvaluatingJavaScriptFromString:varMySheet];
[webView stringByEvaluatingJavaScriptFromString:addCSSRule];
[webView stringByEvaluatingJavaScriptFromString:insertRule1];
[webView stringByEvaluatingJavaScriptFromString:insertRule2];
[webView stringByEvaluatingJavaScriptFromString:setTextSizeRule];
[webView highlightAllOccurencesOfString:sharedManager.searchQuery];
NSString* foundHits = [webView stringByEvaluatingJavaScriptFromString:#"results"];
NSLog(#"%#", foundHits);
NSMutableArray* objects = [[NSMutableArray alloc] init];
NSArray* stringObjects = [foundHits componentsSeparatedByString:#";"];
for(int i=0; i<[stringObjects count]; i++){
NSArray* strObj = [[stringObjects objectAtIndex:i] componentsSeparatedByString:#","];
if([strObj count]==3){
[objects addObject:strObj];
}
}
NSArray* orderedRes = [objects sortedArrayUsingComparator:^(id obj1, id obj2){
int x1 = [[obj1 objectAtIndex:0] intValue];
int x2 = [[obj2 objectAtIndex:0] intValue];
int y1 = [[obj1 objectAtIndex:1] intValue];
int y2 = [[obj2 objectAtIndex:1] intValue];
if(y1<y2){
return NSOrderedAscending;
} else if(y1>y2){
return NSOrderedDescending;
} else {
if(x1<x2){
return NSOrderedAscending;
} else if (x1>x2){
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}
}];
[objects release];
NSLog(#"%#",currentQuery);
for(int i=0; i<[orderedRes count]; i++){
NSArray* currObj = [orderedRes objectAtIndex:i];
SearchResult* searchRes = [[SearchResult alloc] initWithChapterIndex:currentChapterIndex pageIndex:([[currObj objectAtIndex:1] intValue]/webView.bounds.size.height) hitIndex:0 neighboringText:[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"unescape('%#')", [currObj objectAtIndex:2]]] originatingQuery:currentQuery];
[results addObject:searchRes];
NSLog(#"%#",results);
[searchRes release];
}
//Print results
for(int i=0;i<[results count];i++)
{
SearchResult* hit = (SearchResult*)[results objectAtIndex:i];
NSLog(#"%#",hit.neighboringText);
}
[resultsTableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
if((currentChapterIndex+1)<[sharedManager.spineArray count]){
[self searchString:sharedManager.searchQuery inChapterAtIndex:(currentChapterIndex+1)];
} else {
fvc.searching= NO;
}
[[self resultsTableView] reloadData];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
//- (void)dealloc
////{
//// self.resultsTableView = nil;
//// //[results release];
//// //[currentQuery release];
//// [super dealloc];
//}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
resultsTableView=[[UITableView alloc]init];
[resultsTableView setDelegate:self];
[resultsTableView setDataSource:self];
sharedManager=[Mymanager sharedManager];
// Do any additional setup after loading the view from its nib.
results = [[NSMutableArray alloc] init];
self.navigationItem.title=#"Search ";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
[[UINavigationBar appearance] setTitleTextAttributes: #{
UITextAttributeTextColor: [UIColor whiteColor],
UITextAttributeTextShadowColor: [UIColor lightGrayColor],
UITextAttributeTextShadowOffset: [NSValue valueWithUIOffset:UIOffsetMake(0.0f, 1.0f)],
UITextAttributeFont: [UIFont fontWithName:#"Trebuchet MS" size:15.0f]
}];
noMatchingSearch=[[NSArray alloc]initWithObjects:#"No Element Found", nil];
tableOfContents=[[NSMutableArray alloc]init];
for (id img in search.subviews)
{
if ([img isKindOfClass:NSClassFromString(#"UISearchBarBackground")])
{
[img removeFromSuperview];
}
}
tableOfContents=[sharedManager.List copy];
}
- (void)viewDidUnload
{
search = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
self.resultsTableView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
MY SEARCH RESULTS
"<SearchResult: 0x113482c0>",
"<SearchResult: 0x11348a20>",
"<SearchResult: 0x88c0a50>"
The problem is with the search method before search the array is reinitialised and hence 0 returned in the resultArray and hence no value in tables
- (void) searchString:(NSString*)query{
self.results = [[NSMutableArray alloc] init];//Here it becomes 0!!
[resultsTableView reloadData];
currentQuery=sharedManager.searchQuery;
}
To make it right ,After the search is performed i believe
[self searchString:currentQuery inChapterAtIndex:0];
load the value in the result array and then reload table.
Make sure
in .h add
<UITableViewDataSource,UITableViewDelegate>
in nib
connect datasource and delegate[if via nib]
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