Landscape SubViews not filling self.view - ios

I have a UIView whose subview does not want to completely fill self.view after rotating into landscape mode. I have tried many things from setting autoresize masks to setting the frames of subviews after rotation, they either don't work, or the problem becomes much worse. Here is an example with a UINavigationBar that experiences this problem (navBar does not completely fill landscape width). The code:
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];
self.view.backgroundColor = [UIColor blueColor];
myBar =[[UINavigationBar alloc] init];
myBar.frame = CGRectMake (0, 0, self.view.frame.size.width, 44);
UINavigationItem *navItem =[[[UINavigationItem alloc] initWithTitle:#"Title"] autorelease];
UIBarButtonItem *rightButton =[[[UIBarButtonItem alloc] initWithTitle: #"Email" style: UIBarButtonItemStylePlain target: self action:#selector (rightButtonPressed)] autorelease];
navItem.rightBarButtonItem = rightButton;
UIBarButtonItem *leftButton =[[[UIBarButtonItem alloc] initWithTitle: #"About" style: UIBarButtonItemStylePlain target: self action:#selector (leftButtonPressed)] autorelease];
navItem.leftBarButtonItem = leftButton;
myBar.barStyle = UIBarStyleDefault;
myBar.items =[NSArray arrayWithObject:navItem];
[self.view addSubview:myBar];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end

Just add a single line of code at the end of your code:
- (void)loadView
{
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
self.view.backgroundColor = [UIColor blueColor];
UINavigationBar *myBar;
myBar =[[UINavigationBar alloc] init];
myBar.frame = CGRectMake (0, 0, self.view.frame.size.width, 44);
UINavigationItem *navItem =[[UINavigationItem alloc] initWithTitle:#"Title"];
UIBarButtonItem *rightButton =[[UIBarButtonItem alloc] initWithTitle: #"Email" style: UIBarButtonItemStylePlain target: self action:#selector (rightButtonPressed)];
navItem.rightBarButtonItem = rightButton;
UIBarButtonItem *leftButton =[[UIBarButtonItem alloc] initWithTitle: #"About" style: UIBarButtonItemStylePlain target: self action:#selector (leftButtonPressed)];
navItem.leftBarButtonItem = leftButton;
myBar.barStyle = UIBarStyleDefault;
myBar.items =[NSArray arrayWithObject:navItem];
[self.view addSubview:myBar];
[myBar setAutoresizingMask:UIViewAutoresizingFlexibleWidth];
}
I removed autorelease because I used ARC. You can add autorelease again. Have a good day friend.

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.

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.

iPhone crash randomly when calling a camera?

I have tested my app using instrument and it show the following leak.
When I double click on the CameraVC in the stack trace it refer to the following line into my code.
this happen when I call the camera, I call it using the following code:-
- (IBAction) getCamera
{
// set up our camera overlay view
// tool bar - handy if you want to be able to exit from the image picker...
UIToolbar *toolBar=[[UIToolbar alloc] initWithFrame:CGRectMake(0, 480-44, 320, 44)];
UIBarButtonItem *spaceItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil] autorelease];
UIBarButtonItem *spaceItem1 = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil] autorelease];
UIBarButtonItem *cancelItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelPickingImag)] autorelease];
UIBarButtonItem *cameraItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(finishedAugmentedReality)] autorelease];
spaceItem.width = 2.0;
spaceItem1.width = 55.0;
NSArray *items=[NSArray arrayWithObjects:spaceItem,cancelItem,spaceItem1,cameraItem,nil];
[toolBar setItems:items];
// create the overlay view
overlayView=[[OverlayView alloc] initWithFrame:CGRectMake(0, 300, 320, 480-44)];
// important - it needs to be transparent so the camera preview shows through!
overlayView.opaque=NO;
overlayView.backgroundColor=[UIColor clearColor];
// parent view for our overlay
UIView *parentView=[[UIView alloc] initWithFrame:CGRectMake(0,0,320, 480)];
[parentView addSubview:overlayView];
[parentView addSubview:toolBar];
[parentView addSubview:lbl];
[parentView addSubview:overlayGraphicView];
// configure the image picker with our overlay view
//UIImagePickerController *picker=[[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera])
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// hide the camera controls
imagePicker.showsCameraControls=NO;
imagePicker.delegate = self;
//imagePicker.allowsImageEditing = NO;
// and put our overlay view in
imagePicker.cameraOverlayView=parentView;
}
else
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
}
[self presentModalViewController:imagePicker animated:YES];
//Free memory
[imagePicker release];//,imagePicker =nil;
[parentView release], parentView=nil;
[overlayGraphicView release], overlayGraphicView= nil;
[lbl release], lbl=nil;
[overlayView release];//, overlayView =nil;
[toolBar release], toolBar=nil;
}
any help is highly appreciated
Thanks
parentView is being created with [alloc [init...]], meaning it's retained. Then you assign it to the cameraOverlayView property of imagePicker, meaning it gets retained again. You need to release it after you do that assignment.
(This is almost certainly the cause of the "leak", but would not cause a "crash". You say you're having a crash but don't describe that at all.)

Resources