How to anchor a view relative to the side of the screen iPhone - iphone

I am creating an iOS app that creates layouts directly in code. I am used to using xib, but that is not an option for this project. I cannot figure out how to position an element fixed to the bottom/side of the screen. The solution I'm looking for will position it to the bottom in portrait, but on rotation will fix it to the right hand side (very similar to how the bottom bar works in the camera app). It's properly at the bottom of the screen in portrait, the problem is on rotate
Also I'm building for iOS 5 so I need a solution that does not use Auto-Layout.
Here is the code I have so far that I do on rotate to landscape. The idea is that I rotate 90(which is working) then use some sort of mask to anchor it to the left hand side. Where am I going wrong here? Is it even possible to anchor an object like this??
myView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleLeftMargin;
CGAffineTransform rotate90 = CGAffineTransformMakeRotation(degreesToRadians(-90));
myView.transform = rotate90;

Do not deal with the bar, but with the views inside your bar.
Try this :
1) Prevent your app from autoRotate using :
//For iOS 5 and lower
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
return NO;
}
//For iOS 6 and upper
- (BOOL)shouldAutorotate {
return NO;
}
2) Rotate the view inside your bar and not your bar itself
Hope it will help you.

You need to use the NSLayoutConstraints for doing this.
I don't know much about the constraints coding, so please refer NSLayoutConstraint for more reference.
WWDC 2012 Session Videos about NSLayoutConstraints

Related

Subviews incorrect size?

Let me start off with saying that I am no expert in iOS Development or Objective-C.
I am making a app for a local charity(its a church) and they want it to support rotation.
The app work as expected if started in portrait mode, I can choose my new subview and the rotate it works perfectly.
However I need it to work so they can rotate at any time. The Main view(the one loaded on startup) already does this out of the box; but my subviews do not.
I have attached 3 screenshots below to try and explain what I mean.
This is how it looks in portrait mode:
In landscape:
and back to portrait it I started the app rotated:
If it helps I add the subview like this:
dailyPrayerView = [[DailyPrayerView alloc] initWithNibName:#"DailyPrayerView" bundle:nil];
[self.view addSubview:dailyPrayerView.view];
Does anybody have any ideas why this is?
Check the autoresizing mask in Interface Builder. It's on the sizes pane of the Utilities pane. You should be able to make it stretch to fit the screen, rather than staying at a constant size.

Landscape orientation issue

I have my app 98% complete but stumbled across an issue which is stumping me!
Any help would be great.
Basically....I have a 5 tab controller. I have done some remodelling on the first tab view so that moving it from portrait to landscape moves everything around so that it looks great.
The other 4 tabs also move from portrait to landscape and back with ease.
Now....the issue I stumbled across was that if I had say tab 5 in portrait, moved it to landscape and then tapped tab 1, the only bits in tab 1 that orientate to landscape are the bits i fixed in the sizing inspector.
The bits I've re-positioned in code won't landscape.
If I however turn that tab 1 portrait and then back to landscape, it works!
The label fields I've moved with code using .frame and CGRectMake is in the
-(void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation duration: (NSTimeInterval)duration
method.
.......do I need to put some code in the AppDelegate which the TabController resides in??
It makes sense to me that the TabBarController knows the orientation.
When you tap a tab.....what method gets actioned first before the view loads??
I think I need to catch the orientation then, adjust my label positions and then load the view.......
I would appreciate any thoughts?
Gaz.
EDIT: It's like what I want to do is be able to change things in tab 1 if the orientation changes in other tabs.can you do that? It seems that the 5 tab views are separate...
Try making a call to your rotation method in your view controllers viewWillAppear method, checking for correct orientation, and moving what you need to move. Should look something like this
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self autoRotate];
}
I think that if you move something in code it maintains it's position, so you need to change it's position every time the orientation changes in every view controller where you move objects in code. Like:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation)){
//change positions with animation using duration
}else if(UIInterfaceOrientationIsPortrait(toInterfaceOrientation)){
//change positions with animation using duration
}
}
I hope it helps.

iPhone - Prohobit UIView from rotating when the device is turned

I haven't been able to figure this out. Could someone please help me? I am trying to stop one UIView in my app from rotating when the device is turned.
I am working on a drawing app. Right now, when the device is turned, all UI elements turn with it. What I am trying to do is have all the buttons, menus, etc. turn, but have my canvas UIView be static and ignore the rotation of the phone.
If the canvas view is a subview of a view that rotates, then it will rotate as well. It's inescapable.
If you have one element of a view that you do not want to appear to rotate, you have use a rotation transform to programmatically rotate that one view back to the orientation and frame you want it have.
You could use the following to prevent the view itself from rotating:
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return false;
}
Then manually rotate the individual elements you want rotated.
OP here. Rotating the view using CGAffineTransformMakeRotate() worked like a charm. Thanks, TechZen!

iPhone rotation woes

I have been spending many frustrating hours trying to get rotations working on the iPhone version of Tunepal.
Firstly, I have a tab bar controller, with a navigation controller controlling each of the views.
I actually only want one of my views to be able to rotate and that is the TuneDisplay.
I have a subclassed the UITabBarController and overridden the shouldAutorotateToInterfaceOrientation:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation {
if (self.selectedViewController != nil)
{
return [self.selectedViewController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
else
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
}
In each of the view controllers for each of the tabs I have overridden the method and returned YES for each orientation I want to support. All well and good and everything works as it should. If I try and do a rotation on a tab that doesn’t support the rotation, nothing happens.
The problem occurs if I move from a tab thats rotated to a tab that isnt supposed to support that rotation. The new tab is displayed rotated too! Screenshots for all this are included here:
http://tunepal.wordpress.com/2010/04/20/rotation-woes/
Is there any way I can make it rotate back to portrait on tapping the tab?
I have tried the unsupported setOrientation trick, but firstly it doesnt work correctly and secondly I received a warning from Apple for including it in my last build.
If (as I suspect) there is no way to limit this behavior:
How do I make the microphone image scale when I rotate the device?
How do I make the buttons and the progress bar expand to fit the witdh of the toolbar?
Also, one of the tabs that rotates ok has a table, with a search bar. The first time I rotate to the right or to the left, I get a black bar to the right of the search bar. If I subsequently rotate back and rotate again, the bar disappears! I have enabled the struts and springs things on the search bar in the interface builder and it looks like it should behave correctly.
Any ideas about how to fix this?
Ideas, feedback much appreciated
Bryan
This isn't a full answer. Rotation is seriously inconsistent. You have done the right things. Several aspects don't work in the simulator, so you need to confirm all your testing on a device. Table headers and search bars don't resize to full width in older OS versions, so stick with 3.1.3 or higher.
Commonest problems:
implement the shouldAutorotateToInterfaceOrientation: to return YES;
if you use navigation controllers the root view controller must support the orientation;
if you have a toolbar the view controller for all items must support it;
and same for a tab bar controller.
You may need to turn on orientation notifications to get more useful information out of the device:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
Remember to turn it off and remove yourself from the notifications when you are done; this is supposed to have a high overhead.
Set the view contentMode property for your image to resize; together with autoresizingMask, which you are setting in IB, you should be OK.
Remember also that you can use two different nibs for portrait and landscape modes. There is an example project that sort of does this ("WhichWayIsUp"); see the View Controller Programming Guide also ("Creating an Alternate Landscape Interface").
If the rotation methods are being called, then the UI should be rotated consistently. You will find that they aren't always called when they should be.
It isn't hard to call a rotational transform on your views to force a rotation. It shouldn't be needed, but sometimes that's the only way they will rotate.
view.transform = CGAffineTransformMakeRotation(M_PI * n);
If you get it figured out, let us know.
It sounds like you are handling the rotation correctly while the tab is displayed. However, as you know, there's no quick way to switch rotations. What you will have to do is rotate the view yourself using CGAffineTransform. See this question: Is there a documented way to set the iPhone orientation?
To scale the image, you should be able to click the arrows inside the UIImageView housing the image in Interface Builder. There's a little arrow in the upper right hand corner you can click to see how the view behaves when it's rotated to make sure it scales correctly. But you'd probably be better off not scaling the image and hadling the rotation as in the answer to the linked question.

UIView Clipped By Statusbar until Autorotate

Ive created a multiview application that uses multiple controllers to display and control views. The problem Im having is, when the simulator initially loads the view the header is partially covered by the bar at top of screen and the tool bar at the base is not touching the base of the screen. I used the Interface builder size attributes to control the view when the iphone rotates and it works perfectly. All smaps into place perfectly both in landscape and portrait mode AFTER a rotation but the problem is with the initial load before a rotation occurs.
Your thoughts a much appreciated.
Tony
I grappled with this issue for days and days--no amount of fiddling in IB worked.
Ultimately I got it to work by adding this line:
mainViewController.view.frame = window.screen.applicationFrame;
to the application:didFinishLaunchingWithOptions: method. (Where mainViewController is the primary UIViewController).
I've had issues with views being clipped by status, nav, and tab bars. I've fixed most of them by using the Simulated Metrics feature in Interface Builder. That way what your laying out in IB is a lot more accurate to what your actually going to get.
I ran into this issue too. Specifically, when displaying an ADBannerView, my whole view would shift and be under the status bar and leave a little empty space just the size of the status bar at the bottom of the iPhone screen. Here's how I solved it : (Adam's answer here helped me figure this out):
// In the function that displays an iAD Banner
CGRect contentFrame = self.view.bounds;
CGRect myStatusBarFrame = [[UIApplication sharedApplication] statusBarFrame];
CGFloat statusHeight = myStatusBarFrame.size.height;
// Set the view's origin to be under the status bar.
contentFrame.origin.y = statusHeight;
I needed to set the origin of my view to be below the Status bar, and that solved the issue for me.
The problem is that you're adding your controller "incorrectly" according to Apple docs (although IMHO Apple designed it badly - the default should be that you don't need to shift!)
if you're going to have a status bar, Apple requires that you "manually" shift all your controllers down by 20 pixels (more accurately, by the height of the statusbar - although that's always 20 pixels today, Apple lets you request the height at runtime, from the "statusBarFrame" property in UIApplication)
Apple's classes - e.g. UINavigationController / UITabBarController - automatically shift themselves down by 20 pixels when they're added to the screen. Both classes have a bug where they will do this shift even if they are not the main controller - so your app suddenly shifts down an extra 20 pixels, leaving 20 pixels of white space at top.
But, when they rotate, those classes often "get it right" and move back into place. Or vice versa.
c.f. this link for a much more detailed explanation of what's going on, and how to write your code the way Apple wants you to:
http://blog.red-glasses.com/index.php/tutorials/iphone-auto-rotation-for-intermediate-developers-tutorial-1/