I am trying to implement an UIPickerView programmatically. I have implemented the delegate and datasource.
When I first navigate to the UIPickerView everything works fine. If I leave the View and come back to it later, the UIPickerView looks fine.
But when I try to select an other item it crashes.
When I debug it, I saw that my data array is empty. But I don’t know why.
In on class I init the UIPickerView:
DropDownController *objPickerView = [[DropDownController alloc] init];
objPickerView.userInfo = userInfo;
[objPickerView setDataSourceForPickerView:[dropDownItem valueForKey:#"dropDownEntries"] withPreselectedItem:preSelectedItem];
[dropDownContainer addSubview:objPickerView.picker];
The Picker is in this Controller:
#interface DropDownController : UIViewController <FormElement, UIPickerViewDelegate, UIPickerViewDataSource>
{
NSArray *dropDownData;
UIPickerView *picker;
UIElement *userInfo;
}
#property (strong, nonatomic) NSArray *dropDownData;
#property (strong, nonatomic) IBOutlet UIPickerView *picker;
#property (nonatomic, retain) UIElement *userInfo;
-(void)setDataSourceForPickerView:(NSArray *)dataDictionary withPreselectedItem:(NSString*) preSelectedItem;
#end
Here I set the Delegate and Datasource:
-(void)setDataSourceForPickerView:(NSMutableArray *)dataDictionary withPreselectedItem:(NSString*) preSelectedItem{
picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 300, 162)];
picker.delegate = self;
picker.dataSource = self;
picker.showsSelectionIndicator = YES;
dropDownData = dataDictionary;
}
After returning to the View dropDownData is empty.
I've found the problem. I need to copy the dictionary, not only set a reference.
// dropDownData = dataDictionary; -> wrong
dropDownData = [dataDictionary copy];
Related
I would like to modify the text property of a UILabel (nameLbl) but don't know what i am wrong.
I have 2 Views, the first is a ViewController, the second is ProfileViewController. The ProfileViewController fill some field of user profile this data are passed to ViewController and showed in UIlabel.
The issue is I can't show the datas in the ViewController.
What am I get wrong?
---ViewController.h---
#interface ViewController : UIViewController
{
IBOutlet ViewController *profile;
IBOutlet UILabel *nameLbl, *celLbl, *cfLbl;
IBOutlet UITextField *nameTF;
}
#property (nonatomic, retain) IBOutlet ViewController *profile;
#property (retain, nonatomic) IBOutlet UILabel *nameLbl, *celLbl, *cfLbl;
#property (nonatomic, retain) IBOutlet UITextField *nameTF;
-(void) setUser: (NSString *) name:(NSString *) cel:(NSString *) cf;
#end
---ViewController.m---
#synthesize nameLbl, celLbl, cfLbl;
-(void) setUser:(NSString *)name:(NSString *)cel:(NSString *)cf
{
nameLbl = [[UILabel alloc] init];
[nameLbl setText:name];
}
this is the connection inspector
https://drive.google.com/file/d/0Bz7WcQmZNuFLMWt3QUo1Tk5XUW8/edit?usp=sharing
Remove
nameLbl = [[UILabel alloc] init];
from your code it seems that the nameLbl UILabel has already been initialized from nib, and you are creating a new memory reference, so its not working.
Hi everyone I have been building an app and have met some problems.
My app has two viewControllers. One is MenuViewController and another one is MainViewController.
I want to pass a string from MainViewController to a mutableArray in MenuViewController, but have no idea how.
Here are my codes:
<MenuViewController.h>
#import <UIKit/UIKit.h>
#interface MenuViewController : UITableViewController {
NSMutableArray *secondFavourite;
}
#property (nonatomic, strong) NSMutableArray *secondFavourite;
#end
.
<MenuViewController.m>
#import "MenuViewController.h"
#import "MainViewController.h"
#interface MenuViewController ()
#property (strong, nonatomic) NSArray *menu;
#end
#implementation MenuViewController
#synthesize menu;
#synthesize secondFavourite;
- (void)viewDidLoad
{
[super viewDidLoad];
self.secondFavourite = [[NSMutableArray alloc] init];
self.menu = self.secondFavourite;
}
.
<MainViewController.h>
#import <UIKit/UIKit.h>
#import <social/Social.h>
#interface MainViewController : UIViewController {
IBOutlet UIImageView *imagepost;
UILabel *predictionLabel;
}
- (IBAction)sampleSelector:(UIButton *)sender;
- (IBAction)showAllClick:(id)sender;
#property (nonatomic, retain) IBOutlet UILabel *predictionLabel;
#property (strong, nonatomic) NSArray *predictionArray;
#property (strong, nonatomic) UIButton *menuBtn;
#property (strong, nonatomic) NSMutableArray *fav;
#property (strong, nonatomic) IBOutlet UILabel *favLabel;
#property (strong, nonatomic) IBOutlet UITableView* tableView;
#property (nonatomic, strong) NSMutableArray *favourite;
#end
.
<MainViewController.m>
- (void)viewDidLoad
{
[super viewDidLoad];
self.predictionArray = [[NSArray alloc] initWithObjects:#"Hey gurl", nil];
}
//Add to favourite
- (void) addToFav {
self.favourite = [[NSMutableArray alloc] init];
[self.favourite addObject:self.predictionLabel.text];
[self.tableView reloadData];
NSLog(#"%#", self.favourite);
}
//add to favourite button action
- (IBAction)addToFavButton:(id)sender {
[self addToFav];
//pass data from favourite here to secondFacourite in MenuViewController (found on stack overflow)
MenuViewController *menuViewController = [[MenuViewController alloc]initWithNibName:#"MenuViewController" bundle:nil];
menuViewController.secondFavourite = [[NSMutableArray alloc]initWithArray:self.favourite];
[self.navigationController pushViewController:menuViewController animated:YES];
}
I used NSLog to check that the menuViewController.secondFavourite in MainViewController successfully added the string into the array, isn't the array the same array in MenuViewController? Why doesn't the menu.tableView update and show the new string added? I am very confused and I hope someone will help me out.
Thanks for reading this.
This has to do with the fact that your menu viewDidLoad is overwriting the value in these two lines:
self.secondFavourite = [[NSMutableArray alloc] init];
self.menu = self.secondFavourite;
That first line is setting your secondFavourite property to an empty NSMutableArray instance. And since viewDidLoad will be called only after the view has been loaded into memory (in this case, when you try to push the view controller onto the stack), your initial values in the secondFavourite property will be lost.
Instead, you should move that initialization code into the an init method.
I've read through many posts here but I can't seem to make my array available in another class.
I want to access the array plusTransactions in CPPHistoryViewController (a table controller, in a container as a child of CPPSecondViewController) from class CPPSecondViewController.
CPPSecondViewController.h
#import <UIKit/UIKit.h>
#interface CPPSecondViewController : UIViewController <UIWebViewDelegate>
#property (weak, nonatomic) IBOutlet UIWebView *webView;
#property (weak, nonatomic) IBOutlet UISegmentedControl *segmentedController;
#property (weak, nonatomic) NSMutableArray *plustransactions;
#property (weak, nonatomic) NSMutableArray *campustransactions;
#property (weak, nonatomic) NSMutableArray *mealtransactions;
#end
CPPSecondViewController.m
#import "CPPSecondViewController.h"
#interface CPPSecondViewController ()
#implementation CPPSecondViewController
#end
#synthesize plustransactions = _plustransactions;
#synthesize campustransactions = _campustransactions;
#synthesize mealtransactions = _mealtransactions;
...
_plustransactions = newPlustransactions;
NSLog(#"%#", newPlustransactions);
NSLog(#"%#%lu", #"That's how many: ", (unsigned long)_plustransactions.count);
CPPHistoryViewController *historyView = [[CPPHistoryViewController alloc]init];
[historyView.tableView reloadData];
This is good, returns all of my array items and count is 7.
CPPHistoryViewController.h
#import <UIKit/UIKit.h>
#interface CPPHistoryViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>
#end
CPPHistoryViewController.m
#import "CPPHistoryViewController.h"
#import "CPPSecondViewController.h"
#import "CPPPlusTransaction.h"
#import "CPPCampusTransaction.h"
#import "CPPMealTransaction.h"
#import "CPPHistoryCell.h"
#interface CPPHistoryViewController ()
#end
#implementation CPPHistoryViewController
...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
CPPSecondViewController *secondView = [[CPPSecondViewController alloc] init];
NSMutableArray *plusTransactions = [[NSMutableArray alloc]init];
plusTransactions = secondView.plustransactions;
NSMutableArray *campusTransactions = [[NSMutableArray alloc]init];
campusTransactions = secondView.campustransactions;
NSMutableArray *mealTransactions = [[NSMutableArray alloc]init];
mealTransactions = secondView.mealtransactions;
NSLog(#"Table formatting called");
NSLog(#"%ld", (long)secondView.segmentedController.selectedSegmentIndex);
switch (secondView.segmentedController.selectedSegmentIndex) {
case 0:
NSLog(#"%#%lu", #"PlusTransactions", (unsigned long)plusTransactions.count);
return plusTransactions.count;
break;
case 1:
NSLog(#"%#%lu", #"CampusTransactions", (unsigned long)campusTransactions.count);
return campusTransactions.count;
break;
case 2:
NSLog(#"%#%lu", #"MealTransactions", (unsigned long)mealTransactions.count);
return mealTransactions.count;
break;
}
return 1;
}
...
#end
Here's where things get weird. Any array I call from here returns with a count of 0. Any ideas?
I assume what you want is to get the array data stored in CPPSecondViewController to be availalbe in CPPHistoryViewController. But as per the code you posted,
CPPHistoryViewController *historyView = [[CPPHistoryViewController alloc]init];
[historyView.tableView reloadData];
This just create new instance and the tableView inside the view is reloaded. But in cellForRowAtIndexPath, you are creating new instance of CPPSecondViewController, thats wrong.
What you can do is, simply pass the CPPSecondViewController instance before reloading tableView.
In CPPHistoryViewController.h, create a property for keeping secondView like this
#property (strong, nonatomic) CPPSecondViewController *secondView;
then, change your code in CPPSecondViewController like below:
CPPHistoryViewController *historyView = [[CPPHistoryViewController alloc]init];
historyView.secondView = self;
[historyView.tableView reloadData];
Also, remove alloc init statements from cellForRowAtIndexPath, just use secondView.plustransactions here.
Hope this helps!
CPPSecondViewController *secondView = [[CPPSecondViewController alloc] init];
Here you are creating a new object, So all values are nill.
Here you can only set values in to second view controller.
in your History class, you nedd to create a property of a second class they you can set value in to Second class
#property (nonatomic, retain) Secondclass* secondclass;
[secondClass setAry: ary];
CPPSecondViewController *secondView = [[CPPSecondViewController alloc] init];
in this code, the view controller is just init, the properties is all nil, it's a new view controller instance.
setup properties in init method, or access the second view's view property, to load view, to trigger the property initialize.
if you want reference the second view controller from history view controller, you can add a property in history view controller refer to second view controller.
in CPPHistoryViewController.h
#property (weak, nonatomic) CPPSecondViewController *secondViewController;
and set this property in your show code.
in CPPSecondViewController.m
_plustransactions = newPlustransactions;
NSLog(#"%#", newPlustransactions);
NSLog(#"%#%lu", #"That's how many: ", (unsigned long)_plustransactions.count);
CPPHistoryViewController *historyView = [[CPPHistoryViewController alloc]init];
historyView.secondViewController = self;
[historyView.tableView reloadData];
#import <UIKit/UIKit.h>
#import "HZAreaPickerView.h"
#interface CodeNumberViewController : UIViewController<UITextFieldDelegate, HZAreaPickerDelegate>
#property (weak, nonatomic) IBOutlet UITextField *areaText;
#property (weak, nonatomic) IBOutlet UITextField *cityText;
#property (strong, nonatomic) NSString *areaValue, *cityValue;
#property (strong, nonatomic) HZAreaPickerView *locatePicker;
-(void)cancelLocatePicker;
#end
-----------------below's .m file--------------
#pragma mark - TextField delegate
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if ([textField isEqual:self.areaText]) {
[self cancelLocatePicker];
self.locatePicker = [[HZAreaPickerView alloc] initWithStyle:HZAreaPickerWithStateAndCityAndDistrict delegate:self];
[self.locatePicker showInView:self.view];
} else {
[self cancelLocatePicker];
self.locatePicker = [[HZAreaPickerView alloc] initWithStyle:HZAreaPickerWithStateAndCity delegate:self];
[self.locatePicker showInView:self.view];
}
return NO;
}
When I click the UITextField, I found the textFieldShouldBeginEditing even not being called. What's wrong? I already connected the UITextField to the .h file.
I truly hope u can help, if u need more details, I'll add, do not minus my reputation cause I don't have much. Thanks
I guess you didn't set the delegate, in your viewDidLoad set:
self.areaText.delegate = self;
self.cityText.delegate = self;
Did you connect UITextField delegate or mention in your code ??
First you have to add UITexFieldDelegate like you have already done, but you also need to connect the UITextField with the delegate when you initialize it. You can add it programmatically or just connecting it in the xib file(or storyboard).
Programmatically:
areaText; = [[UILabel alloc] initWithFrame:frane];
areaText.delegate = self;
[self.view addSubview:areaText];
I'm having a main view controller containing a UIScrollView called containerScrollView. This scrollview has on each page another scrollview with the size of the screen containing two view controllers: MessagesViewController and InfoViewController. Here's a schema.
The personScrollView in the containerScrollView works fine but the problem is in the adding of the two view controllers' view to the personScrollView.
#property (nonatomic, retain) MessagesViewController *matchesVC;
#property (nonatomic, retain) InfoViewController *standingsVC;
for (int i = 0; i < 3; i++) {
UIScrollView *personScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(i*320, 0, 320, self.containerScrollView.frame.size.height)];
NSArray *colors = #[[UIColor blueColor], [UIColor orangeColor], [UIColor greenColor]];
[personScrollView setBackgroundColor:[y objectAtIndex:i]];
[personScrollView setPagingEnabled:YES];
[personScrollView setContentSize:CGSizeMake(self.view.frame.size.width * 2, personScrollView)];
[self.containerScrollView addSubview:personScrollView];
/* Populate the scrollview */
// Messages
if (self.messagesVC == nil)
{
self.messagesVC = [[MessagesViewController alloc] init];
[self.messagesVC setFrame:CGRectMake(0, 0, 320, self.containerScrollView.frame.size.height)];
}
[personScrollView addSubview:self.messagesVC.view];
// Info
if (self.infoVC == nil)
{
self.infoVC = [[InfoViewController alloc] init];
[self.infoVC setFrame:CGRectMake(320, 0, 320, self.containerScrollView.frame.size.height)];
}
[personScrollView addSubview:self.infoVC.view];
}
[self.containerScrollView setContentSize:CGSizeMake(320*3, self.containerScrollView.frame.size.height)];
The problem is that the two view controllers (messages and info) only get added once, and to the last personScrollView of containerScrollView.
How to get the view controllers added to all of my personScrollViews? Something wrong with the property declaration?
I have read something about this abusing view controllers, but this is the only solution. There is really a lot of code in the two view controllers and I can't add it to my rootviewcontroller.
The problem is with your understanding of the difference between view controllers and views. You need to read up on Creating Custom Container View Controllers.
Apple doc says:
Views can have only one superview. If view already has a superview and that view is not the receiver, this method removes the previous superview before making the receiver its new superview.
You create your controllers once, but you want to add theirs views three times, to three different parent views. You can't do that.
I ended up creating multiple instances of my view controllers and storing them in an array. Not a great solution, but the best I could find.
#property (strong, nonatomic) MessagesViewController *messagesVC1;
#property (strong, nonatomic) MessagesViewController *messagesVC2;
#property (strong, nonatomic) MessagesViewController *messagesVC3;
#property (strong, nonatomic) MessagesViewController *messagesVC4;
#property (strong, nonatomic) MessagesViewController *messagesVC5;
#property (strong, nonatomic) MessagesViewController *messagesVC6;
self.messagesVC1 = [[MessagesViewController alloc] initWithData:data];
self.messagesVC2 = [[MessagesViewController alloc] initWithData:data];
self.messagesVC3 = [[MessagesViewController alloc] initWithData:data];
self.messagesVC4 = [[MessagesViewController alloc] initWithData:data];
self.messagesVC5 = [[MessagesViewController alloc] initWithData:data];
self.messagesVC6 = [[MessagesViewController alloc] initWithData:data];
self.messagesVCArray = #[self.messagesVC1, self.messagesVC2, self.messagesVC3, self.messagesVC4, self.messagesVC5, self.messagesVC6];
MessagesViewController *messagesVC = [self.messagesVCArray objectAtIndex:i];
[messagesVC setFrame:CGRectMake(0, 0, 320, leagueScrollView.frame.size.height)];
[leagueScrollView addSubview:messagesVC.view];