In general my app works only in portrait, but one screen should be only in landscape. So I need to rotate my view, hide status bar and add a tool bar. When the status bar is visible my view is rotating fine, but after I perform [[UIApplication sharedApplication] setStatusBarHidden:YES], I see no rotation.. Here is the code:
- (void) viewWillAppear:(BOOL)animated
{
//[[UIApplication sharedApplication] setStatusBarHidden:YES];
CGAffineTransform landscapeTransform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(90));
landscapeTransform = CGAffineTransformTranslate (landscapeTransform, +80.0, +100.0);
[self.view setTransform:landscapeTransform];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 320.0);
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 20, 480, 40)];
[[UIToolbar appearance] setBackgroundImage:[UIImage imageNamed:#"BarBg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 100, 30)];
label.text = #"asdasd";
[toolBar addSubview:label];
[self.view addSubview:toolBar];
self.gallery.backgroundColor = [UIColor redColor];
}
The code you posted is working for me: the view appears rotated and i'm able to rotate it later having a default
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
I'd also add the following line at your viewWillAppear implementation:
[super viewWillAppear:animated];
Related
I am trying to programmatically make two views share width of a parent view. I have tried either using an init for the subviews and an initWithFrame, but in either case, I can't get the stretching to work correctly. In the example below, I am expecting to see a red window spanning half of the width of the screen and a green window filling the other half. What am I missing?
self.view = [[UIView alloc] initWithFrame:self.window.frame];
self.left = [[UIView alloc] init];
self.right = [[UIView alloc] init];
[self.left setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight)];
[self.right setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight)];
[self.view setBackgroundColor:[UIColor blueColor]];
[self.left setBackgroundColor:[UIColor redColor]];
[self.right setBackgroundColor:[UIColor greenColor]];
[self.left setContentMode:UIViewContentModeScaleToFill];
[self.right setContentMode:UIViewContentModeScaleToFill];
[self.view addSubview:self.left];
[self.view addSubview:self.right];
[self.view setAutoresizesSubviews:YES];
[self.window addSubview:self.view];
Thanks!
You never set the initial frame of the 2 views.
This code is tested and working in a UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
CGRect fullFrame = self.view.frame;
// position left view
CGRect leftFrame = fullFrame;
leftFrame.size.width = leftFrame.size.width / 2;
self.left = [[UIView alloc] initWithFrame:leftFrame];
// position right view
CGRect rightFrame = leftFrame;
rightFrame.origin.x = rightFrame.size.width;
self.right = [[UIView alloc] initWithFrame:rightFrame];
[self.left setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleHeight)];
[self.right setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleHeight)];
[self.view setBackgroundColor:[UIColor blueColor]];
[self.left setBackgroundColor:[UIColor redColor]];
[self.right setBackgroundColor:[UIColor greenColor]];
[self.left setContentMode:UIViewContentModeScaleToFill];
[self.right setContentMode:UIViewContentModeScaleToFill];
[self.view addSubview:self.left];
[self.view addSubview:self.right];
[self.view setAutoresizesSubviews:YES];
}
Try to set some initial frames of the subviews which you add to the main view. This should help:
self.left.frame = CGRectMake(0, 0, self.window.frame.size.width/2, self.window.frame.size.height);
self.right.frame = CGRectMake(self.window.frame.size.width/2, 0 , self.window.frame.size.width/2, self.window.frame.size.height);
Note: Everything worked fine on the older screen sizes however on the new iphone screens (640x1136) things are way to far down
here is the App Delegate initing and showing myRootViewController
myRootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
[myRootViewController.view setFrame:[[UIScreen mainScreen] applicationFrame]];
//NSLog(#"rootviewcontroller1 frame %#", NSStringFromCGRect(myRootViewController.view.frame));
//OUTPUTS: {{0, 0}, {320, 460}}
[window addSubview:myRootViewController.view];
The RootViewController sets the frame for the 'navigationController' and a few other views before adding them to its view.
//NSLog(#"ogtest rootviewcontroller frame2 %#", NSStringFromCGRect(self.view.frame));
//OUTPUTS: {{0, 20}, {320, 548}}
[navigationController.view setFrame:CGRectMake(0, 0, 320,528)];
//I have tried multiples variations including not setting it.
loadingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[loadingView setBackgroundColor:[UIColor clearColor]];
UILabel *_loadingLable = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 80.0f, 20.0f)];
_loadingLable.backgroundColor = [UIColor clearColor];
_loadingLable.textColor = [UIColor whiteColor];
_loadingLable.text = #"Loading...";
[_loadingLable setCenter:CGPointMake(181.0f, 240.0f)];
activityIndicatior = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[activityIndicatior setCenter:CGPointMake(120.0f, 240.0f)];
RoundedView *_roundedRectangle = [[RoundedView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 140.0f, 50.0f) roundedCorner:RoundedCornersTypeALL];
_roundedRectangle.center = CGPointMake(160.0, 240.0);
_roundedRectangle.rectColor = [UIColor blackColor];
_roundedRectangle.alpha = 0.7;
[loadingView addSubview:_roundedRectangle];
[loadingView addSubview:activityIndicatior];
[loadingView addSubview:_loadingLable];
[_loadingLable release];
[_roundedRectangle release];
[loadingView setHidden:YES];
[self.view addSubview:[navigationController view]];
[self.view addSubview: loadingView];
You can see from the image below that the grey bar is there for the nav bar. The text "Tuesday 30 Apr...." with the arrow buttons should occupy that grey area and not 2 cells from the top.
If you find yourself setting the frame of your navigation controller / navigation bar, you're doing something wrong.
Most of the time, you don't even need to set the frame of your view controller's view either.
Your app delegate needn't be any more complicated than this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
[[self window] setRootViewController:[[UINavigationController alloc] initWithRootViewController:[[RootViewController alloc] init]];
[self.window makeKeyAndVisible];
return YES;
}
It will most likely be a setting in your RootViewController nib. For the first view in the "Objects" list on the left, you have probably set the Top Bar property.
I ended up creating separate xib files with
_iPhone_Retina
at end of the file name
Which also called for statements like this
if (IS_IPHONE_RETINA) {
View = [[View alloc] initWithNibName:#"View_iPhone_Retina" bundle:[NSBundle mainBundle]];
}else{
View = [[View alloc] initWithNibName:#"View" bundle:[NSBundle mainBundle]];
}
and IS_IPHONE_RETINA is defined in the projectname.pch file as
#define IS_IPHONE_RETINA ([[UIScreen mainScreen] bounds].size.height == 568 )
I am using view.bounds to determine where to add a date picker view when a button is pressed. This works just fine if the orientation if the same as it was when the view was navigated to. Unfortunately if the orientation changes while the view is displayed the bounds are not undated, so the picker view is displayed incorrectly. I need a way to determine the actually bounds of the view. I would like something that works in both iPad and iPhone if possible because this is for a universal app. Also in the iPad version the picker view is in a splitview detail controller so I can't just swap the height and width and adjust for the navigation bar.
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
// size up the picker view to our screen and compute the start/end frame origin for our slide up animation
//
// compute the start frame
CGRect screenRect = self.view.bounds;
CGSize pickerSize = [self.pickerView sizeThatFits:CGSizeZero];
CGRect startRect;
CGRect pickerRect;
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if (UIInterfaceOrientationIsPortrait(orientation))
{
// code for Portrait orientation
startRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height,
pickerSize.width, pickerSize.height);
pickerRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height - pickerSize.height,
screenRect.size.width,
pickerSize.height);
}
else
{
//code for landscape
startRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height,
pickerSize.width, pickerSize.height);
pickerRect = CGRectMake(0.0,
screenRect.origin.y + screenRect.size.height - pickerSize.height,
screenRect.size.width,
pickerSize.height);
}
self.pickerView.frame = startRect;
// start the slide up animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
// we need to perform some post operations after the animation is complete
[UIView setAnimationDelegate:self];
self.pickerView.frame = pickerRect;
}
If I understand correctly your issue, you should try and set:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
on your views so that they bounds are "updated" when the orientation changes.
I ended up adding the pickerview to an action sheet like so:
UIActionSheet *aac = [[UIActionSheet alloc] initWithTitle:#"Choose Date and Time"
delegate:self
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil];
[datePicker addTarget:self action:#selector(dateChanged) forControlEvents:UIControlEventValueChanged];
pickerDateToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerDateToolbar.barStyle = UIBarStyleBlackOpaque;
[pickerDateToolbar 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(DatePickerDoneClick)];
[barItems addObject:doneBtn];
[pickerDateToolbar setItems:barItems animated:YES];
[aac addSubview:pickerDateToolbar];
[aac addSubview:datePicker];
[aac showFromTabBar:self.tabBarController.tabBar];
CGFloat wideth = self.view.frame.size.width;
if (UIDeviceOrientationIsLandscape([self interfaceOrientation])) {
[aac setBounds:CGRectMake(0,0,wideth, 355)];
[datePicker sizeToFit];
} else {
[aac setBounds:CGRectMake(0,0, wideth, 470)];
[datePicker sizeToFit];
}
picker = aac;
Hope that this helps others.
I have the following code to open a 320px x 320px UIPopoverController, but for some reason the popover is much taller than it should be - about twice the height that I specified (320px).
What's gone wrong?
colorPicker = [[RSColorPickerView alloc] initWithFrame:CGRectMake(20.0, 20.0, 320.0, 320.0)];
[colorPicker setDelegate:self];
[colorPicker setBrightness:1.0];
[colorPicker setCropToCircle:YES];
[colorPicker setBrightness:1.0];
[colorPicker setBackgroundColor:[UIColor clearColor]];
UIColor * aColor = [UIColor colorWithRed:0.803 green:0.4 blue:0.144 alpha:1];
[colorPicker setSelectionColor:aColor];
UIView *newview = [[UIView alloc] initWithFrame:CGRectMake(20.0, 20.0, 320.0, 320.0)];
[newview addSubview:colorPicker];
UIViewController *newviewcontroller = [[UIViewController alloc] init];
[newviewcontroller setView:newview];
UIPopoverController *newpopover =
[[UIPopoverController alloc] initWithContentViewController:newviewcontroller];
newpopover.delegate = self;
[self.colourController setPopoverContentSize:CGSizeMake(320, 320)];
self.colourController = newpopover;
[self.colourController presentPopoverFromRect:CGRectMake(149, 540, 1, 1) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
You need to set the popoverContentSize on the view controller being presented in the popover. You are setting it on the wrong view controller.
newpopover.delegate = self;
self.colourController = newpopover;
[self.colourController setPopoverContentSize:CGSizeMake(320, 320)];
You were doing these last two lines out of order.
I have a resizing issue when rotating a view controller that has two views which I switch between using the flip animation.
The problem appears if i do the following steps:
Rotate the device when viewing the tableview.
Click the info button.
Rotate the device (infoView appears stretched).
Click on info button (tableview appears stretched)
It appears that the view that is not added to the superview is not resizing correctly, since it was not part of the composite views when the device was rotated.. Is there any way to get this view auto resized correctly?
Below is a code sample
- (void)viewDidLoad {
[super viewDidLoad];
//background image
backgroundImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"bg-app.png"]];
backgroundImageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
[self.view addSubview: backgroundImageView];
[backgroundImageView release];
//infoView
aboutImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"About.png"]];
aboutImageView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
//tableView
self.tableView = [[[UITableView alloc ] initWithFrame:[[UIScreen mainScreen] bounds] style:UITableViewStylePlain] autorelease ];
//set the rowHeight once for performance reasons.
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.tableView.rowHeight = 75;
self.tableView.backgroundColor = [UIColor clearColor];
self.tableView.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight);
self.tableView.delegate = self;
self.tableView.dataSource = self;
self.tableView.autoresizesSubviews = YES;
//set the rowHeight once for performance reasons.
[self.view addSubview: tableView];
//[tableView release];
[self.view setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];//for resizing on rotation
//info button
UIButton * infoDarkButtonType = [[UIButton buttonWithType:UIButtonTypeInfoLight] retain];
infoDarkButtonType.frame = CGRectMake(0.0, 0.0, 25.0, 25.0);
infoDarkButtonType.backgroundColor = [UIColor clearColor];
[infoDarkButtonType addTarget:self action:#selector(infoAction:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *buttonInfo = [[UIBarButtonItem alloc] initWithCustomView:infoDarkButtonType];
self.navigationItem.rightBarButtonItem = buttonInfo;
[infoDarkButtonType release];
self.navigationItem.rightBarButtonItem = buttonInfo;
[buttonInfo release];
}
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
- (void)infoAction:(id)sender{
NSLog(#"Clicked on the info button");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75]; /* Sub. duration here */
UIView *superview;
if ((superview = [tableView superview])) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:superview cache:YES];
[tableView removeFromSuperview];
[superview addSubview:aboutImageView];
} else if ((superview = [aboutImageView superview])) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:superview cache:YES];
[aboutImageView removeFromSuperview];
[superview addSubview:tableView];
}
[UIView commitAnimations];
}
Thanks
Try putting the code in viewWillAppear:animated. It's called every time your view will appear. View did load is called once.