I have a weird bug which only happens in iPhone 6 simulator in Xcode 6. I have a generic component which extends UITextField and shows a pickerView as inputView at the bottom of screen.
If I use iPhone5 or iPhone5s to test my application, it's working as expected: inputView and inputAccessoryView is displaying correctly. But if I switch to iPhone 6 or Plus simulator, only inputAccessoryView is shown at bottom of screen, inputView is not showing.
Here is my code:
#interface DropDownTextField : UITextField
#property (strong,nonatomic) UIPickerView* pickerView;
#property (strong,nonatomic) UIToolbar *toolBar;
#property CGFloat originalFontSize;
#property (nonatomic) id<UIPickerViewDelegate> pickerDelegate;
#property (nonatomic) id<UIPickerViewDataSource> pickerDataSource;
- (CGFloat)requiredFontSize;
- (void)setDropdownMode:(BOOL)enabled;
#end
#implementation DropDownTextField
-(id)initWithCoder:(NSCoder *)aDecoder {
if(self = [super initWithCoder:aDecoder]) {
self.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
[self setFont:[UIFont mediumRegular]];
_originalFontSize = self.font.pointSize;
self.layer.borderWidth = 1.0f;
CGRect frame = [self frame];
// rightview dropdown arrow
UIImageView *dropDownImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, (frame.size.height-8)/2, 14.0f, 8.0f)];
UIImage *dropDownImage = [UIImage imageNamed:#"DisclosureDown"];
[dropDownImageView setImage:dropDownImage];
dropDownImageView.contentMode = UIViewContentModeScaleAspectFit;
UIView *dropDownView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 25.0f, frame.size.height)];
[dropDownView addSubview:dropDownImageView];
self.rightView = dropDownView;
self.rightViewMode = UITextFieldViewModeAlways;
[self.rightView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(becomeFirstResponder)]];
// picker view
_pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,216)];
_pickerView.showsSelectionIndicator = YES;
[_pickerView setBackgroundColor:[UIColor colorWithRed:245/255.0 green:245/255.0 blue:245/255.0 alpha:1.0f]];
self.inputView = _pickerView;
// picker view toolbar
_toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,SCREEN_WIDTH,44)];
[_toolBar setBackgroundColor:[UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1.0f]];
[_toolBar setBarStyle:UIBarStyleBlackTranslucent];
// to align button to the right
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] init];
[barButtonDone setTarget:self];
[barButtonDone setAction:#selector(changeSelectionFromLabel:)];
[barButtonDone setTitle:NSLocalizedString(#"ok", #"")];
[barButtonDone setTintColor:[UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1.0f]];
[barButtonDone setStyle:UIBarButtonItemStylePlain];
[barButtonDone setTitleTextAttributes:[UIFont pickerTitleTextAttributes] forState:UIControlStateNormal];
UIBarButtonItem *barButtonCancel = [[UIBarButtonItem alloc] init];
[barButtonCancel setTarget:self];
[barButtonCancel setAction:#selector(dismissPickerView:)];
[barButtonCancel setTitle:NSLocalizedString(#"cancel", #"")];
[barButtonCancel setTintColor:[UIColor colorWithRed:229/255.0 green:229/255.0 blue:229/255.0 alpha:1.0f]];
[barButtonCancel setStyle:UIBarButtonItemStylePlain];
[barButtonCancel setTitleTextAttributes:[UIFont pickerTitleTextAttributes] forState:UIControlStateNormal];
self.toolBar.items = [[NSArray alloc] initWithObjects:barButtonCancel,flex,barButtonDone,nil];
self.inputAccessoryView = _toolBar;
}
return self;
}
Does anybody come across such a problem? Any ideas to resolve?
PS: I've already tried clearing build directory, clean/rebuild project, stop/restart simulator and xcode approaches. Not working.
try to uncheck simulator -> hardware -> keyboard - > connect hardware keyboard
Related
I have written the following code in the viewDidLoad method:
categoryPickerView=[[UIPickerView alloc]init];
categoryPickerView.alpha = 0;
[self.view addSubview:categoryPickerView];
categoryPickerView.delegate=self;
categoryPickerView.tag=1;
and called this method to hide picker view
- (IBAction)hidePickerView:(id)sender {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.6];
CGAffineTransform transfrom = CGAffineTransformMakeTranslation(0, 200);
categoryPickerView.transform = transfrom;
categoryPickerView.alpha = categoryPickerView.alpha * (-1) + 1;
[UIView commitAnimations];
}
My problem is that I want to display a "Done" button on a picker view and the picker view should hide on button click.
You can use this code,
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered target:self action:#selector(changeDateFromLabel:)];
toolBar.items = #[barButtonDone];
barButtonDone.tintColor=[UIColor blackColor];
[pickerView addSubview:toolBar];
//(or)pickerView.inputAccessoryView = toolBar;
and set button action method for changeDateFromLabel:
-(void)changeDateFromLabel:(id)sender
{
[[your UI Element] resignFirstResponder];
}
You can create view and add toolbar with "Done" button and UIPickerView as subviews
- (void)createInputView {
CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width;
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 44)];
[toolBar setBarStyle:UIBarStyleDefault];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(doneClicked)];
toolBar.items = #[flex, barButtonDone];
barButtonDone.tintColor = [UIColor blackColor];
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, toolBar.frame.size.height, screenWidth, 200)];
picker.delegate = self;
picker.dataSource = self;
picker.showsSelectionIndicator = YES;
UIView *inputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, toolBar.frame.size.height + picker.frame.size.height)];
inputView.backgroundColor = [UIColor clearColor];
[inputView addSubview:picker];
[inputView addSubview:toolBar];
textField.inputView = inputView;
}
- (void)doneClicked {
[textField resignFirstResponder];
}
You need to use the UIToolbar as the accessory view:
Try with this:
#pragma mark - PickerView for Location Selection
- (UIPickerView *)locationsPicker {
if ( locationsPicker == nil ) {
locationsPicker = [[UIPickerView alloc] init];
locationsPicker.delegate = self;
locationsPicker.dataSource = self;
locationsPicker.showsSelectionIndicator = YES;
}
return locationsPicker;
}
- (UIToolbar *)accessoryView {
if ( accessoryView == nil ) {
accessoryView = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:
UIBarButtonSystemItemDone
target:self
action:#selector(onLocationSelection)];
[accessoryView setItems:[NSArray arrayWithObject:doneButton]];
}
return accessoryView;
}
- (void)onLocationSelection {
NSInteger row = [self.locationsPicker selectedRowInComponent:0];
if ( [Location isFirstResponder] ) {
NSLog(#"%#", [listOfLocations objectAtIndex:row]);
[Location resignFirstResponder];
}
}
Copy-pasteable solution!
This works in iOS 10 (and probably other versions too) I wrote this code on 9/4/2017.
I needed to combine other answers to get what I wanted, which was a Cancel button, Done button, and a picker view that would show/hide on the tap of a button. Ignore the fact that my screenshot only has one item in the picker.. I only have one item in my array. I've tested multiple items, it works fine.
Disclaimer! I have tested and used this code. I generalized the names in my example, so I apologize in advance if I missed one and they property names don't line up.
In order to have a pickerView that appears on the tap of a button, you need to create a dummyTextField (of type UITextField anywhere in your view controller. This is because UIPickerView's are designed to work with UITextFields. To mimic showing and hiding of the picker, your button taps need to call the dummyTextField's becomeFirstResponder and resignFirstResponder methods. (examples are below)
Step one
Create a custom data source class. MyObj is the class you want to have items show up in the picker for.
In .h:
#import <UIKit/UIKit.h>
#class myObj;
#interface PickerDataSource : NSObject <UIPickerViewDataSource, UIPickerViewDelegate>
#property (nonatomic, strong) MyObj *selectedObject;
#end
In .m:
#import "PickerDataSource.h"
#import "MyObj.h"
#implementation PickerDataSource
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.selectedObject = mySourceArray[row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return mySourceArray.count;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return ((MyObj *)mySourceArray[row]).myTitle;
}
- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
int sectionWidth = 300;
return sectionWidth;
}
#end
Step two In your view controller, import custom data source, delegate, and set properties: (You must include the text field delegate!)
#import "PickerDataSource.h"
#interface MyViewController () <UIPickerViewDelegate, UITextFieldDelegate>
#property (strong, nonatomic) PickerDataSource *pickerDataSource;
#property (strong, nonatomic) UIPickerView *picker;
#property (strong, nonatomic) UITextField *dummyTextField;
#end
Step three
In your viewDidLoad, call [self setupPicker]; (you'll create this method next)
Step four
Create setupPicker
- (void)setupPicker {
// init custom picker data source
self.pickerDataSource = [PickerDataSource new];
// init custom picker
self.picker = [UIPickerView new];
// set the picker's dataSource and delegate to be your custom data source
self.picker.dataSource = self.pickerDataSource;
self.picker.delegate = self.pickerDataSource;
self.picker.showsSelectionIndicator = YES;
// next step is to write this configure method getting called here
[self configurePickerSubviews];
// lastly, add the dummyTextField to your view.
[self.view addSubview:self.dummyTextField];
}
Step five
Create configurePickerSubviews
- (void)configurePickerSubviews {
// A UIPickerView must be added as an inputView to a UITextField in order to be displayed on button tap
// So you need to create a dummyTextField to do so.
self.dummyTextField = [UITextField new];
// Create a toolbar to add a done button
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,[UIScreen mainScreen].bounds.size.width,44)];
[toolBar setBarStyle:UIBarStyleDefault];
UIBarButtonItem *done = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStylePlain target:self action:#selector(locationPressed)];
// Create a flex space so that done button will be right aligned
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(dismissPicker)];
toolBar.items = #[cancel, flex, done];
done.tintColor = [UIColor blackColor];
[self.picker addSubview:toolBar];
// Create an input view to add picker + done button as subviews
UIView *inputView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, self.picker.frame.size.height + 44)];
[self.picker setFrame:CGRectMake(0, 0, inputView.frame.size.width, inputView.frame.size.height)];
inputView.backgroundColor = [UIColor clearColor];
[inputView addSubview:self.picker];
[inputView addSubview:toolBar];
// Set custom inputView as container for picker view
self.dummyTextField.inputView = inputView;
// Hiding the textfield will hide the picker
[self.dummyTextField setHidden:YES];
}
Step six
Configure the PickerDataSource so that it is fetching the data you want to display from your source array.
Step 7
Click Run!
The UIToolbar with the 'Done' button should be added to the inputAccessoryView of the view that becomes first responder. As the UIView class inherits from UIResponder, any view can potentially contain an inputView and inputAccessoryView. So instead of manually performing the animations programmatically, you could use the default animation behaviour that comes with the UIResponder's keyboard show/hide animation.
Subclass a UIView and override the inputView and inputAccessoryView properties and make them readwrite. In this example, I will subclass a UITableViewCell.
// FirstResponderTableViewCell.h
#interface FirstResponderTableViewCell : UITableViewCell
#property (readwrite, strong, nonatomic) UIView *inputView;
#property (readwrite, strong, nonatomic) UIView *inputAccessoryView;
#end
Override canBecomeFirstResponder in your subclass' implementation.
// FirstResponderTableViewCell.m
- (BOOL)canBecomeFirstResponder {
return YES;
}
In your view controller, create and assign the picker view and input accessory toolbar
// MyViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
UIPickerView *pickerView = [[UIPickerView alloc] init];
UIToolbar *accessoryToolbar = [UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
// Configure toolbar .....
// note: myFirstResponderTableViewCell is an IBOutlet to a static cell in storyboard of type FirstResponderTableViewCell
self.myFirstResponderTableViewCell.inputView = pickerView;
self.myFirstResponderTableViewCell.inputAccessoryView = accessoryToolbar;
}
Don't forget to assign first responder to the view when required (e.g. inside - tableView:didSelectRowAtIndexPath:)
[self.myFirstResponderTableViewCell becomeFirstResponder];
Hope this helps.
Reference: http://blog.swierczynski.net/2010/12/how-to-create-uipickerview-with-toolbar-above-it-in-ios/
Try this.
UIPickerView *cityPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
cityPicker.delegate = self;
cityPicker.dataSource = self;
[cityPicker setShowsSelectionIndicator:YES];
txtText.inputView = cityPicker;
// Create done button in UIPickerView
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];
txtText.inputAccessoryView = mypickerToolbar; // set the toolbar as input accessory view for uitextfield, not the pickerview.
http://technopote.com/how-to-make-multiple-uipickerview-in-a-single-view/
#import "ViewController.h"
#interface ViewController ()<UIPickerViewDelegate>
{
UIPickerView *myPickerView;
NSArray *namesArray ;
}
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
namesArray=[[NSArray alloc]initWithObjects:#"a",#"b", nil];
[self popoverWithInformation];
}
-(void)popoverWithInformation
{
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerToolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(pickerCancel:)];
[barItems addObject:cancelBtn];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone:)];
[barItems addObject:doneBtn];
[pickerToolbar setItems:barItems animated:YES];
myPickerView = [[UIPickerView alloc] init];
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
CGRect pickerRect = myPickerView.bounds;
myPickerView.bounds = pickerRect;
myPickerView.frame = CGRectMake(0, 44, 320, 216);
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 300)];
popoverView.backgroundColor = [UIColor whiteColor];
[popoverView addSubview:myPickerView];
[popoverView addSubview:pickerToolbar];
[self.view addSubview:popoverView];
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow: (NSInteger)row inComponent:(NSInteger)component {
}
// tell the picker how many rows are available for a given component
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return namesArray.count;
}
// tell the picker how many components it will have
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
// tell the picker the title for a given component
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return namesArray[row];
}
// tell the picker the width of each row for a given component
-(CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
int sectionWidth = 300;
return sectionWidth;
}
-(void)pickerDone:(id)sender
{
}
-(void)pickerCancel:(id)sender
{
}
In Swift 5 try this,
func setToolBar() {
let toolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 44))
toolBar.barStyle = UIBarStyle.default
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItem.Style.done, target: self, action: #selector(self.donePicker))
toolBar.setItems([doneButton],animated: false)
toolBar.isUserInteractionEnabled = true
doneButton.tintColor = UIColor.black
picker.addSubview(toolBar)
}
#objc func donePicker() {
// hide keypad
}
The UIBarButtonItems in the UINavigationBar inside of our UIPopoverController are hugging the left and right sides of the nav bar:
Here is the CustomPopoverController that we implemented. It used to hug the top of the navigation bar as well, but configurePopoverNavBar fixed that.
#implementation CMCommentPopoverController
- (id)initWithCaseId:(NSString *)cid andViewController:(CMNoteViewController *)cv forView:(UIView *)v {
self = [super initWithContentViewController:[[UINavigationController alloc] init]];
self.popoverNav= (UINavigationController *)self.contentViewController;
self.caseId = cid;
self.dvController = cv;
//size the popover
CGRect popoverRect = [CMMiscUtil getPopoverRect];
[self setPopoverContentSize:CGSizeMake(popoverRect.size.width, popoverRect.size.height)];
[self presentPopoverFromRect:CGRectMake(popoverRect.origin.x, popoverRect.origin.y, popoverRect.size.width, popoverRect.size.height) inView:v permittedArrowDirections:0 animated:YES];
[self setUpNav];
return self;
}
- (void) setUpNav {
[self.popoverNav pushViewController:self.dvController animated:NO];
self.popoverNav.navigationBar.topItem.title = #"Comments";
//add the buttons to the nav bar of the popover nav controller
self.popoverNav.navigationBar.topItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Add Comment" style:UIBarButtonItemStylePlain target:self action:#selector(notesAction:)];
self.popoverNav.navigationBar.topItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Close" style:UIBarButtonItemStylePlain target:self action:#selector(closeAction:)];
[self configurePopoverNavBar:self.popoverNav];
}
-(void) configurePopoverNavBar:(UINavigationController *)popoverNav {
UINavigationBar *navigationBar = popoverNav.navigationBar;
UIView *contentView = nil;
for (UIView *view in popoverNav.view.subviews) {
if ([[NSString stringWithFormat:#"%#", [view class]] isEqualToString:#"UILayoutContainerView"])
contentView = view;
}
[navigationBar setFrame:CGRectMake(navigationBar.frame.origin.x, 0, navigationBar.frame.size.width, navigationBar.frame.size.height)];
[contentView setFrame:CGRectMake(contentView.frame.origin.x, 0, contentView.frame.size.width, contentView.frame.size.height+50 + navigationBar.frame.size.height)];
[popoverNav.view bringSubviewToFront:contentView];
for (UIView *customView in contentView.subviews)
customView.frame = CGRectMake(customView.frame.origin.x, customView.frame.origin.y + navigationBar.frame.size.height, customView.frame.size.width, customView.frame.size.height);
[contentView addSubview:navigationBar];
[contentView bringSubviewToFront:navigationBar];
}
...
Create a custom view with a UIButton and create a UIBarButtonItem with this custom view.
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 80)];
UIButton *customButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 50, 70)];
[customButton setTitle : #"Add Comment"];
[customButton addTarget:self action:#selector(notesAction:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:customButton];
UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:customView];
self.popoverNav.navigationBar.topItem.rightBarButtonItem = rightBarButton;
change the customView and customButton frame according to your requirement.
Fixed this issue by putting the UINavigationBar inside a UIView that extended 10px on either side:
CGRect navBarFrame = navigationBar.frame;
navBarFrame.origin.y = 0;
UIView * navBarContainer = [[UIView alloc] initWithFrame:navBarFrame];
navBarContainer.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"header.png"]];
[navigationBar setFrame:CGRectMake(navBarFrame.origin.x + 10, navBarFrame.origin.y, navBarFrame.size.width - 20, navBarFrame.size.height)];
...
[navBarContainer addSubview:navigationBar];
[contentView addSubview:navBarContainer];
...
I have a custom overlay for camera, it that overlay I have UISlider:
#implementation LWOverlayView
- (id)initWithFrame:(CGRect)frame imagePath:(NSString*) imagepath{
if ((self = [super initWithFrame:frame])) {
// Clear the background of the overlay:
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
UIImageView *overlayGraphicView = [[UIImageView alloc] init];
overlayGraphicView.contentMode = UIViewContentModeScaleAspectFill;
[overlayGraphicView setImageWithURL:[NSURL URLWithString:imagepath]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
overlayGraphicView.frame = CGRectMake(80, 140, 160, 120);
[self addSubview:overlayGraphicView];
UIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 436, 320, 44)];
[toolbar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(dismiss)];
CGRect frame = CGRectMake(0.0, 0.0, 200.0, 10.0);
UISlider *slider = [[UISlider alloc] initWithFrame:frame];
[slider addTarget:self action:#selector(sliderAction:) forControlEvents:UIControlEventValueChanged];
[slider setBackgroundColor:[UIColor clearColor]];
slider.minimumValue = 0.0;
slider.maximumValue = 50.0;
slider.continuous = YES;
slider.value = 25.0;
[toolbar setItems:[NSArray arrayWithObjects:doneButton, slider, nil]];
[self addSubview:toolbar];
}
return self;
}
App crashes:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UISlider view]: unrecognized selector sent to instance 0x20854fe0'
Any hints?
As has been pointed out, you can't directly add a UISlider (or any other UIView) directly to the list of toolbar items.
What you need to do is create a UIBarButtonItem that contains the slider.
UIBarButtonItem *sliderBtn = [[UIBarButtonItem alloc] initWithCustonView:slider];
Now add sliderBtn to the array instead of slider.
You may find you need to set the width property on sliderBtn.
You cannot add the slider to the toolbar:
[toolbar setItems:[NSArray arrayWithObjects:doneButton, slider, nil]];
That is what is breaking your code, you can only add UIBarButtonItem
Toolbar can have items that are UIBarButtonItem. UISlider is not a UIBarButtonItem. That can have something to do with the crash. Try removing the slider and see how it works.
I have a UITextField that I set the inputView to a UIDatePicker so that when the UITextField is pressed, instead of a keyboard, a UIDatePicker pops up. I would like to also add a toolbar with a 'Next' button on it so that the user could easily jump to the next field, but I am not sure how to do this as I am already altering a view on the UITextField to get the UIDatePicker. Here is the code used in loading the view:
- (void)viewDidLoad
{
self.datePicker = [[UIDatePicker alloc] init];
self.datePicker.datePickerMode = UIDatePickerModeDate;
[self.datePicker addTarget:self action:#selector(datePickerValueChanged) forControlEvents:UIControlEventValueChanged];
issue.inputView = self.datePicker;
}
Suggestions for getting the 'Next' button added to a toolbar on top of it?
Create a view to use as the text field's inputAccessoryView. This view should contain your buttons (e.g. Next, Cancel, Previous).
Here's the code :
if (keyboardToolbar == nil) {
keyboardToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 44)];
[keyboardToolbar setBarStyle:UIBarStyleBlackTranslucent];
UIBarButtonItem *extraSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *next = [[UIBarButtonItem alloc] initWithTitle:#"Next" style:UIBarButtonItemStyleDone target:self action:#selector(switchToNextField:)];
[keyboardToolbar setItems:[[NSArray alloc] initWithObjects: extraSpace, next, nil]];
}
issue.inputAccessoryView = keyboardToolbar;
datePicker = [[UIDatePicker alloc] init];
datePicker.datePickerMode = UIDatePickerModeDate;
[datePicker addTarget:self action:#selector(datePickerValueChanged:) forControlEvents:UIControlEventValueChanged];
issue.inputView = datePicker;
And in your switchToNextField method, just make the nextField as the firstResponder using [nextTextField becomeFirstResponder];
You can create a view then put any UI elements inside of it.
#property (nonatomic,strong) UIPopoverController *popoverControllerBirthday;
add above to your .h file and sync it at .m #synthesize popoverControllerBirthday;
also change your #synthesize datePicker; to #synthesize datePicker=_datePicker;
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
if (textField==self.yourtextfield) {
UIViewController* popoverContent = [[UIViewController alloc] init]; //ViewController
UIView *popoverView = [[UIView alloc] init]; //view
popoverView.backgroundColor = [UIColor blackColor];
_datePicker=[[UIDatePicker alloc]init];//Date picker
_datePicker.frame=CGRectMake(0,0,320, 216);
_datePicker.datePickerMode = UIDatePickerModeDate;
[_datePicker setMinuteInterval:5];
[_datePicker setTag:10];
[popoverView addSubview:_datePicker];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button addTarget:self
action:#selector(result)
forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Next" forState:UIControlStateNormal];
button.frame = CGRectMake(0, 220, 320, 45);
UIColor *titleColor = [UIColor whiteColor];
[button setTitleColor:titleColor forState:UIControlStateNormal];
// UIImage *doneButtonImage = [UIImage imageNamed:#"create event button.png"]; choose a button background if you ahve one
[button setBackgroundImage:doneButtonImage forState:UIControlStateNormal];
[popoverView addSubview:button];
popoverContent.view = popoverView;
popoverControllerBirthday = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
popoverControllerBirthday.delegate=self;
CGRect myFrame =textField.frame;
myFrame.origin.x = 200;// your coordinates change it as you wish
myFrame.origin.y = 195;
[popoverControllerBirthday setPopoverContentSize:CGSizeMake(320, 265) animated:NO];
[popoverControllerBirthday presentPopoverFromRect:myFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
return NO; // tells the textfield not to start its own editing process (ie show the keyboard)
}
else{
return YES;
}
}
//handle your result call next uitextfield in your case
-(void) result
{
//in result method you can get date using datepicker.date
if (self.popoverControllerBirthday)
{
[self.popoverControllerBirthday dismissPopoverAnimated:NO];
self.popoverControllerBirthday = nil;
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateFormat:#"M d yyyy"];
NSString *parseDatePickerDAte =[dateFormatter stringFromDate:_datePicker.date]; // your string that is choosen at datepicker
// self.textfield.text = parseDatePickerDAte ; set this to your textfield if you want
//google this dont remember exact code for that, just changing your textfield to desired one
[self.nexttextfield becomesFirstResponder];
}
You can use SMDatePicker instead of UIDatePicker. It will create a custom view with UIToolbar and UIDatePicker. You can easy customise toolbar with necessary buttons. Take a look at example project.
I recently have been asking questions pertaining to UIToolbars and what not, but now I discover I need to add items to it programatically, I have seen other people's methods on how to go about doing it, but when I try doing the same thing, nothing ends up appearing. Pinpointing this problem is what I need help with. Here are my connections in IB:
And here is the relevant code:
Header file:
#import <UIKit/UIKit.h>
#interface ParkingRootViewController : UIViewController {
UINavigationController *navigationController;
UIToolbar *toolbar;
UIBarButtonItem *lastUpdateLabel;
}
#property(nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#property (nonatomic, retain) IBOutlet UIBarButtonItem *lastUpdateLabel;
- (IBAction)selectHome:(id)sender;
#end
Implementation file:
- (void)viewDidLoad {
[super viewDidLoad];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 20.0f)];
label.text = #"last updated...";
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont boldSystemFontOfSize:13.0];
label.userInteractionEnabled = NO;
lastUpdateLabel = [[UIBarButtonItem alloc] initWithCustomView:label];
[label release];
[toolbar setItems:[NSArray arrayWithObject:lastUpdateLabel]];
[self.view addSubview:self.navigationController.view];
//[self.view addSubview:toolbar];
//[self.navigationController.view addSubview:toolbar];
[self.navigationController.view setFrame:self.view.frame];
}
Any help is greatly appreciated!
EDIT:
I removed whatever I had in the nib which would cause the toolbar to appear/be modified and I updated my code in viewDidLoad to the following:
self.navigationController.toolbarHidden = NO;
//creating label in tool bar
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 150.0f, 20.0f)];
label.text = #"last updated...";
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
//label.highlightedTextColor = [UIColor colorWithWhite:0.5 alpha:1.0];
//label.highlighted = YES;
label.font = [UIFont systemFontOfSize:13.0];
label.userInteractionEnabled = NO;
UIBarButtonItem *lastUpdateLabel = [[UIBarButtonItem alloc] initWithCustomView:label];
//[lastUpdateLabel initWithCustomView:label];
//[label release];
//[toolbar setItems:[NSArray arrayWithObject:lastUpdateLabel]];
[self setToolbarItems:[NSArray arrayWithObject:lastUpdateLabel]];
And I end up getting a blank toolbar showing up. I fire up the debugger and this is what I see:
Aha! lastUpdateLabel's view's _text field is out of scope! But why? And how would I remedy this?
EDIT 2:
I have been able to add labels and an NSActivityIndicator with the following code:
#synthesize refreshDataButton;
//...
self.navigationController.toolbarHidden = NO;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20.0f, 0.0f, 80.0f, 40.0f)];
label.text = #"last updated...";
label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
label.backgroundColor = [UIColor clearColor];
label.textAlignment = UITextAlignmentCenter;
label.font = [UIFont systemFontOfSize:13.0];
label.userInteractionEnabled = NO;
[self.toolbar addSubview:label];
// create activity indicator
// dist frm lft, dist frm top
CGRect frame = CGRectMake( 90.0, 11.0, 25.0, 25.0);
UIActivityIndicatorView *loading = [[UIActivityIndicatorView alloc] initWithFrame:frame];
loading.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite;
[loading sizeToFit];
loading.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin);
[loading startAnimating];
[self.toolbar addSubview:loading];
But when I try to add a UIBarButtonItem I have no luck (doesn't show up in the toolbar):
self.refreshDataButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:100 target:self action:#selector(refreshDataButtonTapped)];
[self setToolbarItems:[NSArray arrayWithObject:refreshDataButton]];
Here is the header file:
#import <UIKit/UIKit.h>
//#import <CoreData/CoreData.h>
#interface ParkingRootViewController : UIViewController {
UINavigationController *navigationController;
UIToolbar *toolbar;
UIBarButtonItem *refreshDataButton;
//UIActivityIndicatorView *loading;
}
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UIToolbar *toolbar;
#property (nonatomic, retain) UIBarButtonItem *refreshDataButton;
//#property (nonatomic, retain) IBOutlet UIActivityIndicatorView *loading;
#property (nonatomic, readonly) NSString *applicationDocumentsDirectory;
-(IBAction)selectHome:(id)sender;
-(void)testCoreData;
-(void)refreshDataButtonTapped;
#end
The code should work...there are couple of suggestions I could make. Instead of:
[toolbar setItems:[NSArray arrayWithObject:lastUpdateLabel]];
try this:
[toolbar setItems:[NSArray arrayWithObject:lastUpdateLabel] animated:YES];
Also, since you are using a UINavigationController, NavControllers come with their own toolbar that you could use if you like. By default it is hidden, which you can make visible by doing this:
self.navigationController.toolbarHidden = NO;
and you can set its toolbar items by doing this:
[self setToolbarItems:[NSArray arrayWithObject:lastUpdateLabel]];
Hope this tid bit helps you. good luck!
The buttons need to be added by the viewController that is pushed by the navigationController. The navController holds the bar, but the items on the bar are controlled (added) by the viewController that is being shown. That way, each different kind of vc has it's own bar.
So take that barbuttonitem code, and plunk it in the init section of the vc, and enjoy.
//try this one.
- (void)viewDidAppear:(BOOL)animated
{
[toolbar setItems:[NSArray arrayWithObject:lastUpdateLabel]];
}
The code posted works fine, I think it has to be how the XIB is hooked up. I would re-do your connections in IB (ie break all the connections and re make them), save your XIB and try again.
You can add label to tool bar directly if u have instantiated it with frame...for example
UILabel *lbl=[[UILabel alloc]initWithFrame:CGRectMake(7,7,200,30)];
[lbl setBackgroundColor:[UIColor clearColor]];
[lbl setText:#"Test lbl"];
[_toolBar addSubview:lbl];