UIMenuController: how to tell which menuItem is pressed? - objective-c

I have a UILongPressGestureRecognizer on a UITableViewCell that displays a UIMenuController with some categories the user can pick from. These categories are stored in a NSMutableArray and can be customized by the user. I want to use one method to handle all category-presses in the UIMenuController. How can I pass the index of the selected UIMenuItem? Thanks in advance.
#pragma mark -
#pragma mark Custom Quick Menu Item
#interface QuickMenuItem : UIMenuItem
{
}
#property (nonatomic, retain) NSIndexPath *indexPath;
#property (nonatomic, retain) NSMutableString *category;
#end
#implementation QuickMenuItem
#synthesize indexPath, category;
- (void)dealloc
{
[indexPath release];
[category release];
[super dealloc];
}
#end
#pragma mark -
#pragma mark Handle UILongPressGesture
- (void)handleLongItemPress:(UILongPressGestureRecognizer *)longPressRecognizer
{
if (longPressRecognizer.state == UIGestureRecognizerStateBegan)
{
NSIndexPath *pressedIndexPath = [queueTableView indexPathForRowAtPoint:[longPressRecognizer locationInView:queueTableView]];
if (pressedIndexPath && (pressedIndexPath.row != NSNotFound) && (pressedIndexPath.section != NSNotFound))
{
[self becomeFirstResponder];
UIMenuController *menuController = [UIMenuController sharedMenuController];
NSMutableArray *categoryMenuItems = [NSMutableArray array];
NSEnumerator *e = [self.stats.categories objectEnumerator]; // array with categories
NSMutableString *cat;
while (cat = [e nextObject])
{
QuickMenuItem *categoryMenuItem = [[QuickMenuItem alloc] initWithTitle:cat action:#selector(quickMenuCategoryPressed:)];
categoryMenuItem.indexPath = pressedIndexPath;
categoryMenuItem.category = cat;
[categoryMenuItems addObject:categoryMenuItem];
[categoryMenuItem release];
}
menuController.menuItems = [NSArray arrayWithArray:categoryMenuItems];
[menuController setTargetRect:[queueTableView rectForRowAtIndexPath:pressedIndexPath] inView:queueTableView];
[menuController setMenuVisible:YES animated:YES];
}
}
}
- (void)quickMenuCategoryPressed:(UIMenuController *)menuController
{
QuickMenuItem *menuItem = [[[UIMenuController sharedMenuController] menuItems] objectAtIndex: ??]; // How to tell which category is selected?
if (menuItem.indexPath)
{
[self resignFirstResponder];
// Perform action
}
}

You'll probably need to create some dynamic selectors, as described at Dynamic UIMenuItems with #selector and dynamic methods

Related

UISearchController results are not being filtered

So I am using the UISearchController in my project, and it seems to work all fine but whatever I type on the Search Bar no I get no results. So I believe the problem is on my
(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
}. To be honest, I don't really know what code to put in that method. Here is the rest of the code:
#property (nonatomic, strong) UISearchController *searchController;
#property (nonatomic, strong) SearchResultsTableViewController *resultsTableController;
#property (nonatomic, strong) NSMutableArray *searchResults; // Filtered search results
// for state restoration
#property BOOL searchControllerWasActive;
#property BOOL searchControllerSearchFieldWasFirstResponder;
_resultsTableController = [[SearchResultsTableViewController alloc] init];
_searchController = [[UISearchController alloc] initWithSearchResultsController:self.resultsTableController];
self.searchController.searchResultsUpdater = self;
[self.searchController.searchBar sizeToFit];
self.tableView.tableHeaderView = self.searchController.searchBar;
self.searchController.delegate = self;
self.searchController.dimsBackgroundDuringPresentation = NO;
self.searchController.searchBar.delegate = self;
self.searchController.searchBar.tintColor = [UIColor darkGrayColor];
self.definesPresentationContext = YES;
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// restore the searchController's active state
if (self.searchControllerWasActive) {
self.searchController.active = self.searchControllerWasActive;
_searchControllerWasActive = NO;
if (self.searchControllerSearchFieldWasFirstResponder) {
[self.searchController.searchBar becomeFirstResponder];
_searchControllerSearchFieldWasFirstResponder = NO;
}
}}
#pragma mark - UISearchBarDelegate
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];}
#pragma mark - UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
}
You'll need to take the NSArray that your table view data comes from, filter it as per your search criteria, and then reload the table view. Your code might look something like this:
- (void) doSearch:(NSString *)searchText {
[self.filteredClients removeAllObjects];
if ( [searchText length] == 0 ) {
[self.filteredClients addObjectsFromArray:self.users];
} else {
for (User *user in self.users) {
NSString *name = [user fullName];
NSRange range = [[name lowercaseString] rangeOfString:[searchText lowercaseString]];
if ( range.location != NSNotFound )
[self.filteredClients addObject:user];
}
}
[self.tableView reloadData];
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
if ( [searchText length] > 0 )
{
[self showCancelButton:YES];
}
else {
[self showCancelButton:NO];
[searchBar resignFirstResponder];
}
[self doSearch:searchText];
}
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
[self showCancelButton:YES];
}
- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar
{
if ( [searchBar.text length] > 0 ) [self showCancelButton:YES];
else [self showCancelButton:NO];
[self doSearch:_searchBar.text];
}

Can't import NSMutableArray to another class, and save tablecell objects

I have an app that is tableview/pickerview controlled and for each table i have filled with textcellobjects.
Now when customer chooses one row and continue to next tableview I want to save that object in an NSMutableArray that is allocated/initialized in one class and I want to have that class file public so objects can be added from all the different tableview classes into the NSMutableArray.
The first 2 files MotorTVController code is working well, when a tableview cell is clicked the object is added to _myTrimArray, but I want to be able to save next tablecell object in the same _myTrimArray, i try to import the TrimArray.h(2 files last in the code here) with the same save function to MotorTVController to use the savearraycode from it, but is is not working.
So I want TrimArray.h/TrimArray.h to be able to save from all the different classes with tableviews and tableviewcell text values into one NSMutableArray.
I have been struggling with this for almost a week now, I hope someone can give me a solution, I'm kinda new at this, I know this cant be so difficult to solve, but I just don't know how?
//--------- MotorTVController.h
#import "YearPickerTVControllerPolaris.h"
#import "MotorTVController.h"
#import "motorTVCell.h"
#import "brandsTVCell.h"
#import "TrimArray.h"
#interface MotorTVController : YearPickerTVControllerPolaris
#property (nonatomic, strong) NSArray *motorLabelArray;
#property (nonatomic, strong) NSMutableArray *myTrimArray;
#end
//--------- MotorTVController.m file:
#import "MotorTVController.h"
#import "motorTVCell.h"
#import "YearPickerTVControllerPolaris.h"
#import "BackButton.h"
#import "TrimArray.h"
#interface MotorTVController ()
#end
#implementation MotorTVController
#synthesize myTrimArray = _myTrimArray;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
// Getter
- (NSMutableArray *)myTrimArray
{
if (_myTrimArray == nil) {
_myTrimArray = [[NSMutableArray alloc] init];
}
return _myTrimArray;
}
- (void)viewDidLoad
{
UIImage *arrow = [UIImage imageNamed:#"backbutton"];
UIButton *arrowButton = [[UIButton alloc] initWithFrame:CGRectMake(-12, 0, 36, 36)];
[arrowButton setBackgroundImage:arrow forState:UIControlStateNormal];
[arrowButton addTarget:self action:#selector(back)
forControlEvents:UIControlEventTouchUpInside];
UIView* buttonView = [[UIView alloc] initWithFrame:CGRectMake(-12, 0, 36, 36)];
[buttonView addSubview:arrowButton];
UIBarButtonItem * backbutton = [[UIBarButtonItem alloc]
initWithCustomView:buttonView];
[self.navigationItem setLeftBarButtonItem:backbutton];
[super viewDidLoad];
_motorLabelArray = #[#"Original EH12 (4hk)",
#"Honda GX160 (5.5hk)",
#"Subaru EX17 (6hk)",
#"Honda GX200 (6.5hk)",
#"Briggs LO206 (9hk)",
#"Briggs WF206 (11HK)"];
//NSLog(#"%#", _myTrimArray);
}
-(void)back
{
[self.navigationController popViewControllerAnimated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _motorLabelArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"motorTVCell";
motorTVCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
// Configure the cell...
[cell setTintColor:[UIColor blackColor]];
[cell setAccessoryType:UITableViewCellAccessoryDetailDisclosureButton];
[cell setAccessoryType:UITableViewCellAccessoryDetailButton];
NSInteger row = [indexPath row];
cell.motorCellLabel.text = _motorLabelArray[row];
return cell;
}
// Which row is selected
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath
{
NSInteger rowNumber = indexPath.row;
if (rowNumber == 0)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:0]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:0]);
}
else if (rowNumber == 1)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:1]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:1]);
}
else if (rowNumber == 2)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:2]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:2]);
}
else if (rowNumber == 3)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:3]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:3]);
}
else if (rowNumber == 4)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:4]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:4]);
}
else if (rowNumber == 5)
{
[_myTrimArray addObject:[_motorLabelArray objectAtIndex:5]];
NSLog(#"You choosed %#", [_myTrimArray objectAtIndex:5]);
}
}
#end
//-------------- TrimArray.m
#import "TrimArray.h"
#import "MotorTVController.h"
#interface TrimArray ()
#end
#implementation TrimArray
#synthesize myTrimArray = _myTrimArray;
// Getter
- (NSMutableArray *)myTrimArray
{
if (_myTrimArray == nil) {
_myTrimArray = [[NSMutableArray alloc] initWithCapacity:10];
}
return _myTrimArray;
}
#end
//----------------- TrimArray.h:
#import "MotorTVController.h"
#interface TrimArray : NSMutableArray
#property (nonatomic, strong) NSMutableArray *myTrimArray;
#end
If I understood right your question , you want an arrayObject to be available globally for all the other ViewControllers right ?
If so ,your subclassing form NSMutableArray and give it Property of NSMutableArray is Wrong.
To achieve this , the simplest solution would be to use NSUserDefaults.
To sore the ArrayObject Like below.
// Get the standardUserDefaults object, store your UITableView data array against a key, synchronize the defaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:_trimArray forKey:#"TrimArray"];
[userDefaults synchronize];
To retrieve // you can retrieve the arrayObject from anywhere in your app.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayOfObjects = [userDefaults objectForKey:#"TrimArray"];
// Use 'yourArray' to repopulate your UITableView

Set NSMutableArray to the new NSMutableArray

#implementation RightViewController{
NSMutableArray * tableArray;
}
#synthesize tableView;
- (void)viewDidLoad {
[super viewDidLoad];
tableArray = [[NSMutableArray alloc] init];
}
- (void)refreshTable: (NSMutableArray*)resultsArray{
[tableArray setArray:resultsArray];
NSLog(#"resultsArray : %d : %d", [tableArray count] , [resultsArray count]);
[self.tableView reloadData];
}
It shows me : resultsArray : 0 : 78
Why can't I set information to this array?
I do call refreshTable from another controller like this:
[[[RightViewController alloc] init] refreshTable:resultsArray];
Updated:
tableArray = [NSMutableArray arrayWithArray:resultsArray];
worked for me.
After that i do
- (IBAction)reloadTableButton:(id)sender {
[self refreshTable:tableArray];
}
and it's shows me : resultsArray : 0 : 0
Why is tableArray array empty?
Try setting your tableArray variable like so :
tableArray = [NSMutableArray arrayWithArray:resultsArray];
You might not be retaining your mutable array I would suggest making a #property for your tableArray. Place this before your #synthesize
#property (retain, nonatomic) NSMutableArray *tableArray;
Option 1:
- (void)viewDidLoad {
[super viewDidLoad];
//don't do anything with the array here!
//refreshTable may well be called before the view is loaded
}
- (void)refreshTable: (NSMutableArray*)resultsArray{
if (!self.tableArray) // if it does not exist, then create it on the fly.
self.tableArray = [[NSMutableArray alloc] init];
[tableArray setArray:resultsArray];
[self.tableView reloadData];
}
Option 2:
- (MyClass*) init {
self = [super init];
if (self) {
self.tableArray = [[NSMutableArray alloc] init];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
//don't do anything with the array here!
}
- (void)refreshTable: (NSMutableArray*)resultsArray{
[tableArray setArray:resultsArray]; // you can be sure that init was invoked earlier.
[self.tableView reloadData];
}
Option 3:
- (void)viewDidLoad {
[super viewDidLoad];
//don't do anything with the array here!
}
- (void)refreshTable: (NSMutableArray*)resultsArray{
self.tableArray = [NSMutalbeArray arrayWithArray:resultsArray]; //This creates a new array as a copy of resultsArray and assigns it to tableArray. No need to initialize anything.
[self.tableView reloadData];
}
i believe it should work
RightViewController *controller = [[RightViewController alloc] init];
[controller refreshTable:resultsArray];
#implementation RightViewController{
NSMutableArray * tableArray;
}
#property (strong, nonatomic) NSMutableArray *tableArray; //use the keyword "retain" instead of "strong" in below iOS 5
#synthesize tableView;
#synthesize tableArray;
- (void)viewDidLoad {
[super viewDidLoad];
self.tableArray = [[NSMutableArray alloc] init];
}
- (void)refreshTable: (NSMutableArray*)resultsArray{
self.tableArray = resultsArray;
NSLog(#"resultsArray : %d : %d", [tableArray count] , [resultsArray count]);
[self.tableView reloadData];
}

NSMutableArray gets reset after calling modalViewController

IT IS SOLVED BY #T-X. I've marked the changes with "// SOLUTION" in the code!!!
I have the following issue, if I presentModalViewController, the NSMutableArray "projectsArray" gets reset.
Here is my code:
Here the .h file:
// ViewController.h
#import <UIKit/UIKit.h>
#class AddProject;
#interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
IBOutlet UITableView *projectsTableView;
UIAlertView *reallyDelete;
BOOL candelButtonClicked;
NSIndexPath *actualIndexPath;
NSMutableArray *projectsArray;
NSInteger ID;
NSString *NAME;
AddProject *addProject;
**ViewController *viewContr; // SOLUTION**
}
- (IBAction)addNewProject:(id)sender;
- (void)addToTableView:(NSString *)projectName;
#property (nonatomic, retain) UIAlertView *reallyDelete;
#property (nonatomic) NSInteger cancelButtonIndex;
#property IBOutlet UITableView *projectsTableView;
#property (nonatomic, retain) AddProject *addProject;
**#property (nonatomic, retain) ViewController *viewContr; // SOLUTION**
#end
Here the .m file:
// ViewController.m
#import "ViewController.h"
#import "CustomTableCell.h"
#import "AddProject.h"
#interface ViewController ()
#end
#implementation ViewController
**#synthesize viewContr; // SOLUTION**
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
projectsArray = [[NSMutableArray alloc] init];
ViewController *element = [[ViewController alloc] init];
element->ID = 1;
element->NAME = #"Demo project";
NSLog(#"viewdidload");
[projectsArray addObject:element];
NSLog(#"1. Array length: %d", [projectsArray count]);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([projectsArray count] < 1) {
NSLog(#"2. Array length: 0");
return 0;
} else {
NSLog(#"2. Array length: %d", [projectsArray count]);
return [projectsArray count];
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 78;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customTableCellIdentifier = #"CustomTableCell";
CustomTableCell *cell = (CustomTableCell *)[tableView dequeueReusableCellWithIdentifier:customTableCellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
ViewController *element = [[ViewController alloc] init];
element = [projectsArray objectAtIndex:indexPath.row];
cell.nameLabel.text = element->NAME;
cell.prepTimeLabel.text = [NSString stringWithFormat:#"%i", element->ID];
NSLog(#"3. Array length: %d", [projectsArray count]);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
reallyDelete = [[UIAlertView alloc] initWithTitle:#"Deleting" message:#"Do your really want to delete that row?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[reallyDelete show];
actualIndexPath = indexPath;
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex != [reallyDelete cancelButtonIndex])
{
//If "Yes" clicked delete
[projectsArray removeObjectAtIndex:actualIndexPath.row];
NSLog(#"delete row");
[self.projectsTableView deleteRowsAtIndexPaths:[NSMutableArray arrayWithObjects:actualIndexPath, nil] withRowAnimation:YES];
[self.projectsTableView reloadData];
}
}
#pragma mark Edit
- (IBAction)addNewProject:(id)sender {
NSLog(#"4. Array length: %d", [projectsArray count]);
AddProject *addProjectView = [[AddProject alloc] initWithNibName:#"AddProject" bundle:nil];
NSLog(#"4.1 Array length: %d", [projectsArray count]);
addProjectView.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
NSLog(#"4.2 Array length: %d", [projectsArray count]);
addProjectView.modalPresentationStyle = UIModalPresentationFormSheet;
NSLog(#"4.3 Array length: %d", [projectsArray count]);
**addProjectView.viewContr = self; // SOLUTION**
[self presentModalViewController:addProjectView animated:YES];
NSLog(#"4.4 Array length: %d", [projectsArray count]);
addProjectView.view.superview.frame = CGRectMake(addProjectView.view.center.x/2.5, addProjectView.view.center.y/3, 800, 600);
NSLog(#"4.5 Array length: %d", [projectsArray count]);
}
- (void)addToTableView:(NSString *)projectName
{
NSLog(#"Project Array: %#", projectsArray);
NSLog(#"addToTableView: %#", projectName);
NSLog(#"5. Array length: %d", [projectsArray count]);
ViewController *element = [[ViewController alloc] init];
element->ID = 2;
element->NAME = projectName;
[projectsArray addObject:element];
NSLog(#"6. Array length: %d", [projectsArray count]);
[self.projectsTableView reloadData];
[self.projectsTableView setNeedsDisplay];
}
- (void)viewDidUnload
{
[self setProjectsTableView:nil];
self.projectsTableView = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#end
Here the .h file of the modal presented view:
// AddProject.h
#import <UIKit/UIKit.h>
#class ViewController;
#interface AddProject : UIViewController
{
IBOutlet UITextField *projectName;
ViewController *viewContr;
}
- (IBAction)back:(id)sender;
- (IBAction)next:(id)sender;
#property (nonatomic, retain) ViewController *viewContr;
#end
The .m file of the modal presented file:
// AddProject.m
#import "AddProject.h"
#import "ViewController.h"
#interface AddProject ()
#end
#implementation AddProject
**#synthesize viewContr; // SOLUTION I've mist to synthesize it**
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
**// SOLUTION no new allocation/init of ViewController**
}
- (IBAction)back:(id)sender
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)next:(id)sender
{
[viewContr addToTableView:projectName.text];
[viewContr.projectsTableView reloadData];
[viewContr.projectsTableView setNeedsDisplay];
[self dismissModalViewControllerAnimated:YES];
}
- (void)viewDidUnload
{
projectName = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
#end
I've tested the code by using breakpoints and I could locate the issue when the AddProject class "viewDidLoad" starts loading. But I don't know why it resets the array.
You navigate from ViewController Screen to Add project Screen. In Add Project Screen, you add a new project and want to delegate back this information to the ViewController Screen where you came from.
Now, you are trying to have an instance of ViewController in your AddProject, which you newly instantiate in viewDidLoad method and when project is added, you provide the information to it by calling - (void)addToTableView:(NSString *)projectName on it.
This doesn't work because - The instance of ViewController you allocated is a new instance and not the one you navigated from. When you do alloc + init you get a new object. Thus, although you get addToTableView: called on your ViewController, it doesn't work because the ViewController instance that is receiving this message is a new instance and not the one you navigated from.
Thus, all you needed to do is - have a ViewController property in your Add Project, which you would set before navigating. And then you can send message to this property - As explained in this transcript.
I would like to say - However this thing works, it provides tight coupling between the two controllers.
Ideally, This cane be done by making ViewController (where you go navigate from) as a delegate of Add Project (where you navigate to). And then Add Project can delegate the added project to it's delegate by something like - (void) addProjectController:(AddProjectViewController *) controller didAddProject:(NSString *) projectName. This provides lose coupling between the two view controllers. To understand delegation concept, refer to Delegates and Datasources. Alternatively, search for other Stack overflow posts.
You should allocate projectsArray in the init method of the view controller, not in in viewDidLoad. projectsArray = [[NSMutableArray alloc] init]; allocated a new empty array tach time the view is loaded.
Okay my issue is fixed through the stackoverflow chat. The tips for the final solution came from user #T-X. I've added the tips in the code in my question. They are marked with "// SOLUTION".
In Add Project View controller's viewDidLoad method, remove the line
viewContr = [[ViewController alloc] init];. Now make the variable
viewContr in your ViewController class a property. Also synthesize
it. And finally in the - (IBAction)addNewProject:(id)sender method,
before presenting the controller, do - addProjectView.viewContr = self;. It will solve your issue.
(quote from chat.stackoverflow | #T-X)

UIPicker accessing items from a plist

I have a plist that is being loaded into a UIPickerView. I can access the array info and have it loaded into the picker in one of the components. What I'm trying to do is to access Item 0 or Item 1 and have them displayed on a UILabel based on a condition.
I can't figure out how to access Item 0 or Item 1 (the string values). Any tips on how I'd go about doing this? thanks for the help.
here's an image to clarify what I'm talking about:
pickerViewcontroller.h
#import <UIKit/UIKit.h>
#define kStateComponent 0
#define kZipComponent 1
#interface PickerViewController : UIViewController
<UIPickerViewDataSource,UIPickerViewDelegate>{
IBOutlet UIPickerView *dpicker;
NSDictionary *stateZip;
NSArray *states;
NSArray *zips;
}
#property (nonatomic,retain) UIPickerView *dpicker;
#property (nonatomic,retain) NSDictionary *stateZip;
#property (nonatomic, retain) NSArray *states;
#property (nonatomic, retain) NSArray *zips;
#end
pickerViewcontroller.m
#import "PickerViewController.h"
#implementation PickerViewController
#synthesize dpicker;
#synthesize stateZip;
#synthesize states;
#synthesize zips;
-(void) viewDidLoad{
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath =[bundle pathForResource:#"plistfilename" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.stateZip=dictionary;
[dictionary release];
NSArray *component = [self.stateZip allKeys];
NSArray *sorted =[component sortedArrayUsingSelector:#selector(compare:)];
self.states=sorted;
NSString *selectedState = [self.states objectAtIndex:0];
NSArray *array = [stateZip objectForKey:selectedState];
self.zips = array;
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
}
- (void)dealloc {
[dpicker release];
[stateZip release];
[states release];
[zips release];
[super dealloc];
}
#pragma mark-
#pragma mark picker Data Source Methods
-(NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerview
{
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == kStateComponent)
return [self.states count];
return [self.zips count];
}
#pragma mark picker delegate Methods
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if(component == kStateComponent)
return[self.states objectAtIndex:row];
return [self.zips objectAtIndex:row];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == kStateComponent)
{
NSString *selectedState = [self.states objectAtIndex:row];
NSArray *array=[stateZip objectForKey:selectedState];
self.zips=array;
[dpicker selectRow:0 inComponent:kZipComponent animated:YES];
[dpicker reloadComponent:kZipComponent];
}
}
#endhere