Why will my UIPickerView only respond when not in a superview? - ios

I'm adding a UIPickerView to my view when a UILabel is tapped. When I was adding the UIPickerView by itself, it worked fine:
static const CGFloat HMCMeasurePickerHeight = 200.0;
CGRect measurePickerFrame = CGRectMake(0.0,
CGRectGetHeight(self.view.window.bounds) - HMCMeasurePickerHeight,
CGRectGetWidth(self.view.window.bounds),
HMCMeasurePickerHeight);
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:measurePickerFrame];
picker.dataSource = self;
picker.delegate = self;
picker.showsSelectionIndicator = YES;
[self.view addSubview:picker];
However, I wanted a toolbar with it, so I wrapped it in a UIView:
static const CGFloat HMCMeasurePickerAccessoryHeight = 44.0;
static const CGFloat HMCMeasurePickerHeight = 200.0;
CGRect measurePickerSuperviewFrame = CGRectMake(0.0,
CGRectGetHeight(self.view.window.bounds) - HMCMeasurePickerHeight - HMCMeasurePickerAccessoryHeight,
CGRectGetWidth(self.view.window.bounds),
HMCMeasurePickerAccessoryHeight);
UIView *measurePicker = [[UIView alloc] initWithFrame:measurePickerSuperviewFrame];
CGRect measurePickerAccessoryFrame = CGRectMake(0.0,
0.0,
CGRectGetWidth(self.view.window.bounds),
HMCMeasurePickerAccessoryHeight);
UIToolbar *measurePickerAccessory = [[UIToolbar alloc] initWithFrame:measurePickerAccessoryFrame];
measurePickerAccessory.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *rightAlignSpacer = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(dismissMeasurePicker:)];
measurePickerAccessory.items = #[rightAlignSpacer, doneButton];
[measurePicker addSubview:measurePickerAccessory];
CGRect measurePickerFrame = CGRectMake(0.0,
HMCMeasurePickerAccessoryHeight,
CGRectGetWidth(self.view.window.bounds),
HMCMeasurePickerHeight);
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:measurePickerFrame];
picker.dataSource = self;
picker.delegate = self;
picker.showsSelectionIndicator = YES;
[measurePicker addSubview:picker];
[self.view addSubview:measurePicker];
Now, when I attempt to scroll the UIPickerView nothing happens. I can successfully tap the Done button I added, it's just the UIPickerView that is not responding. I tried setting picker.userInteractionEnabled = YES but that had no effect (given the first example it seems like it defaults to YES).

I guess the issue is that frame size of
measurePicker is smaller than picker. I
would suggest you to check on this line.
NSLog the final frame of measurePicker
and see what width and height it
returns.

Related

Dynamically created UIBarButtonItem doesn't trigger on tap

I've got a UIPickerView that has a UIToolbar attached to it on the parent view's load with this code:
- (void)viewDidLoad {
[super viewDidLoad];
self.itemSortPicker.hidden = false;
pickerData = #[#"Name",#"Item Level",#"Crafting Level",#"Profit",#"Profit Percentage",#"Sell Price",#"Buy Price",#"Supply",#"Demand",#"Rarity"];
self.itemSortPicker.dataSource = self;
self.itemSortPicker.delegate = self;
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleDefault;
[pickerToolbar sizeToFit];
[pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(pickerCancel)];
[barItems addObject:cancelBtn];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone)];
[barItems addObject:doneBtn];
[pickerToolbar setItems:barItems animated:YES];
CGRect pickerRect = self.itemSortPicker.bounds;
self.itemSortPicker.bounds = pickerRect;
self.itemSortPicker.frame = CGRectMake(0, 44, 320, 216);
[self.itemSortPicker addSubview:pickerToolbar];
}
Now the problem is, when I tap on either the 'done' or 'cancel' buttons, the associated method doesn't trigger. The method doesn't take any parameters and just does an NSLog action. The PickerView isn't taking focus from the bar because when I tap and drag on the buttons, the PickerView doesn't change.
The problem is that the UIToolbar isn't entirely inside the frame of the UIPickerView. As your code is written, although UIToolbar is a subview of UIPickerView, the toolbar is -pickerToolbar.bounds.size.height above the UIPickerView:
[pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];
so you're unable to interact with its buttons because it's hanging off the edge of its superview's frame. For example, if you changed the pickerToolbar frame like so:
[pickerToolbar setFrame:CGRectMake(0, 0, 320, 44)];
you should be able to interact with it.
If you need this specific placement -pickerToolbar.bounds.size.height above the UIPickerView though, I suggest not adding it as a subview to UIPickerView and placing it appropriately as a subview to UIPickerView's superview instead. In general, if you need to interact with a subview it needs to be entirely within its superview's frame.
Edit: In this case, if you're going to instead add the toolbar to the superview, like so:
[self.view addSubview:pickerToolbar];
I suggest trying out this frame to maintain your original placement:
[pickerToolbar setFrame:CGRectMake(self.itemSortPicker.frame.origin.x, self.itemSortPicker.frame.origin.y - pickerToolbar.bounds.size.height, 320, 44)];
(To calculate this new frame, I've added the UIPicker's x and y origin values to the frame's x and y to adjust for the change in the view's coordinate system.)
I'm not sure of wether the problem is because of the button or the toolbar itself nor the pickerview but a better way of doing this is to do it all programmatically and you have to remove the pickerview from the view:
- (void)viewDidLoad {
[super viewDidLoad];
pickerData = #[#"Name",#"Item Level",#"Crafting Level",#"Profit",#"Profit Percentage",#"Sell Price",#"Buy Price",#"Supply",#"Demand",#"Rarity"];
UIPickerView *itemSortPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 162)];
itemSortPicker.dataSource = self;
itemSortPicker.delegate = self;
itemSortPicker.showsSelectionIndicator = YES;
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(pickerCancel)];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone)];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[pickerToolbar setBarStyle:UIBarStyleDefault];
[pickerToolbar sizeToFit];
[toolBar setItems:#[cancelBtn,flexSpace,doneBtn]];
BlaBlaTextField.delegate = self;
BlaBlaTextField.inputView = itemSortPicker;
BlaBlaTextField.inputAccessoryView = pickerToolbar;
}
And not to forget your pickerCancel and pickerDone functions, and of course the delegate methods of your itemSortPicker.
I hope that solves your problem.

UIBarButton not showing in UINavigationBar

I need help with my UIBarButtonItem not showing in my UINavigationBar.
I am trying to put a UINavigationBar in my third view. As I am not quite sure if UINavigationController will work, I decided to manually initialized a UINavigationBar, together with its UINavigationItem initwithTitle. The code works, but my problem is adding a UIBarButtonItem because it won't show in the UINavigationBar.
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
UINavigationItem *navigationItem = [[UINavigationItem alloc] initWithTitle:#"Title"];
[navigationBar pushNavigationItem:navigationItem animated:NO];
UIBarButtonItem *button = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(showPI:)];
self.navigationItem.rightBarButtonItem = button;
UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 44.0, self.view.frame.size.width, self.view.frame.size.height - navigationBar.frame.size.height) style:UITableViewStylePlain];
self.tableView = tableView;
[self.view addSubview:tableView];
[self.view addSubview:navigationBar];
[self showCurrencies];
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
I'm not sure what's missing.
In your case, you're creating your own navigationBar. Try not to alloc init your navigationItem, instead use
UINavigationBar *navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 44.0)];
UINavigationItem *item = [navigationBar.items lastObject];
Then set your created barbuttonItem to the item's rightBarButtonItem,
item.rightBarButtonItem = button;
It's works for me.

UIDatePicker not showing in right place on UITable

I have a UITableCell and on that cell i have a UITextBox, when the textbox is clicked instead of a keyboard being shown, a UIDatePicker is being displayed with the code below. But i am having trouble positioning the UIDatePicker. I need it to start from the very bottom of the page at at the moment it appears to start from the top of the table section where the textbox was pressed. The code fires when the user clicks the Preferred Date label. Any pointers? I have attached an image to show where it is currently rendering. Thanks.
- (IBAction)selectDateBegin:(id)sender {
//Disable Keyboard
[self.txtBookingDate resignFirstResponder];
//Disable Scrolling
[_tableForm setScrollEnabled:false];
if ([self.view viewWithTag:9]) {
return;
}
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-216-44, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-216, 320, 216);
UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds];
darkView.alpha = 0;
darkView.backgroundColor = [UIColor blackColor];
darkView.tag = 9;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissDatePicker:)] ;
[darkView addGestureRecognizer:tapGesture];
[self.view addSubview:darkView];
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] ;
datePicker.tag = 10;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)];
toolBar.tag = 11;
toolBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissDatePicker:)];
[toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
[self.view addSubview:toolBar];
[UIView beginAnimations:#"MoveIn" context:nil];
toolBar.frame = toolbarTargetFrame;
datePicker.frame = datePickerTargetFrame;
darkView.alpha = 0.5;
[UIView commitAnimations];
}
What I suggest you to do is replacing the inputView of your textField (the default is the keyboard) with this instruction:
UIDatePicker *datePicker = [[UIDatePicker alloc] init] ;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[preferredDateField setInputView:datePicker];
It is more appropriate and in compliance with Apple Human Interface Guideline
Don't do it that way. Create a date picker and set it as the inputView of your text field. Then the system will present it for you, in the right place, with the right animation, instead of the keyboard.

Can't click bar button on Tool bar?

In my iPad app, i add navigation bar and tool bar manually.
I also add scroll view and image view by coding.
My problem is i can see both navigation bar and tool bar.
I can click button on navigation bar.
But, i can't click bar button on tool bar.
How can i do it?
This is my code.
- (void)viewDidLoad
{
[super loadView];
self.view.backgroundColor = [UIColor grayColor];
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height)];
ScrollView.pagingEnabled = YES;
NSInteger numberOfViews = 4;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * self.view.frame.size.width;
// Create a UIImage to hold Info.png
UIImage *image1 = [UIImage imageNamed:#"Image-001.jpg"];
UIImage *image2 = [UIImage imageNamed:#"Image-002.jpg"];
UIImage *image3 = [UIImage imageNamed:#"Image-003.jpg"];
UIImage *image4 = [UIImage imageNamed:#"Image-004.jpg"];
NSArray *images = [[NSArray alloc] initWithObjects:image1,image2,image3,image4,nil];
UIImageView *ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin, 0, self.view.frame.size.width, self.view.frame.size.height-88)];
[ImageView setImage:[images objectAtIndex:i]];
[ScrollView addSubview:ImageView];
}
ScrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:ScrollView];
}
I dont Know what is your exact problem, Because your displayed code is not related to UIToolBar.
But Following code i added two UIBarButton with flexSpace.
you can add UIBarButton as you want
UIToolbar *Toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
Toolbar = UIBarStyleBlackTranslucent;
[Toolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
[flexSpace release];
UIBarButtonItem *btnCancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(Cancel)];
[barItems addObject:btnCancel];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(done)];
[barItems addObject:btnDone];
[Toolbar setItems:barItems animated:YES];
Following Method is call when tapped on bar Button
-(void)Cancel
{
// Write Code for Cancel Method
}
-(void)done
{
// Write Code for Done Method
}
This code might helpful in your own case.
Thanks :)
Thanks everybody. I can solve my problem.
I change my code.
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height)];
To this.
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height-88)];

Disable keyboard when

When the user clicks on a UITextField I am showing a UIDatePicker for the input with the code below. But when i do this the datepicker and the normal text keyboard show at the same time. How would i disable the keyboard from displaying?
- (IBAction)selectDateBegin:(id)sender {
if ([self.view viewWithTag:9]) {
return;
}
CGRect toolbarTargetFrame = CGRectMake(0, self.view.bounds.size.height-216-44, 320, 44);
CGRect datePickerTargetFrame = CGRectMake(0, self.view.bounds.size.height-216, 320, 216);
UIView *darkView = [[UIView alloc] initWithFrame:self.view.bounds];
darkView.alpha = 0;
darkView.backgroundColor = [UIColor blackColor];
darkView.tag = 9;
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(dismissDatePicker:)] ;
[darkView addGestureRecognizer:tapGesture];
[self.view addSubview:darkView];
UIDatePicker *datePicker = [[UIDatePicker alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height+44, 320, 216)] ;
datePicker.tag = 10;
[datePicker addTarget:self action:#selector(changeDate:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:datePicker];
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height, 320, 44)];
toolBar.tag = 11;
toolBar.barStyle = UIBarStyleBlackTranslucent;
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismissDatePicker:)];
[toolBar setItems:[NSArray arrayWithObjects:spacer, doneButton, nil]];
[self.view addSubview:toolBar];
[UIView beginAnimations:#"MoveIn" context:nil];
toolBar.frame = toolbarTargetFrame;
datePicker.frame = datePickerTargetFrame;
darkView.alpha = 0.5;
[UIView commitAnimations];}
-(void)textFieldDidBeginEditing:(UITextField *)sender
{
[self.textFieldName resignFirstResponder];
//
// Code ...continue,......for display DatePicker
//
}
Create a separate UIView for your datepicker (with navigation bar having OK and Cancel button) container and then assign it to textfield.inputView property. For more details refer UITextField Class Reference.
This will load your datepicker view instead of default keyboard.
You will find many more examples on net for the same.
Hope this is what you are looking for.

Resources