uiwindow landscape mode problem - iphone

i a uiview compenent and add it to application uiwindow like below. it works fine in portrait mode but when i oriante into lanscape mode it does not work properly. it think uiwindow still feels itself in portrait mode although not. how can run in landscape mode?
thanks.
MyView* popupView = [[MyView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)
url:url slidingType:slidingType html5Flag:_html5Flag];
// i change frame to CGRectMake(0, 0,480, 320) but not works
[popupView setTitle:self.currentAd.altText];
popupView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.5];
UIWindow* mainWindow = (((UIWindow*) [UIApplication sharedApplication].delegate).window);
CGPoint middleCenter = popupView.center;
CGSize offSize = [UIScreen mainScreen].bounds.size;
CGPoint offScreenCenter = CGPointMake(offSize.width / 2.0, offSize.height * 1.5);
popupView.center = offScreenCenter;
[mainWindow addSubview:popupView];
popupView.center = middleCenter;

Is that you view popupView autorized to rotate ? You need yo implement this method in your UIViewController class:
- (void)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return YES;
}

Related

iOS7 View moves under status/nav bars when loadView called again

I have a View Controller that creates its view programatically through the loadView method. The purpose of the view is to display a data models contents. When the view loads it is aligned correctly under the status and navigation bar.
But at a later point I present another view modally to allow the user to select a different data model to populate the view. This causes the the loadView to get called again and re-create the required UI for the new data model. The problem is that the view's contents now appear under the status and navigation bars!
Please note that I am not using auto-layout due to having to support iOS4 :( Also if I include the extendedLayout fix - it does fix the problem but only after the modal's dismiss animation completes leaving a jump down effect. My code below, thanks for any help.
- (void)loadView {
CGRect frame = CGRectMake(0, 0, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight);
self.view = [[UIView alloc] initWithFrame:frame];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
self.view.backgroundColor = [Constants categoriesScreenBackgroundColor];
CGRect scrollFrame = CGRectMake(0, 0, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight - ToolbarHeight);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin |
UIViewAutoresizingFlexibleTopMargin;
[self.view addSubview:scrollView];
_toolbarViewController = [self createToolbarViewController];
[self.view addSubview:_toolbarViewController.view];
_toolbarViewController.productInfoWorkflowState = _productInfoWorkflowState;
UIView *containerView = [[UIView alloc] initWithFrame:scrollView.frame];
containerView.backgroundColor = [UIColor clearColor];
_headerViewController = [self createHeaderViewController];
[containerView addSubview:_headerViewController.view];
_menuViewController = [[ProductInfoMenuViewController alloc] initWithBatch:[self batchData]];
_menuViewController.delegate = self;
[containerView addSubview:_menuViewController.view];
CGRect categoriesFrame = _menuViewController.view.frame;
categoriesFrame.origin.y = _headerViewController.view.frame.size.height;
_menuViewController.view.frame = categoriesFrame;
CGRect viewFrame = containerView.frame;
viewFrame.size.height = _headerViewController.view.frame.size.height + _menuViewController.view.frame.size.height;
containerView.frame = viewFrame;
[scrollView addSubview:containerView];
scrollView.contentSize = containerView.frame.size;
_starViewController = [[StarViewController alloc] initForProduct:_productData With:[StarredItems new]];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_starViewController.view];
}
Screen layout after first load:
Screen layout after second load:
With Leo's suggested fix, the scrollView is correct BUT the toolbar at the bottom now appears incorrectly. Code I used (placed after the toolbar creation code above):
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(#"7.0")) {
self.automaticallyAdjustsScrollViewInsets = NO;
scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(64.0f, 0.0f, 0.0f, 0.0f);
scrollView.contentInset = UIEdgeInsetsMake(64.0f, 0.0f, 0.0f, 0.0f);
}
Results:
Add following code its work for me for same issue, may be its help you
/* ios 7 Change */
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.edgesForExtendedLayout = UIRectEdgeNone;
self.automaticallyAdjustsScrollViewInsets = NO;
}
Does this only happen on iOS 7?
Give this a try:
self.navigationController.navigationBar.translucent = NO;
Try following:
Toolbar.autoresizingMask = UIViewAutoresizingFlexibleTopMargin;
try this
CGRect frame = CGRectMake(0, StatusBarHeight, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight);
self.view = [[UIView alloc] initWithFrame:frame];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.view.autoresizesSubviews = YES;
self.view.backgroundColor = [Constants categoriesScreenBackgroundColor];
CGRect scrollFrame = CGRectMake(0, StatusBarHeight, [Constants ScreenWidth], [Constants ScreenHeight] - StatusBarHeight - ToolbarHeight - ToolbarHeight);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleBottomMargin |
UIViewAutoresizingFlexibleTopMargin;
[self.view addSubview:scrollView];
I think the problem is due to incorrect automatic set of content insets of the scrollview.
Try the following. In your loadView, set self.automaticallyAdjustsScrollViewInsets to NO (only if NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1). Now, set the contentInset and scrollIndicatorInsets to the correct values depending on OS version:
scrollview.contentInset = scrollview.scrollIndicatorInsets = UIEdgeInsetMake(NSFoundationVersionNumber <= NSFoundationVersionNumber_iOS_6_1 ? 0 : 64, 0, 0, 0);
My problem was solved unmarking the check "Adjust Scroll View Insets" in the View Controller (using Storyboards).

Overlapping UITextView border

I need to support Landscape and Portrait orientation for my app, and I venture into using a single UIView.
When I first simulate the application, it displays the result without a problem. However, when I change orientation to landscape, the problem occurs.
The first time I run the application in portrait:
When I change the orientation to landscape:
Notice the lower left corner, near the Information tab.
When I change back the orientation to portrait:
It gets worse.
The code I am using,
- (void)updateLayoutForNewOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
CGFloat height = CGRectGetHeight([[UIScreen mainScreen] bounds]);
CGFloat width = CGRectGetWidth([[UIScreen mainScreen] bounds]);
if (UIInterfaceOrientationIsPortrait(toInterfaceOrientation)) {
NSLog(#"Portrait");
[self iPhoneUserInterfacePortrait:width height:height];
}
else if (UIInterfaceOrientationIsLandscape(toInterfaceOrientation)) {
NSLog(#"Landscape");
[self iPhoneUserInterfaceLandscape:width height:height];
}
}
- (void)iPhoneUserInterfacePortrait:(CGFloat)width height:(CGFloat)height
{
UITextView *descriptionTextView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 0.0, width - 100.0, height - 300.0)];
[self makeBorder:descriptionTextView];
[self setInformation:descriptionTextView];
[self.view addSubview:descriptionTextView];
}
- (void)iPhoneUserInterfaceLandscape:(CGFloat)width height:(CGFloat)height
{
UITextView *descriptionTextView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 0.0, width + 230, height - 368.0)];
[self makeBorder:descriptionTextView];
[self setInformation:descriptionTextView];
[self.view addSubview:descriptionTextView];
}
- (void)makeBorder:(UITextView *)descriptionTextView
{
descriptionTextView.layer.borderWidth = 3.0;
descriptionTextView.layer.cornerRadius = 15.0;
descriptionTextView.layer.borderColor = [[UIColor grayColor] CGColor];
[self.view addSubview:descriptionTextView];
}
You're adding several views while you want just one.
[self.view addSubview:descriptionTextView];
To get rid of this line, you could add field descriptionTextView to your ViewController subclass and change frame of that text view without adding/removing it from self.view.
Also you should try to play with AutoResizing masks to see if you can get needed results without actually changing frame manually.
And you should be careful with that constants: try your app on both 3.5 and 4.0 inch simulator devices.

How to resize a UIModalPresentationFormSheet?

I am trying to display a modal view controller as a UIPresentationFormSheet. The view appears, but I can't seem to resize it. My XIB has the proper height & width, but it seems to get overridden when I call it like this:
composeTweetController = [[ComposeTweet alloc] initWithNibName:#"ComposeTweet" bundle:nil];
composeTweetController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:composeTweetController animated:TRUE];
Any thoughts? I am using the iPhone SDK 3.2 beta 4
You are able to adjust the frame of a modal view after presenting it:
Tested in iOS 5.1 - 7.1
MyModalViewController *targetController = [[[MyModalViewController alloc] init] autorelease];
targetController.modalPresentationStyle = UIModalPresentationFormSheet;
targetController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; //transition shouldn't matter
[self presentViewController:targetController animated:YES completion:nil];
if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){
targetController.view.superview.frame = CGRectInset(targetController.view.superview.frame, 100, 50);
}else{
targetController.view.frame = CGRectInset(targetController.view.frame, 100, 50);
targetController.view.superview.backgroundColor = [UIColor clearColor];
}
Here's a method that works on iOS7 as well as iOS5 and iOS6: (arc)
-(void)presentController:(UIViewController*)controller fromRootController:(UIViewController*)rootController withSize:(CGSize)size
{
UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:controller];
nav.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[rootController presentModalViewController:nav animated:YES];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
{
nav.view.superview.backgroundColor = [UIColor clearColor];
nav.view.bounds = CGRectMake(0, 0, size.width, size.height);
}
else
{
nav.view.superview.bounds = CGRectMake(0, 0, size.width, size.height);
}
}
composeTweetController = [[ComposeTweet alloc] initWithNibName:#"ComposeTweet" bundle:nil];
composeTweetController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:composeTweetController animated:TRUE];
//if you want to change its size but the view will remain centerd on the screen in both portrait and landscape then:
composeTweetViewController.view.superview.bounds = CGRectMake(0, 0, 320, 480);
//or if you want to change it's position also, then:
composeTweetViewController.view.superview.frame = CGRectMake(0, 0, 320, 480);
As of iOS7 you can simply do
composeTweetController.preferredContentSize = CGSizeMake(380.0, 550.0);
Tested and works for iOS 6, using XCode 4.5
I stumbled upon my answer after reading much of the tips on here:
In the viewWillAppear:(BOOL)animated method:
[super viewWillAppear:animated];
//resize modal view
self.view.superview.bounds = CGRectMake(0, 0, 432, 680);
In the viewDidAppear:(BOOL)animated method:
CGPoint centerPoint = CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2);
self.view.superview.center = centerPoint;
I tried to add the centering code in the same place as the resizing code, but that did not work. For some reason, it only works after the view has appeared on the screen.
I surmise that it has something to do with the way that UIModalPresentationFormSheet works, because when I was stepping through in the LLDB debugger, I noticed that there was a variable _formSheetSize that was still {540, 620}. Go figure.
This will work with any UIModalTransitionStyle
#interface BaseDialog ()
#property(nonatomic,assign) CGRect origFrame;
#end
#implementation BaseDialog
-(void)viewDidLoad{
[super viewDidLoad];
self.origFrame=self.view.frame;
}
-(CGSize)formSheetSize{
return self.origFrame.size;
}
Following first code is how to present your model view controller
composeTweetController = [[ComposeTweet alloc] initWithNibName:#"ComposeTweet" bundle:nil];
composeTweetController.modalPresentationStyle = UIModalPresentationFormSheet;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:composeTweetController];
navigationController.delegate = self;
[self presentModalViewController:navigationController animated:YES];
And In your ComposeTweet controller class
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.navigationController.view.superview.frame = CGRectMake(0, 0,500,400);
}
iOS 7
So the approach of setting the superview's frame or bounds doesn't work anymore on iOS 7 (for UIModalTransitionStyleCoverVertical). You can, however, now set the background color of the superview to clear and then change the frame of the modal view controller how you see fit.
So in iOS 7 you will want to:
present the view controller (presentation mode: UIModalPresentationFormSheet)
set view controller superview background color to clear
change frame of view controller as desired (perhaps making it smaller and then centering it in superview)
I got a full screen modal view from UIPresentationFormSheet with just this line:
modalViewController.view.superview.bounds = CGRectMake(0, 0, 1024, 748);
#bdrobert sadly your nice solution does not work anymore on iOS6 - the container keeps the original size even though the new viewcontroller is embedded with the custom size.
You probably need to use the containment API introduced in iOS5, but you need to add a dimmed background on your own, fetching all touch events for that area.
On change of orientation, this code work perfect....
settingViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:settingViewController animated:YES completion:nil];
settingViewController.view.superview.frame = CGRectMake(0, 0, 700, 700);
UIInterfaceOrientation currentOrientation = [self getDeviceOrientation];
if(currentOrientation == UIInterfaceOrientationPortrait || currentOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
CGPoint centerPoint = CGPointMake([[UIScreen mainScreen] bounds].size.width/2, [[UIScreen mainScreen] bounds].size.height/2);
settingViewController.view.superview.center = centerPoint;
}
else
{
CGPoint centerPoint = CGPointMake([[UIScreen mainScreen] bounds].size.height/2, [[UIScreen mainScreen] bounds].size.width/2);
settingViewController.view.superview.center = centerPoint;
}
The modern ios13 way:
use popover (formsheet and page ignore preferredContentSize)
then set or override preferredContentSize aka Ed Pilowat & Co
The view size is fixed. You will have to implement things yourself if you want something different.

Landscape Screen shifted to right in 20px

I am trying to rotate the screen on the iphone. For example,
First state of screen : is "Portrait".
Then it calls "Landscape" screen. Following code is used for making Landscape screen :
- (void)viewDidLoad {
[super viewDidLoad];
[UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
CGFloat angle = 90 * M_PI / 180;
self.view.transform = CGAffineTransformMakeRotation(angle);
self.view.center = [nRangeAppDelegate sharedAppDelegate].window.center;
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 480, 44)];
label.textAlignment = UITextAlignmentLeft;
label.numberOfLines = 2;
label.text = #"12345\n67890";
[self.view addSubview:label];
}
But above code shifted to right in 20 px.
How to make 480x320 view at point 0,0 no shifting ?
Thanks in advance.
Update:
My application navigation based application. All UIViewControllers have one UIView. When call the the view I am trying rotate, this code is used : MyRoratedController *myCtrlr = [[MyRoratedController alloc] initWithNibName:#"MyRoratedController" bundle:nil]; [navigationController pushViewController: myCtrlr animated:NO]; I've changed CGPointMake(160.0, 240.0) by many different values. But no changes.
Your window is shifted because the appDelegate window is not centred on the screen as it is drawn below the status bar
Try this:
self.view.center = CGPointMake(160.0, 240.0);
You must make sure you are adding this view to a normal viewcontroller (ie not a nav controller or similar). The easiest way to do this is to add it to the main application window, like so:
MyRoratedController *myCtrlr = [[MyRoratedController alloc]
initWithNibName:#"MyRoratedController" bundle:nil];
[window addSubview:[myCtrlr view]];
Note that if your app has a status bar shown you will have to change the 160 above to 150

UIPickerView not appearing until touch occurs

I'm programatically adding two custom UIPickerViews to another view (MainView). They work just fine but they are not visible until a touch event occurs in any part of the MainView. I've checked the class references for UIPickerView and UIView but haven't found anything that manages to "refresh" the view, unless I'm missing something obvious?
Here's my drawRect method in MainView.m. I've tried doing the same thing in viewDidLoad but with no success. Could the custom rotations/transforms etc have something to do with it?
- (void)drawRect:(CGRect)rect {
CGRect pickerFrame = CGRectMake(50, -32, 30, 180);
m_picker1 = [[UIPickerView alloc] initWithFrame:pickerFrame];
m_picker1.delegate = self;
m_picker1.tag = k_ptag1;
m_picker1.showsSelectionIndicator =YES;
m_picker1.backgroundColor = [UIColor clearColor];
CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 0.075, 0.85);
[m_picker1 setTransform:rotate];
[self addSubview:m_picker1];
pickerFrame = CGRectMake(50, 67, 30, 180);
m_picker2 = [[UIPickerView alloc] initWithFrame:pickerFrame];
m_picker2.delegate = self;
m_picker2.tag = k_ptag2;
m_picker2.showsSelectionIndicator =YES;
m_picker2.backgroundColor = [UIColor clearColor];
rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 0.075, 0.85);
[m_picker2 setTransform:rotate];
[self addSubview:m_picker2];
}
You add subviews in a view's controller, not the view itself. I would suggest familiarising yourself with the MVC design pattern.
drawRect is only supposed to be used for the actual drawing of the view itself, not subviews.