So I have a picker that pops up instead of the keyboard, however it does not change values when you scroll to different points on the picker. I test this by having an alert show what age was selected, and it never changes from the first option. I would think the alert is broken, but the blue selector outline over the currently selected option in the picker is not showing up either. Here is the code for both the picker and the alert:
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = [[NSArray alloc] initWithObjects:#"18-29",#"30-39",#"40-49",#"50-59",#"60+",nil];
self.pickerData = array;
}
-(IBAction)UITextFieldEditingDidBegin
{
UIPickerView *picker = [[UIPickerView alloc]
initWithFrame:CGRectMake(0, 244, 320, 270)];
picker.delegate = self;
picker.dataSource = self;
[self.view addSubview:picker];
[picker release];
}
-(IBAction)donePressed
{
NSInteger row = [agePicker selectedRowInComponent:0];
NSString *selected = [pickerData objectAtIndex:row];
NSString *title = [[NSString alloc] initWithFormat:
#"You selected %#!", selected];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message : #"Thank you for choosing."
delegate:nil
cancelButtonTitle :#"Okay!"
otherButtonTitles :nil];
[alert show];
[agePicker resignFirstResponder];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [pickerData count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
return[pickerData objectAtIndex:row];
}
Edit,
to help dismiss your picker,
make it an instance var, declare your picker in the interface,
MyClass.h
#interface MyClass:UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>{
UIPickerView *picker
}
MyClass.m
#interface MyClass()
property (nonatomic, retain) *selectedVal; //make it a NSString
#end
-(IBAction)UITextFieldEditingDidBegin
{
picker = [[UIPickerView alloc]
initWithFrame:CGRectMake(0, 244, 320, 270)];
picker.delegate = self;
picker.dataSource = self;
[self.view addSubview:picker];
//[picker release]; //Place your picker release in the dealloc method
}
You have to implement the delegate for the picker,
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.selectedVal = [pickerData objectAtIndex:row]
NSLog(#"Selected option: %#. ", self.selectedVal );
}
Then on your done button, you have the selected val in your property for use
-(IBAction)donePressed
{
NSString *title = [[NSString alloc] initWithFormat:
#"You selected %#!", self.selectedVal];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message : #"Thank you for choosing."
delegate:nil
cancelButtonTitle :#"Okay!"
otherButtonTitles :nil];
[alert show];
[alert release]; //I noticed you release the picker, so not using ARC, so release alert!!
[picker resignFirstResponder];
//after done, remove the picker from the view
[picker removeFromSuperview];
}
Related
My below code working fine in below iOS 7
I am trying to add picker view in alert that works fine in below ios7 version But in ios 7 it show white alert without picker view.
-(void)showPinPickerAlert
{
numberarr = [[NSMutableArray alloc]initWithObjects:#"0",#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9", nil];
UIAlertView *alert =[[UIAlertView alloc]initWithTitle:#"Enter Pin To Change Track me Option" message:#"\n\n\n\n\n\n\n" delegate:self cancelButtonTitle:#"Verify" otherButtonTitles:nil];
UIPickerView *picker=[[UIPickerView alloc]initWithFrame:CGRectMake(25, 30, 230, 60) ];
picker.dataSource=self;
picker.delegate=self;
// picker.backgroundColor=[UIColor blueColor];
picker.showsSelectionIndicator = YES;
// picker.autoresizingMask = UIViewAutoresizingFlexibleHeight;
picker.transform = CGAffineTransformMakeScale(0.6, 0.6);
alert.tag=100;
// picker.transform = CGAffineTransformMakeScale(1, 0.2);
[alert addSubview:picker];
[alert show];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 4;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
strPin=[[NSString stringWithFormat:#"%i%i%i%i",[pickerView selectedRowInComponent:0],[pickerView selectedRowInComponent:1],[pickerView selectedRowInComponent:2],[pickerView selectedRowInComponent:3]]mutableCopy];
NSLog(#"strPin=%#",strPin);
// mlabel.text= [arrayNo objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [numberarr count];
}
**//code try to change color of picker text and background thats work fine in below ios7 but in iOS 7 still shows white screen**
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *label = (UILabel*) view;
if (label == nil)
{
label = [[UILabel alloc] init];
}
//[label setText:#"Whatever"];
// This part just colorizes everything, since you asked about that.
[label setTextColor:[UIColor whiteColor]];
[label setBackgroundColor:[UIColor blackColor]];
CGSize rowSize = [pickerView rowSizeForComponent:component];
CGRect labelRect = CGRectMake (0, 0, rowSize.width, rowSize.height);
[label setFrame:labelRect];
return label;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
pickerView.backgroundColor=[UIColor blackColor];
return [numberarr objectAtIndex:row];
}
OutPut in below
Output in IOS 7
How to fix it?
Adding subviews to a UIAlertView is not supported anymore, starting in iOS7.
You should implement your own view and try to do it similar to the alert view, or like other person said, use a 3rd party alert view like this one:
https://github.com/wimagguc/ios-custom-alertview
Most of the following code is from pre ios7 stack overflow answers.
PickerPrompt.h
#import <UIKit/UIKit.h>
#interface PickerPrompt : UIAlertView <UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
{
UIPickerView *_pickerView;
NSMutableArray *_options;
}
#property (readonly) NSString *enteredText;
- (id)initWithTitle:(NSString *)title message:(NSString *)message options:(NSMutableArray*)options delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle okButtonTitle:(NSString *)okButtonTitle;
#end
pickerPrompt.m
#import "PickerPrompt.h"
#implementation PickerPrompt
#define VIEW_TAG 49
#define SUB_LABEL_TAG 52
#define LABEL_TAG 53
#define COMPONENT_WIDTH 250
#define LABEL_WIDTH 10
#synthesize enteredText;
- (id)initWithTitle:(NSString *)title message:(NSString *)message options:(NSMutableArray*)options delegate:(id)delegate cancelButtonTitle:(NSString *)cancelButtonTitle okButtonTitle:(NSString *)okayButtonTitle
{
if (self = [super initWithTitle:title message:message delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:okayButtonTitle, nil])
{
_options = options;
_pickerView = [[UIPickerView alloc] init];
[_pickerView sizeToFit];
[_pickerView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)];
[_pickerView setDelegate:self];
[_pickerView setDataSource:self];
[_pickerView setShowsSelectionIndicator:TRUE];
// Change from pre iOS 7
[self setAlertViewStyle:UIAlertViewStylePlainTextInput];
[[self textFieldAtIndex:0] setDelegate:self];
[[self textFieldAtIndex:0] setInputView:_pickerView];
[[self textFieldAtIndex:0] becomeFirstResponder];
}
return self;
}
#pragma mark -
#pragma mark Picker delegate
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView == _pickerView) {
return [_options count];
}
return [_options count];
}
- (UIView *)labelCellWithWidth:(CGFloat)width rightOffset:(CGFloat)offset {
// Create a new view that contains a label offset from the right.
CGRect frame = CGRectMake(0.0, 0.0, width, 32.0);
UIView *view = [[[UIView alloc] initWithFrame:frame] autorelease];
view.tag = VIEW_TAG;
frame.size.width = width - offset;
UILabel *subLabel = [[UILabel alloc] initWithFrame:frame];
subLabel.textAlignment = UITextAlignmentRight;
subLabel.backgroundColor = [UIColor clearColor];
subLabel.font = [UIFont systemFontOfSize:24.0];
subLabel.userInteractionEnabled = NO;
subLabel.tag = SUB_LABEL_TAG;
[view addSubview:subLabel];
[subLabel release];
return view;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSString *fullString = [[textField text] stringByAppendingString:string];
for (NSString* object in _options) {
if ([object isEqualToString:fullString]) {
return YES;
}
}
return NO;
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UIView *returnView = nil;
if ((view.tag == VIEW_TAG) || (view.tag == LABEL_TAG)) {
returnView = view;
}
else {
returnView = [self labelCellWithWidth:COMPONENT_WIDTH rightOffset:LABEL_WIDTH];
}
// The text shown in the component is just the number of the component.
NSString *text = [_options objectAtIndex:row];
// Where to set the text in depends on what sort of view it is.
UILabel *theLabel = nil;
if (returnView.tag == VIEW_TAG) {
theLabel = (UILabel *)[returnView viewWithTag:SUB_LABEL_TAG];
}
else {
theLabel = (UILabel *)returnView;
}
theLabel.text = text;
return returnView;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
return COMPONENT_WIDTH;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
[[self textFieldAtIndex:0] setText:[_options objectAtIndex:row]];
}
- (NSString *)enteredText
{
return [[self textFieldAtIndex:0] text];
}
#end
How to use (called from an alert view delegate):
PickerPrompt *prompt = [PickerPrompt alloc];
NSMutableArray *options = [[NSMutableArray alloc] initWithObjects:#"option 1", #"option 2", nil];
prompt = [prompt initWithTitle:#"Select Option" message:#"Select Option" options:options delegate:self cancelButtonTitle:#"Cancel" okButtonTitle:#"Okay"];
[prompt show];
[prompt release];
This is the code:
#interface CreateAccountViewController : UIViewController<UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate>
{
UIToolbar *keyboardToolbar;
NSDate *birthdate;
UIActionSheet *dateSheet;
}
#property(strong, nonatomic) IBOutlet UITextField *txtFirstName;
#property(strong, nonatomic) IBOutlet UITextField *txtLastName;
#property(strong, nonatomic) IBOutlet UITextField *txtGender;
#property(strong, nonatomic) IBOutlet UITextField *txtBirthdate;
#property(strong, nonatomic) IBOutlet UITextField *txtEmail;
-(void)resignKeyboard:(id)sender;
-(void)gotoPreviousField:(id)sender;
-(void)gotoNextField:(id)sender;
-(void)setBirth;
-(void)dismissDateSet;
-(void)gotoPreviousBirthdate;
-(void)gotoNextBirthdate;
#end
#implementation CreateAccountViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[[[keyboardToolbar items] objectAtIndex:0] setEnabled:YES];
[[[keyboardToolbar items] objectAtIndex:1] setEnabled:YES];
if([textField isEqual:self.txtFirstName])
{
[[[keyboardToolbar items] objectAtIndex:0] setEnabled:NO];
}
else if([textField isEqual:self.txtEmail])
{
[[[keyboardToolbar items] objectAtIndex:0] setEnabled:NO];
}
}
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
if([textField isEqual:self.txtBirthdate])
{
[self setBirth];
return NO;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view
if(keyboardToolbar==nil)
{
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
UIBarButtonItem *btnPrevious = [[UIBarButtonItem alloc] initWithTitle:#"Previous" style:UIBarButtonItemStyleBordered target:self action:#selector(gotoPreviousField:)];
UIBarButtonItem *btnNext = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleBordered target:self action:#selector(gotoNextField:)];
UIBarButtonItem *btnExtraSpace= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *btnDone=[[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(resignKeyboard:)];
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects:btnPrevious, btnNext, btnExtraSpace, btnDone, nil]];
}
}
-(void) resignKeyboard:(id)sender
{
if([self.txtFirstName isFirstResponder])
{
[self.txtFirstName resignFirstResponder];
}
else if([self.txtLastName isFirstResponder])
{
[self.txtLastName resignFirstResponder];
}
else if([self.txtGender isFirstResponder])
{
[self.txtGender resignFirstResponder];
}
else if([self.txtBirthdate isFirstResponder])
{
[self.txtBirthdate resignFirstResponder];
}
else if([self.txtEmail isFirstResponder])
{
[self.txtEmail resignFirstResponder];
}
}
-(void) gotoPreviousField:(id)sender
{
if([self.txtFirstName isFirstResponder])
{
[self.txtEmail becomeFirstResponder];
}
else if([self.txtLastName isFirstResponder])
{
[self.txtFirstName becomeFirstResponder];
}
else if([self.txtGender isFirstResponder])
{
[self.txtLastName becomeFirstResponder];
}
else if([self.txtEmail isFirstResponder])
{
[self.txtBirthdate becomeFirstResponder];
}
}
-(void)gotoNextField:(id)sender
{
if([self.txtFirstName isFirstResponder])
{
[self.txtLastName becomeFirstResponder];
}
else if([self.txtLastName isFirstResponder])
{
[self.txtGender becomeFirstResponder];
}
else if([self.txtGender isFirstResponder])
{
[self.txtBirthdate becomeFirstResponder];
}
else if([self.txtEmail isFirstResponder])
{
[self.txtFirstName becomeFirstResponder];
}
}
-(void)setBirth
{
dateSheet=[[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[dateSheet setActionSheetStyle:UIActionSheetStyleDefault];
CGRect pickerFrame=CGRectMake(0, 44, 0, 0);
UIDatePicker *birthDayPicker=[[UIDatePicker alloc] initWithFrame:pickerFrame];
[birthDayPicker setDatePickerMode:UIDatePickerModeDate];
[dateSheet addSubview:birthDayPicker];
UIToolbar *birthDayToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, dateSheet.bounds.size.width, 44)];
[birthDayToolbar setBarStyle:UIBarStyleBlackTranslucent];
[birthDayToolbar sizeToFit];
UIBarButtonItem *btnPrevious = [[UIBarButtonItem alloc] initWithTitle:#"Previous" style:UIBarButtonItemStyleBordered target:self action:#selector(gotoPreviousBirthdate:)];
UIBarButtonItem *btnNext = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleBordered target:self action:#selector(gotoNextBirthdate:)];
UIBarButtonItem *btnExtraSpace= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *btnDone=[[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(dismissDateSet:)];
[birthDayToolbar setItems:[[NSArray alloc] initWithObjects:btnPrevious, btnNext, btnExtraSpace, btnDone, nil]];
[dateSheet addSubview:birthDayToolbar];
[dateSheet showInView:self.view];
[dateSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
-(void)dismissDateSet
{
NSArray *listOfViews = [dateSheet subviews];
for(UIView *subView in listOfViews)
{
if([subView isKindOfClass:[UIDatePicker class]])
{
NSDateFormatter *dateFormatter=[[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
self.txtBirthdate.text=[dateFormatter stringFromDate:[(UIDatePicker*)subView date]];
}
}
}
-(void)gotoPreviousBirthdate
{
[self dismissDateSet];
[self.txtGender becomeFirstResponder];
}
-(void)gotoNextBirthdate
{
[self dismissDateSet];
[self.txtEmail becomeFirstResponder];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 5;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CreateCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UITextField *textField = [[UITextField alloc] init];
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.clearButtonMode=UITextFieldViewModeWhileEditing;
textField.delegate=self;
CGRect aRect=CGRectMake(10, 10.f, CGRectGetWidth(cell.bounds)-40.f, 30.f );
textField.frame = aRect;
if(indexPath.row==0)
{
textField.placeholder = #"First name";
self.txtFirstName=textField;
}
else if(indexPath.row==1)
{
textField.placeholder = #"Last name";
self.txtLastName=textField;
}
else if(indexPath.row==2)
{
textField.placeholder = #"Gender";
self.txtGender=textField;
}
else if(indexPath.row==3)
{
textField.placeholder = #"Date of birth";
self.txtBirthdate=textField;
}
else
{
textField.placeholder = #"Email";
self.txtEmail=textField;
}
[cell.contentView addSubview:textField];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
textField.inputAccessoryView=keyboardToolbar;
return cell;
}
#end
If i press the Previous button from the date picker toolbar i get this exception:
[CreateAccountViewController gotoPreviousBirthdate:]: unrecognized selector sent to instance
If i press the Next button from the date picker toolbar i get this exception:
[CreateAccountViewController gotoNextBirthdate:]: unrecognized selector sent to instance
If i press the Done button from the date picker toolbar i get this exception:
[CreateAccountViewController dismissDateSet:]: unrecognized selector sent to instance
It seems that i am making the same mistake 3 times but i can't quite figure out what is that.
Thanks
Your setting the target selector to be:
#selector(gotoPreviousBirthdate:)
But you declare it as:
-(void)gotoPreviousBirthdate;
Remove the : in the selector as #selector(gotoPreviousBirthdate) since you're not taking an argument, or change the declaration to be -(void)gotoPreviousBirthday:(id)sender.
Then repeat for the other two.
You are calling the methods as if they are class methods, but they are declared as instance methods in your interface. Also the invocation of the selector is incorrect.
Create an instance of the class first:
CreateAccountViewController *vc = [[CreateAccountViewController alloc] init]; //Something like this
Then you can call the instance methods:
[vc gotoPreviousBirthday]; //Note no trailing colon!
Or, if you declared the method as
+(void)gotoPreviousBirthdate;
note the + in the signature - then you could call the method as your code shows.
This is a pretty fundamental concept in Objective-C so I would recommend you read the documentation first. Apple Objective-C Primer
Here's a simplified code, with a view controller with just a text field I also updated the title to reflect the newer issue.
When run, I click the text field and it brings up the picker view, and I'm able to click a value on the picker view and it shows up on the text field. I'm able to dismiss the picker view now when I press the Done button on the navigation bar. But now when I click the text field a second time, I don't get the picker view to pop up a second time.
import
#interface MyPickerViewViewController : UIViewController <UIPickerViewDelegate,
UIPickerViewDataSource,
UITextFieldDelegate>
#end
#interface MyPickerViewViewController () {
UIPickerView *_pv;
NSArray *_array;
IBOutlet __weak UITextField *_tf;
}
#end
#implementation MyPickerViewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_array = [NSArray arrayWithObjects:#"One", #"Two", #"Three", nil];
// Do any additional setup after loading the view, typically from a nib.
_pv = [[UIPickerView alloc] initWithFrame:CGRectZero];
_pv.dataSource = self;
_pv.delegate = self;
_tf.inputView = _pv;
UIToolbar* mypickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 56)];
mypickerToolbar.barStyle = UIBarStyleBlackOpaque;
[mypickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDoneClicked:)];
[barItems addObject:doneBtn];
[mypickerToolbar setItems:barItems animated:YES];
_tf.inputAccessoryView = mypickerToolbar;
_tf.delegate = self;
}
- (void)pickerDoneClicked:(id)sender
{
[_pv removeFromSuperview];
[_tf.inputView removeFromSuperview];
[_tf.inputAccessoryView removeFromSuperview];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Added this method and now the picker view comes up every time I
// click on the text field, even after I dismiss it. However, the
// picker view is in wrong place, so I just have to adjust the
// CGRect assigned to it.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[self.view addSubview:_tf.inputAccessoryView];
[self.view addSubview:_tf.inputView];
return NO;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
NSLog(#"Hello there");
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[textField resignFirstResponder];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)selectRow:(NSInteger)row inComponent:(NSInteger)component animated:(BOOL)animated
{
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:( NSInteger)component
{
return [_array objectAtIndex:row];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return _array.count;
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
_tf.text = [_array objectAtIndex:row];
}
#end
I think you missed this:
[datePicker removeFromSuperview];
[pickerView removeFromSuperview];
You may try:
[self.view endEditing:YES];
in your action method
See update with this addition
// Added this method and now the picker view comes up every time I
// click on the text field, even after I dismiss it. However, the
// picker view is in wrong place, so I just have to adjust the
// CGRect assigned to it.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[self.view addSubview:_tf.inputAccessoryView];
[self.view addSubview:_tf.inputView];
return NO;
}
Here is an adjusted CGRect for the pickerview and tool bar that worked. I was wondering though if there is a default height for a pickerview?
- (void)viewDidLoad
{
[super viewDidLoad];
_array = [NSArray arrayWithObjects:#"One", #"Two", #"Three", #"Four", nil];
// Do any additional setup after loading the view, typically from a nib.
CGRect viewRect = [[UIScreen mainScreen] bounds];
CGFloat pvHeight = 235;
CGFloat pvYpos = viewRect.size.height - pvHeight;
CGRect pvRect = CGRectMake(viewRect.origin.x, pvYpos, viewRect.size.width, pvHeight);
_pv = [[UIPickerView alloc] initWithFrame:pvRect];
_pv.dataSource = self;
_pv.delegate = self;
_tf.inputView = _pv;
CGFloat tbYpos = pvYpos-44;
UIToolbar* mypickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, tbYpos, viewRect.size.width, 44)];
mypickerToolbar.barStyle = UIBarStyleBlackOpaque;
[mypickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDoneClicked:)];
[barItems addObject:doneBtn];
[mypickerToolbar setItems:barItems animated:YES];
_tf.inputAccessoryView = mypickerToolbar;
_tf.delegate = self;
}
I'm having an issue with my iOS app freezing whenever I trigger a UIActionSheet with a UIPickerView inside it. The picker wheel scrolls fine until I try to hit the "Done" button on the UIActionSheet, at which point the UI freezes. However, XCode isn't registering any kind of crash in the program, so I'm pretty confused.
Has anyone else run into this problem before? How can I solve it?
I never Face this type of problem.I think this one is hekp you to solve your problem. I used the PickerView in same way
UIActionSheet *actionSheet;
NSString *pickerType;
- (void)createActionSheet {
if (actionSheet == nil) {
// setup actionsheet to contain the UIPicker
actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
[flexSpace release];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone:)];
[barItems addObject:doneBtn];
[doneBtn release];
[pickerToolbar setItems:barItems animated:YES];
[barItems release];
[actionSheet addSubview:pickerToolbar];
[pickerToolbar release];
[actionSheet showInView:self.view];
[actionSheet setBounds:CGRectMake(0,0,320, 464)];
}
}
-(IBAction)BtnPressed:(id)sender
{
[self createActionSheet];
pickerType = #"picker";
select = NO;
UIPickerView *chPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0.0, 44.0, 0.0, 0.0)];
chPicker.dataSource = self;
chPicker.delegate = self;
chPicker.showsSelectionIndicator = YES;
[actionSheet addSubview:chPicker];
sessoTxt.text = [sessoArray objectAtIndex:0];
[chPicker release];
}
#pragma mark UIPickerViewDelegate Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
int count;
if ([pickerType isEqualToString:#"picker"])
count = [array count];
return count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *string;
if ([pickerType isEqualToString:#"picker"])
string = [array objectAtIndex:row];
return string;
}
// Set the width of the component inside the picker
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
return 300;
}
// Item picked
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
select = YES;
if ([pickerType isEqualToString:#"picker"])
{
Txt.text = [array objectAtIndex:row];
}
}
- (void)pickerDone:(id)sender
{
if(select == NO)
{
if ([pickerType isEqualToString:#"picker"])
{
Txt.text = [array objectAtIndex:0];
}
}
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
[actionSheet release];
actionSheet = nil;
}
}
in one of my view controllers I want to use multiple pickers.
Header file:
#interface MyTableController : TTTableViewController <UIActionSheetDelegate, UIPickerViewDataSource, UIPickerViewDelegate>{
IBOutlet UIPickerView *picker1;
IBOutlet UIPickerView *picker2;
NSMutableArray *list1;
NSMutableArray *list2;
}
#property(nonatomic,retain) UIPickerView *picker1, *picker2;
-(IBAction)togglePickerView1;
-(IBAction)togglePickerView2;
#end
Implementation file:
#implementation MyTableController
#synthesize picker1, picker2;
int row_index1 = 0;
int row_index2 = 0;
- (void)locationPicker:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent: (NSInteger)component
{
if([pickerView isEqual: picker1]){
row_index1 = row;
}
if([pickerView isEqual: picker2]){
row_index2 = row;
}
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
if([pickerView isEqual: picker1]){
return 1;
}
if([pickerView isEqual: picker2]){
return 1;
}
return 0;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if([pickerView isEqual: picker1]){
return [list1 count];
}
if([pickerView isEqual: picker2]){
return [list2 count];
}
return 0;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent: (NSInteger)component{
return [list objectAtIndex:row];
if([pickerView isEqual: picker1]){
return [list1 objectAtIndex:row];
}
if([pickerView isEqual: picker2]){
return [list2 objectAtIndex:row];
}
return nil;
}
-(void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
}
- (void)willPresentActionSheet:(UIActionSheet *)actionSheet {
if (actionSheet.tag == 111) {
picker1 = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 40, 320, 216)];
picker1.showsSelectionIndicator = YES;
picker1.dataSource = self;
picker1.delegate = self;
//Add picker to action sheet
[actionSheet addSubview:picker1];
[picker1 release];
}else if(actionSheet.tag == 222){
picker2 = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 40, 320, 216)];
picker2.showsSelectionIndicator = YES;
picker2.dataSource = self;
picker2.delegate = self;
//Add picker to action sheet
[actionSheet addSubview:picker2];
[picker2 release];
}
//Gets an array af all of the subviews of our actionSheet
NSArray *subviews = [actionSheet subviews];
[[subviews objectAtIndex:1] setFrame:CGRectMake(20, 266, 280, 46)];
[[subviews objectAtIndex:2] setFrame:CGRectMake(20, 317, 280, 46)];
}
-(IBAction)togglePickerView1{
UIActionSheet *asheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(#"FLT", nil) delegate:self cancelButtonTitle:NSLocalizedString(#"CANCEL", nil) destructiveButtonTitle:nil otherButtonTitles:NSLocalizedString(#"PICK", nil), nil];
[asheet setTag:111];
[asheet showInView:[self.view superview]]; //note: in most cases this would be just self.view, but because I was doing this in a tabBar Application, I use the superview.
[asheet setFrame:CGRectMake(0, 117, 320, 383)];
[asheet release];
}
-(IBAction)togglePickerView2{
//...
[asheet setTag:222];
//...
}
- (void)loadView {
[super loadView];
}
-(void)viewDidLoad{
UIBarButtonItem *item1 = [[UIBarButtonItem alloc] initWithTitle:#"Button1" style:UIBarButtonItemStyleBordered target:self action:#selector(togglePickerView1)];
UIBarButtonItem *item2 = [[UIBarButtonItem alloc] initWithTitle:#"Button2" style:UIBarButtonItemStyleBordered target:self action:#selector(togglePickerView2)];
NSArray *myToolbarItems = [[NSArray alloc] initWithObjects: item1, item2, nil];
[self setToolbarItems: myToolbarItems];
[myToolbarItems release];
list1 = [[NSMutableArray alloc] init];
[list1 addObject:#"--"];
[list1 addObject:#"Test1"];
list2 = [[NSMutableArray alloc] init];
[list2 addObject:#"--"];
[list2 addObject:#"Test2"];
}
#end
My problem is that no matter which button I hit, it is always the picker1 that is triggered. Any ideas where the problem is?
You are successfully creating two different pickers, and showing the correct one each time.
The problem is, each picker has the same data in it.
The first line in your data source titleForRow... method is this:
return [list objectAtIndex:row];
This ends execution of your data source method by returning a value, so both pickers will always show the same data, regardless of the rest of your code. list isn't declared anywhere in your code above so I'm not sure what you are actually seeing on the screen.
I have built a sample project using your code above and confirmed that this is the issue. Removing that line gives you two different pickers, with the different content in each one.