UISlider crashes app when adding programmatically to view - ios

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.

Related

UITextField inputView not showing in iPhone 6

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

Why my UIButton doesn't display in my subview? iPad App

Could somebody help me to understand why my UIButton doesn't display in my custom UIView?
In the code below I posted initWithFrame method:
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor =[UIColor whiteColor];
UIToolbar *toolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0,frame.size.width, 50)];
toolbar.backgroundColor = [UIColor grayColor];
UIBarButtonItem *cancelBarButton = [[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(dismissNewInvoiceView:)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *saveBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStylePlain target:self action:#selector(saveNewInvoice:)];
[saveBarButton setEnabled:NO];
NSArray *arrayOfItems = [[NSArray alloc]initWithObjects:cancelBarButton,flexibleSpace, saveBarButton, nil];
[toolbar setItems:arrayOfItems];
UILabel *headerViewLabel = [[UILabel alloc]initWithFrame:CGRectMake(335, 15, 200, 20)];
headerViewLabel.text = #"New Invoice";
[toolbar addSubview:headerViewLabel];
[self addSubview:toolbar];
UIButton *selectCustomerButton = [[UIButton alloc]initWithFrame:CGRectMake(25, 200, 60, 60)];
selectCustomerButton.imageView.image = [UIImage imageNamed:#"Farmer.png"];
[self addSubview:selectCustomerButton];
[self bringSubviewToFront:selectCustomerButton];
UILabel *invoiceNumberLabel = [[UILabel alloc]initWithFrame:CGRectMake(25, 55, 150, 25)];
[invoiceNumberLabel setFont:[UIFont fontWithName:#"Verdana" size:14]];
invoiceNumberLabel.text = #"Invoice number:";
[self addSubview:invoiceNumberLabel];
UITextField *invoiceNumberField = [[UITextField alloc]initWithFrame:CGRectMake(140, 53, 150, 30)];
[invoiceNumberField setFont:[UIFont fontWithName:#"Verdana" size:25]];
invoiceNumberField.placeholder = #"25/13";
[self addSubview:invoiceNumberField];
UILabel *dateOfCreationLabel = [[UILabel alloc]initWithFrame:CGRectMake(500, 55, 150, 25)];
[dateOfCreationLabel setFont:[UIFont fontWithName:#"Verdana" size:14]];
dateOfCreationLabel.text = #"Date of creation:";
[self addSubview:dateOfCreationLabel];
}
return self;}
Why UILabels are displaying properly by implement addSubview method while UIButtons are not?
Regards
Don't do this:
selectCustomerButton.imageView.image = [UIImage imageNamed:#"Farmer.png"]
Use
[selectCustomerButton setImage:[UIImage imageNamed:#"Farmer.png"] forState:UIControlStateNormal];
The button sets its own image views image depending on its state, you don't access and set the image view's image yourself.
The button will be just invisible in case the image is not loaded/shown properly. As jrturton already said, you should use another method to set the image.
To figure out if the button is 'there', you can give the button a backgroundcolor like this:
selectCustomerButton.backgroundColor = [UIColor redColor];
If you see a red box, you know the image is not properly loaded or maybe not even found.

UIBarButtons too close to the edges of UINavigationBar inside UIPopoverController

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];
...

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.

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