Xcode 4.2 Xib Drop Down Menu - xcode

I have created a .xib file and I'm having a little problem.
I did a video to show you where I'm at with it. The software I am using is Xcode 4.2 and its an iOS application.
Here is a copy of the code in my view .h .m
#import <UIKit/UIKit.h>
#interface myview : UIViewController <UITableViewDelegate, UITableViewDataSource, UIPickerViewDelegate, UIPickerViewDataSource>
#property (strong, nonatomic) IBOutlet UITableView* tableView;
#property (strong, nonatomic) IBOutlet UIPickerView* pickerView;
#property (strong, nonatomic) NSMutableArray* tableData;
#property (strong, nonatomic) NSMutableArray* pickerData;
#end
#import "myview.h"
#implementation myview
#synthesize tableView, pickerView, tableData, pickerData;
- (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];
// Do any additional setup after loading the view from its nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
tableView.delegate = self;
tableView.dataSource = self;
pickerView.delegate = self;
pickerView.dataSource = self;
tableData = [[NSMutableArray alloc] init]; // table starts empty
pickerData = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", #"4", #"5", nil]; // picker starts with values 1, 2, 3, 4, 5
[tableView reloadData];
[pickerView reloadAllComponents]; // Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
//The number of sections in UITableView
return 1;
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
// The number of rows in the UITableView
return [tableData count];
}
- (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];
}
// Set the table cell text to the appropriate value in tableDate
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Whatever happens when you select a table view row.
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
// The number of sections in the UIPickerView
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
// The number of rows in the UIPickerView
return [pickerData count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// The data for each row in the UIPickerView
return [pickerData objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// whatever you want to happen when a row is selected.
// here I am assuming you want to remove from the picker and add to the table on selection
[tableData addObject:[pickerData objectAtIndex:row]];
[pickerData removeObjectAtIndex:row];
[tableView reloadData];
[pickerView reloadAllComponents];
}
#end

I know this is super old and the video is removed so I am not sure what the exact problem is but it is most certainly related to you instantiating everything in our viewDidUnload... You should be doing this in your viewDidLoad most likely.

Related

TableView code to display plist is not working, Is it because it has to be on a UITableView Controller? (Xcode)

I cannot get my plist to display on my app. I need to use TableView and not a TableView Controller. Im not sure if I have followed the wrong code when first attempting it. Please take a look.
m. file is:
#import "ECSlidingViewController.h"
#import "NewsFeedViewController.h"
#import "BuySharesViewController.h"
#import "SellSharesViewController.h"
#import "FinancesViewController.h"
#import "CurrentHoldingsViewController.h"
#import "TradingHistoryViewController.h"
#import "LeaderboardViewController.h"
#import "HowToPlayViewController.h"
#import "MenuViewController.h"
#import "InitViewController.h"
#interface SellSharesViewController ()
{
BOOL isSearching;
}
#property (nonatomic, readonly) NSDate *CurrentDate;
#property (nonatomic, strong) NSDictionary *shares;
#property (nonatomic, strong) NSArray *shareValue;
#property (nonatomic, strong) NSArray *number;
#property (nonatomic, strong) NSArray *shareName;
- (void)resetSearch;
- (void)handleSearchForTerm:(NSString *)searchTerm;
#end
#implementation SellSharesViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
isSearching = NO;
NSString *path=[[NSBundle mainBundle] pathForResource:#"shares" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.allNames = dict;
//NSArray *array = [[self.names allKeys] sortedArrayUsingSelector:#selector(compare:)];
//self.keys = (NSMutableArray *)array;
[self resetSearch];
[self.table reloadData];
[self.table setContentOffset:CGPointMake(0.0, 44.0) animated:NO];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (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 ([self.keys count] > 0) ? [self.keys count] : 1 ;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
if ([self.keys count] == 0)
return 0 ;
NSString *key = [self.keys objectAtIndex:section];
NSArray *nameSection = [self.names objectForKey:key];
return nameSection.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [self.keys objectAtIndex:section];
NSArray *nameSection = [self.names objectForKey:key];
cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([self.keys count] == 0)
return nil;
NSString *key = [self.keys objectAtIndex:section];
if (key == UITableViewIndexSearch)
return nil;
return key;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
*/
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
if (isSearching)
return nil;
return self.keys;
}
#pragma mark -
#pragma mark Custom Methods
- (void) resetSearch {
NSMutableDictionary *allNamesCopy = [self.allNames mutableDeepCopy];
self.names = allNamesCopy;
NSMutableArray *keyArray = [[NSMutableArray alloc] init];
[keyArray addObjectsFromArray:[[self.allNames allKeys]
sortedArrayUsingSelector:#selector(compare:)]];
[keyArray insertObject:UITableViewIndexSearch atIndex:0];
self.keys = keyArray;
}
- (void)handleSearchForTerm:(NSString *)searchTerm {
NSMutableArray *sectionsToRemove = [[NSMutableArray alloc] init];
[self resetSearch];
for (NSString *key in self.keys) {
NSMutableArray *array = [self.names valueForKey:key];
NSMutableArray *toRemove = [[NSMutableArray alloc] init];
for (NSString *name in array ) {
if ([name rangeOfString:searchTerm
options:NSCaseInsensitiveSearch].location == NSNotFound)
[toRemove addObject:name];
}
if ([array count] == [toRemove count])
[sectionsToRemove addObject:key];
[array removeObjectsInArray:toRemove];
}
[self.keys removeObjectsInArray:sectionsToRemove];
[self.table reloadData];
}
#pragma mark -
#pragma mark Table View Delegate Methods
- (NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.search resignFirstResponder];
isSearching = NO;
self.search.text = #"";
[self.table reloadData];
return indexPath;
}
#pragma mark -
#pragma mark Search Bar Delegate Methods
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
NSString *searchTerm = [searchBar text];
[self handleSearchForTerm:searchTerm];
}
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchTerm {
if ([searchTerm length] == 0) {
[self resetSearch];
[self.table reloadData];
return;
}
[self handleSearchForTerm:searchTerm];
}
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
isSearching = NO;
self.search.text = #"" ;
[self resetSearch];
[self.table reloadData];
[searchBar resignFirstResponder];
}
-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
isSearching = YES;
[self.table reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView
sectionForSectionIndexTitle:(NSString *)titleForHeaderInSection
atIndex:(NSInteger)index {
NSString *key = [self.keys objectAtIndex:index];
if (key == UITableViewIndexSearch) {
[tableView setContentOffset:CGPointZero animated:NO];
return NSNotFound;
}
else {
return index;
}
}
#end
h.file is:
#import <UIKit/UIKit.h>
#interface SellSharesViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *sellShares;
#property (weak, nonatomic) IBOutlet UILabel *rowSelectedDisplay;
#property (weak, nonatomic) IBOutlet UIButton *removeShare;
#property (strong, nonatomic) UIButton *menuBtn;
-(IBAction)removeShareButton:(id)sender;
#end
Feel free to ask for anything else that may help. Thanks.
Change the uitableview property to strong instead of weak. I do this to have a strong pointer to the tableview so it does not get deallicateded. Also you need to connect the delegate and datasource of the uitableview to the uiviewcontroller in the storyboard. So the protocol methods will be called in your uiviewcontroller. If they are not connected the protocol methods are not being called so nothing will show up in your table view.
If you have an array of dictionaries the fornumberofrows return [myarray count];
Connecting the datasource and delegate in the storyboard is overlooked a lot of times so check this first. I hope this helps!
Did you set Delegate and Datasource in the XIB?
Other things you need to check is ,
Put break point in below methods and check if it s firing
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Make sure you are not returning zero in the first two methods.
If either of first 2 methods are not firing then it means you did not added the datasource in XIB

Performing a Segue from a table with searchbar to an UIImage in Detail View in xcode

I'm pretty new to xcode so I'm having trouble performing this task. I've created a table with a search bar with names that are passed to a detail view with a UILabel that shows the corresponding name of the cell clicked. The search bar works and it filters the results. I used this tutorial to help me with it:
http://www.appcoda.com/how-to-add-search-bar-uitableview/
Now I want to have an image in the detail view instead of a UILabel, that corresponds to each of the cells but I'm having trouble figuring out how to do that. Here is the code I'm working with:
TableViewController.h:
#interface SearchViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
#property (nonatomic, strong) IBOutlet UITableView *tableView;
TableViewController.m:
#interface SearchViewController ()
#end
#implementation SearchViewController {
NSArray *cards;
NSArray *searchResults;}
#synthesize tableView = _tableView;
-(void)viewDidLoad
{
[super viewDidLoad];
cards = [NSArray arrayWithObjects:
#"Snivy",
#"Servine",
#"Serperior",
#"Tepig",
#"Pignite",
#"Emboar",
#"Oshawott",
#"Dewott",
#"Samurott", nil];
}
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF contains[cd] %#",
searchText];
searchResults = [cards filteredArrayUsingPredicate:resultPredicate];}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller
shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString
scope:[[self.searchDisplayController.searchBar scopeButtonTitles]
objectAtIndex:[self.searchDisplayController.searchBar
selectedScopeButtonIndex]]];
return YES;
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
return [searchResults count];
} else {
return [cards count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SearchCardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = [searchResults objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [cards objectAtIndex:indexPath.row];
}
return cell;}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"ShowSearchCard"]) {
SearchCardViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
destViewController.cardName = [searchResults objectAtIndex:indexPath.row];
} else {
indexPath = [self.tableView indexPathForSelectedRow];
destViewController.cardName = [cards objectAtIndex:indexPath.row];
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier: #"ShowSearchCard" sender: self];
}
}
UIViewController.h:
#property (strong, nonatomic) IBOutlet UILabel *cardLabel;
#property (strong, nonatomic) NSString *cardName;
#property (strong, nonatomic) NSArray *searchCardDetail;
UIViewController.m:
#implementation SearchCardViewController
#synthesize cardLabel;
#synthesize cardName;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
cardLabel.text = cardName;
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)viewDidUnload {
[super viewDidUnload];
}
So in detail, the "cards" are the names in the table. Right now, it segue to a UILabel of the name of the card and I would like to have it instead, segue to the corresponding image of the card in the regular table and filtered table when searched. I appreciate your time and help! Thanks!
I'm not sure if I understanded your question correctly, but I would use one of these three approaches:
1st:
Easiest way is to follow this tutorial
2nd: Create custom cell which you will use instead of default cell. To get you on track, you can check this good tutorial How to create custom cell. In your custom cell, you'll declare additional variable, UIImage, which will or won't be displayed in your table view. Point is, you can send it in prepareForSegue method to your detailViewController.
3rd: Create NSDictionary where you will have values (images of your items) for keys (name of item). Then, pass it in prepareForSegue to your NSDictionary in detailViewController. After that, just assign your UIImage to UIImageView in your detailViewController based on what name of item did you receive. (So you'll still be sending name and then detailImage = [yourdict objectForKey:myItemName];)
I'm writing this on my windows laptop, because I'm not at work right now (that's where I have my mac mini), so there may be some syntax errors in my answer :)

Using a UIpickerview in a xib file

i have created a xib file in Xcode 4.2 and i am looking at getting it to the tabbed application but i have been trying and I'm a little bit new to Xcode , coding so thats why i need your help i have my code below but there are a few little errors but what i would like you lot to help me with is maybe getting to a tabbed application... well telling me what to do anyhow. heres a video for you to have a look at in case i haven't explained it correct (this is my video i did just for this question http://www.youtube.com/watch?v=e7R5_kGClM0 hope the video help but more importantly you can help me.
There is the .h but the is no errors in this
#import <UIKit/UIKit.h>
#interface myview : UIViewController <UITableViewDelegate, UITableViewDataSource, UIPickerViewDelegate, UIPickerViewDataSource>
#property (strong, nonatomic) IBOutlet UITableView* tableView;
#property (strong, nonatomic) IBOutlet UIPickerView* pickerView;
#property (strong, nonatomic) NSMutableArray* tableData;
#property (strong, nonatomic) NSMutableArray* pickerData;
#end
This is the .m but i will break it up
#import "myview.h"
#implementation myview
#synthesize tableView, pickerView, tableData, pickerData;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
this is the -(void)viewDidLoad];etc..
- (void)viewDidUnload
{
[super viewDidUnload];
tableView.delegate = self;
tableView.dataSource = self;
pickerView.delegate = self;
pickerView.dataSource = self;
tableData = [[NSMutableArray alloc] init]; // table starts empty
pickerData = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", #"4", #"5", nil]; // picker starts with values 1, 2, 3, 4, 5
[tableView reloadData];
[pickerView reloadAllComponents]; // Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(bool)
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {
//The number of sections in UITableView
return 1;
}
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
// The number of rows in the UITableView
return [tableData count];
}
- (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];
}
// Set the table cell text to the appropriate value in tableDate
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Whatever happens when you select a table view row.
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
// The number of sections in the UIPickerView
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
// The number of rows in the UIPickerView
return [pickerData count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// The data for each row in the UIPickerView
return [pickerData objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// whatever you want to happen when a row is selected.
// here I am assuming you want to remove from the picker and add to the table on selection
[tableData addObject:[pickerData objectAtIndex:row]];
[pickerData removeObjectAtIndex:row];
[tableView reloadData];
[pickerView reloadAllComponents];
}
#end
Here Are The Errors In The Code There are Two
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
^^^^^^^^^^^^^^^^^
**Local declaration of 'tableView hides instance variable**
Second error
[pickerView reloadAllComponents];
^^^^^^^^^^^^^^
Local declaration of 'pickerView hides instance variable
Thanks Very Much I Hope To Here From You Soon !!!
Use this, "tableView hides instance variable" occurs if local variable and instance variable have the same name.
- (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.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
and for pickerView use this
[self.pickerView reloadAllComponents];

unable to handover a string to my method

I have a problem in getting a method to work, and I am totally confused.
I am unable to hand over a string as a variable for my method.
I call the function even with the string, no variable currently.
Engine *myEngine = [Engine sharedInstance];
[myEngine getContentArrayFromEngine:#"zumbra"];
My method
-(NSMutableArray*) getContentArrayFromEngine:(NSString *)catName{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Catname:%#", catName);
//some more code
}
NSLOG output
2011-12-18 18:49:44.165 Zitate[77224:15203] Catname:(null)
Why is catName empty ???
edit1: the complete code
ThirdViewController.m
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString* myTempCatname;
myTempCatname = cell.textLabel.text;
// NSLog(#"test select %#", myTempCatname);
DetailViewController *detailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"detailzitat"];
[self.navigationController pushViewController:detailVC animated:YES];
Engine *myEngine = [Engine sharedInstance];
[myEngine getContentArrayFromEngine:myTempCatname];
}
and in the engine.m
-(NSMutableArray*) getContentArrayFromEngine:(NSString *)catName{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Übergebener Catname:%#", catName);
// catName=#"zumbra";
// NSLog(#"Inhalt InhalteFromWeb:%#", InhalteFromWeb);
NSLog(#"Catname:%#", catName);
unsigned count = [InhalteFromWeb count];
while (count--) {
NSLog(#"count %d %#", count, [[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY]);
if([[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY] isEqualToString:catName]) {
[categorieContent addObject:[InhalteFromWeb objectAtIndex:count]];
NSLog(#"Row %d has Content%#",count, [InhalteFromWeb objectAtIndex:count]);
}
}
NSLog(#"Inhalt Category:%#", categorieContent);
NSArray* tempAr = [[NSArray alloc] initWithArray:[categorieContent allObjects]];
return [NSMutableArray arrayWithArray:tempAr];
}
EDIT2:
Ok, even the hint with the catName did not work. so I have changed my code a little bit.
I have an array with a category, title, content, author, image for each row
I would like to do two things
1) get a unique list of all categories (its working fine)
2) when tapping on one of these categories , open a detailView , show the first element of this category, jump to previous and next item in category by swiping around.
For this, I am going to SET the category I have chosen
First try was to handover in the method, which did not work.
Now I though, SET the category in my engine.h and when displaying the single item, get the array for this category back.
but again, the value of the category is not stored.
ThirdViewController.h
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface ThirdViewController : UIViewController<UITableViewDelegate, UITableViewDataSource> {
NSMutableArray* CategoryList;
}
#property (nonatomic, retain) NSMutableArray* CategoryList;
#end
ThirdViewController.m
#import "ThirdViewController.h"
#import "engine.h"
#import "DetailViewController.h"
#implementation ThirdViewController
#synthesize CategoryList;
- (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];
Engine *myEngine = [Engine sharedInstance];
CategoryList = [myEngine getCategories];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [CategoryList count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier =#"Cell";
UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [CategoryList objectAtIndex:indexPath.row];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString* myTempCatname;
myTempCatname = cell.textLabel.text;
DetailViewController *detailVC = [self.storyboard instantiateViewControllerWithIdentifier:#"detailzitat"];
[self.navigationController pushViewController:detailVC animated:YES];
Engine *myEngine = [Engine sharedInstance];
[myEngine setCategName:myTempCatname];
NSLog(#"Aufruf %#", myTempCatname);
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
DetailViewController.h
#import <UIKit/UIKit.h>
#import <MessageUI/MFMailComposeViewController.h>
#import "engine.h"
#interface DetailViewController : UIViewController<MFMailComposeViewControllerDelegate> {
IBOutlet UILabel *authorLabel;
IBOutlet UILabel *categoryLabel;
IBOutlet UILabel *titleLabel;
IBOutlet UITextView *contentTextView;
NSString *authorText, *contentText, *categoryText, *titleText, *imageText, *catName;
NSMutableArray *contentArray;
}
#property (nonatomic, retain) IBOutlet UITextView *contentTextView;
#property (nonatomic, retain) IBOutlet UILabel *authorLabel;
#property (nonatomic, retain) IBOutlet UILabel *categoryLabel;
#property (nonatomic, retain) IBOutlet UILabel *titleLabel;
#property (nonatomic, retain) NSString *authorText, *contentText, *categoryText, *titleText, *imageText, *catName;
#property (nonatomic, retain) NSMutableArray *contentArray;
-(IBAction)vorher:(id)sender;
-(IBAction)nachher:(id)sender;
#end
DetailViewController.m
#import "DetailViewController.h"
#implementation DetailViewController
#synthesize contentTextView;
#synthesize authorText, contentText, categoryText, titleText, imageText;
#synthesize authorLabel, categoryLabel, titleLabel;
#synthesize contentArray;
#synthesize catName;
int contentIndex;
int contentMax;
- (IBAction)swipeDetected:(UIGestureRecognizer *)sender {
NSLog(#"Right Swipe detected");
}
-(IBAction) vorher:(id)sender {
NSLog(#"-----VORHER Button gedrückt-------");
if (contentIndex==0) {contentIndex=contentMax-1;}
else {contentIndex--;}
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
-(IBAction) nachher:(id)sender {
NSLog(#"-----Nachher Button gedrückt-------");
if (contentIndex==contentMax-1) {contentIndex=0;}
else {contentIndex++;}
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
Engine *myEngine = [Engine sharedInstance];
contentArray = [myEngine getContentArrayFromEngine];
contentMax = [contentArray count];
UISwipeGestureRecognizer *swipeRecognizerRight =
[[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(vorher:)];
swipeRecognizerRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:swipeRecognizerRight];
UISwipeGestureRecognizer *swipeRecognizerLeft =
[[UISwipeGestureRecognizer alloc]
initWithTarget:self
action:#selector(nachher:)];
swipeRecognizerLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:swipeRecognizerLeft];
titleText = [[contentArray objectAtIndex:contentIndex] objectForKey:TITLE];
authorText= [[contentArray objectAtIndex:contentIndex] objectForKey:AUTHOR];
contentText= [[contentArray objectAtIndex:contentIndex] objectForKey:CONTENT];
authorLabel.text=authorText;
titleLabel.text=titleText;
contentTextView.text=contentText;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
engine.h
//#import
#define AUTHOR #"author"
#define CATEGORY #"cat"
#define CONTENT #"content"
#define IMAGE #"image"
#define TITLE #"title"
#interface Engine : NSObject {
NSMutableArray* InhalteFromWeb;
NSInteger maxAnzahlInhalte;
NSString* categNameStorage;
}
+ (Engine *) sharedInstance;
- (NSMutableArray*) getZitateArrayFromEngine;
- (NSInteger) getMaxAnzahlZitateFromEngine;
- (NSString*) getAutor:(NSInteger)pos;
- (NSString*) getZitat:(NSInteger)pos;
- (NSString*) getAuthor:(NSInteger)pos;
- (NSString*) getCategory:(NSInteger)pos;
- (NSString*) getContent:(NSInteger)pos;
- (NSString*) getImage:(NSInteger)pos;
- (NSString*) getTitle:(NSInteger)pos;
-(NSMutableArray*) getContentArrayFromEngine;
-(void) setCategName:(NSString *) categNameVariable;
-(NSString*) getCategName;
-(NSMutableArray*) getCategories;
#end
engine.m
#import "Engine.h"
#implementation Engine
static Engine *_sharedInstance;
- (id) init
{
if (self = [super init])
{
// custom initialization
//Beginn my code
NSURL *url = [NSURL URLWithString:#"http://www.*/iMotivate.plist"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if( theConnection )
{
InhalteFromWeb = [[NSMutableArray alloc] initWithContentsOfURL:url];
maxAnzahlInhalte = [InhalteFromWeb count];
}
else
{
NSLog(#"Connection failed");
}
}
return self;
}
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
// NSLog(#"Recieving Response...");
}
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
// NSLog(#"Recieving Data...");
}
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message : #"An error has occured.Please verify your internet connection."
delegate:nil
cancelButtonTitle :#"OK"
otherButtonTitles :nil];
[alert show];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// NSLog(#"DONE. Received Quotes: %d", maxAnzahlZitate);
}
// ###########
+ (Engine *) sharedInstance
{
if (!_sharedInstance)
{
_sharedInstance = [[Engine alloc] init];
}
return _sharedInstance;
}
// Getter and Setter for WebArray
- (NSMutableArray*) getZitateArrayFromEngine{
return InhalteFromWeb;
}
- (NSInteger) getMaxAnzahlZitateFromEngine{
return maxAnzahlInhalte;
}
- (NSString*) getAutor:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:AUTHOR];
}
- (NSString*) getZitat:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CONTENT];
}
// #######
- (NSString*) getAuthor:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:AUTHOR];
}
- (NSString*) getCategory:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CATEGORY];
}
- (NSString*) getContent:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:CONTENT];
}
- (NSString*) getImage:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:IMAGE];
}
- (NSString*) getTitle:(NSInteger)pos{
return [[InhalteFromWeb objectAtIndex:pos] objectForKey:TITLE];
}
-(NSArray*) getCategories {
NSMutableSet* categorieSet = [[NSMutableSet alloc] init];
unsigned count = [InhalteFromWeb count];
while (count--) {
NSString *tempString;
tempString=[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY];
// NSLog(#"tempString %#", tempString );
[categorieSet addObject:tempString];
}
// NSLog(#"categories from engine %#", categorieSet);
NSArray* tempAr = [[[NSArray alloc] initWithArray:[categorieSet allObjects]]sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
return [NSMutableArray arrayWithArray:tempAr];
}
-(void) setCategName:(NSString *) categNameVariable
{ NSLog(#"categNameStorage 2%#",categNameStorage);
categNameStorage=categNameVariable;
NSLog(#"setCategName 1 %#",categNameVariable);
NSLog(#"categNameStorage 2%#",categNameStorage);
}
-(NSString*) getCategName {
return categNameStorage;
}
-(NSMutableArray*) getContentArrayFromEngine{
NSMutableSet* categorieContent = [[NSMutableSet alloc] init];
NSLog(#"Übergebener Catname:%#", categNameStorage);
// NSLog(#"Inhalt InhalteFromWeb:%#", InhalteFromWeb);
unsigned count = [InhalteFromWeb count];
while (count--) {
// NSLog(#"count %d %#", count, [[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY]);
if([[[InhalteFromWeb objectAtIndex:count] objectForKey:CATEGORY] isEqualToString:categNameStorage]) {
[categorieContent addObject:[InhalteFromWeb objectAtIndex:count]];
// NSLog(#"Row %d has Content%#",count, [InhalteFromWeb objectAtIndex:count]);
}
}
// NSLog(#"Inhalt Category:%#", categorieContent);
NSArray* tempAr = [[NSArray alloc] initWithArray:[categorieContent allObjects]];
return [NSMutableArray arrayWithArray:tempAr];
}
#end
There has to be a variable conflict with 'catName' in your view controller. I'm not sure why the view controller would be in scope, but I bet if you change your parameter to "inCatName" it will be fine. It's good to use naming conventions like that for this reason.

objectAtIndex - Message sent to deallocated instance

I am having a real problem finding where my problem is in my search controller. This is a table view with search bar and search display controller. It used to work fine, but all the sudden it stopped working. I turned on NSZombieEnabled and it shows that my NSArray called searchDataSource is the zombie.
When you type a search term the "shouldReloadTableForSearchTerm" executes the handleSearchForTerm function. The handleSearchForTerm" function accesses my ProductInfo class that query a SQLite database and returns the query results. Those results are then placed in my searchDataSource Array. Everything appears to work fine there. However, once I get to the "cellForRowAtIndexPath" function and I try to load the cells from the searchDataSource, that is when I run in to the problem of the Array having been deallocated.
Here is my code for the search controller:
//
// SearchViewController.h
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FourthViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate> {
UITableView *mainTableView;
NSArray *searchDataSource;
NSMutableArray *contentsList;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
NSString *webURL;
}
#property (nonatomic, retain) IBOutlet UITableView *mainTableView;
#property (nonatomic, retain) IBOutlet NSArray *searchDataSource;
#property (nonatomic, retain) NSMutableArray *contentsList;
#property (nonatomic, retain) NSMutableArray *searchResults;
#property (nonatomic, copy) NSString *savedSearchTerm;
#property (nonatomic, retain) NSString *webURL;
- (void)handleSearchForTerm:(NSString *)searchTerm;
#end
SearchViewController.m
//
// SearchViewController.m
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import "FourthViewController.h"
#import "ProductsDatabase.h"
#import "ProductInfo.h"
#import "WebViewController.h"
#implementation FourthViewController
#synthesize mainTableView;
#synthesize searchDataSource;
#synthesize contentsList;
#synthesize searchResults;
#synthesize savedSearchTerm;
#synthesize webURL;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.searchDataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set up the cell...
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row]; //This is where I get the 'message sent to deallocated instance' message.
[cell.textLabel setText:info.sName];
[cell.detailTextLabel setText:info.sType];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row];
webURL = [NSString stringWithFormat:#"http://www.prioritywire.com/specs/%#", info.sFile];
WebViewController *wvController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]];
wvController.URL = webURL;
wvController.navTitle = #"Spec Sheet";
[self.navigationController pushViewController:wvController animated:YES];
[wvController release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (void)dealloc {
[searchDataSource release], searchDataSource = nil;
[mainTableView release];
[contentsList release];
[searchResults release];
[savedSearchTerm release];
[super dealloc];
}
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
} else {
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self contentsList])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self handleSearchForTerm:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[self setSavedSearchTerm:nil];
self.searchDataSource = nil;
[self.mainTableView reloadData];
}
#end
I am quite new to objective-C and can't understand what I did wrong. I have spent days trying to figure this out and have had no luck. I would appreciate any help anyone can offer.
Keith
This bit of code seems to be the only place searchDataSource gets set:
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
If ProductsDatabase follows the rules, you don't own the returned array (i.e. it is already autoreleased) so the release on the fourth line is incorrect.
Don't you mean to use your searchResults-array instead of your searchDataSource, because in handleSearchForTerm: you are adding the results to it. Why do you even have the searchResult ivar? It's only used in handleSearchForTerm:, maybe some mixup there?

Resources