iphone 5 retina 4 inch mapview - objective-c

I'm trying to adapt my app to retina 4 screen for iPhone 5, and adding the png archive and everything resizes but the map view, that moves to the top and leaves a white square on the bottom. I'd like to know how to fix it.
Thanks in advance.
Maybe this has to do with it?
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// We need to manually handle rotation on iPads running iOS 5 and higher to support the new UINavigationBar customization. This is automatic on the iPhone & iPod Touch.
if ([self.navigationController.navigationBar respondsToSelector:#selector(setBackgroundImage:forBarMetrics:)] ) {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"UINavBarLandscape#iPad.png"] forBarMetrics:UIBarMetricsDefault];
}
else {
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"UINavBar#iPad.png"] forBarMetrics:UIBarMetricsDefault];
}
}
}
else {
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
[mapView setFrame:CGRectMake(0, 0, 480, 236)];
[toolbar setFrame:CGRectMake(0, 236, 480, 32)];
}
else {
[mapView setFrame:CGRectMake(0, 0, 320, 372)];
[toolbar setFrame:CGRectMake(0, 372, 320, 44)];
}

For the to top bar should be anchored to the top. the bottom bars anchored to the bottom of the controller's view. The map view should be anchored to the top and the bottom but should also have a vertical spring.
Now everything should expand correctly when you have a iphone 4 or 5.
Also if you are targeting iOS 6, take the time to use AutoLayout. That way when the iPhoneN has a different resolution you don't have to worry about the layout so much.

You have to check iPhone device version in your code programmatically and resize the controls accordingly.

Related

Hide and show UIView with bottom View filling the space when hidden using autolayout

I have two views on top of one another like so. When I press button, I want to hide the grey view and have the pink view move up into its space. When I press button again, I want the grey view to re-appear and move the pink view back into its original position.
I can accomplish this by doing something like
- (IBAction)toggle:(id)sender {
if (self.top.hidden) {
self.top.hidden = NO;
self.top.layer.frame = CGRectMake(0, 0, 320, 50);
self.bottom.layer.frame = CGRectMake(0, 50, 320, 50);
} else {
self.top.layer.frame = CGRectMake(0, 0, 0, 0);
self.bottom.layer.frame = CGRectMake(0, 0, 320, 50);
self.top.hidden = TRUE;
}
}
However, the general wisdom, from what I understand, regarding autolayout is to not set the frame sizes programmatically in the code. So my question is, how can achieve the same result using autolayout?
It's basically the iPhone version of this question: OS X Cocoa Auto Layout hidden elements
Found the answer courtesy of this question: Animating an image view to slide upwards
In short:
- (IBAction)toggle:(id)sender {
if (self.top.hidden) {
self.top.hidden = NO;
[UIView animateWithDuration:0
animations:^{
self.verticalSpace.constant += 50.0;
[self.view layoutIfNeeded];
}];
} else {
[UIView animateWithDuration:0
animations:^{
self.verticalSpace.constant -= 50.0;
[self.view layoutIfNeeded];
}];
self.top.hidden = TRUE;
}
}
where self.verticalSpace is the constraint set between the bottom view to the top view.

Reset frames when rotating orientation

I have an app that has some buttons and a text view and a label. I want to rotate the device and have them redrawn on the screen to fit. I want to do it programatically. Currently I have these methods:
-(void)willRotateToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
[super willRotateToInterfaceOrientation:toInterfaceOrientation
duration:duration];
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight ||
toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self reOrderSideways];
} else {
[self reOrderUpDown];
}
}
-(void)reOrderSideways{
self.viewLabel.frame=CGRectMake(175.0,140.0,130.0,20.0);
self.buttonOne.frame=CGRectMake(20.0,20.0,440.0,100.0);
self.buttonTwo.frame=CGRectMake(20.0,180.0,440.0,100.0);
self.textContent.frame=CGRectMake(20.0, 290.0, 440.0, 100.0);
self.theScroller.contentSize = CGSizeMake(480.0, 350.0);
}
-(void)reOrderUpDown{
self.viewLabel.frame=CGRectMake(95.0,15.0,130.0,20.0);
self.buttonOne.frame=CGRectMake(20.0,50.0,280.0,190.0);
self.buttonTwo.frame=CGRectMake(20.0,250.0,280.0,190.0);
self.textContent.frame=CGRectMake(20.0, 450.0, 280.0, 190.0);
self.theScroller.contentSize = CGSizeMake(320.0, 460.0);
}
It doesn't quite work because when i rotate sideways, the buttons and labels and textview get cutoff the right side. I checked it and it looks like its using the coordinates I gave it but it is still using the portrait frame or bounds. How can i fix this?
Try using willAnimateRotationToInterfaceOrientation: instead.

Why frame of detailViewController always return me 1024*768

I have an iPad app with split view controller.
I want to programmaticaly create and add subview to detailViewController in right bottom corner. To do that i try to get frame of detailView (app support autorotation, so that position not static)
i do next
in viewWillAppear for detailView i try to get frame and calculate position i need
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGRect btnRect = self.view.frame;
//it always return 1024*748 width and height
//even in landscape mode
//when as i think must return 1024-321=703*748 pxls
//where is my mistake? How i can get actual frame
//dimensions for detailViewController in landscape orientation
btnRect.origin.y = btnRect.size.height - 42;
btnRect.origin.x = btnRect.size.width - 42;
btnRect.size.height = 42;
btnRect.size.width = 42;
UIButton* btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setBackgroundImage:someimage forState:UIControlStateNormal];
[[btn layer] setFrame:btnRect];
[self.view addSubview:btn];
}
But it always show me that detailView frame has 1024*748 dimensions. When in landscape mode i think it must be 703*748. What i need to do to get actual detailView frame?
You should want to change the frame of the view in the shouldAutorotateToInterfaceOrientation method.
An example:
(This one will adjust scrollView2 to fit its new orientation (88 pixels lower then the mainview))
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
if (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) {
// Portrait
self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.width, self.view.frame.size.height - 88);
[self drawContent];
}
else {
// Landscape
self.scrollView2.frame = CGRectMake(0, 88, [UIScreen mainScreen].bounds.size.height, self.view.frame.size.width);
[self drawContent];
}
return YES;
}

'willRotateToInterfaceOrientation' not working for my DetailViewController

I'm developing this application on the iPad. My MainWindow contains a Split View Controller which loads the RootViewController and DetailViewController.
I have this image that is placed at the bottom-right of the DetailViewController.
My application allows different orientations, therefore i want the image to appear at different positions for different orientations.
This is my code in DetailViewController:
- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
myImage.frame = CGRectMake(183.0f, 257.0f, 548.0f, 447.0f);
}
else if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
myImage.frame = CGRectMake(244.0f, 518.0f, 548.0f, 447.0f);
}
}
When i launch my application and my iPad is at portrait orientation, the image will be correctly placed at (X:244, Y:518) which is at the bottom right.
But when i launch my application and my iPad is at landscape orientation, the image will not be shown and i suspect that it is still at the position for portrait orientation. Only when i rotate my iPad to portrait orientation and then back to landscape orientation, then the image will appear at (X:183, Y:257) which is correct.
What i tried to do is to place these codes in my DetailViewController's 'viewWillAppear' method:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if(self.interfaceOrientation == UIInterfaceOrientationLandscapeLeft || self.interfaceOrientation == UIInterfaceOrientationLandscapeRight)
{
myImage.frame = CGRectMake(183.0f, 257.0f, 548.0f, 447.0f);
}
else if(self.interfaceOrientation == UIInterfaceOrientationPortrait || self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
myImage.frame = CGRectMake(244.0f, 518.0f, 548.0f, 447.0f);
}
}
But when i launch my application, it still has the same problem.
What can i do so that when i first launch my application in landscape orientation, it will be correctly placed at (X:244, Y:518) ?
You might want to try putting your resizing logic in didRotateFromInterfaceOrientation instead of willRotateToInterfaceOrientation.
My custom layout code only worked when I called it after the rotation had completed it, rather than before.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
NSLog(#"didRotateFromInterfaceOrientation");
float width;
float height;
if ((fromInterfaceOrientation == UIInterfaceOrientationLandscapeRight) ||
(fromInterfaceOrientation == UIInterfaceOrientationLandscapeLeft))
{
width = [[UIScreen mainScreen] applicationFrame].size.width;
height = [[UIScreen mainScreen] applicationFrame].size.height;
NSLog(#"Changing to portrait: %f x %f", width, height);
}
else
{
width = [[UIScreen mainScreen] applicationFrame].size.height;
height = [[UIScreen mainScreen] applicationFrame].size.width;
NSLog(#"Changing to landscape: %f x %f", width, height);
}
NSLog(#"Changed orientation: %f x %f", width, height);
// Call my custom layout function to setFrame on all my UI controls
[self doLayout:width height:height];
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
If your app shows the status bar then you probably need to call self.view.frame.size.width instead of getting the size from the applicationFrame.
Make sure that you're overriding
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation; // Override to allow rotation. Default returns YES only for UIInterfaceOrientationPortrait
To return YES for each UIInterfaceOrentation that you want to support, otherwise willRotateToInterfaceOrientation and didRotateToInterfaceOrientation wont get called.
Try calling this early in your applicationDidFinishLauching:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
Since the detailViewController wouldn't sometimes know its orientation, I solved this issue by having a shared variable in the appDelegate that would store the device orientation throughout the app. You can initialize it in the splitViewController with its orientation so when the detailViewController loads it can read it from there.

Center UIPageControl after orientation change

I'm trying to centralize a UIPageControl in portrait and landscape modes, but it isn't working, the x changes after device rotation.
#interface DetailViewController : UIViewController<UIScrollViewDelegate>
{
UIPageControl *pageControl;
}
- (void)viewDidLoad
{
pageControl = [[UIPageControl alloc] init] ;
[self renderMyView];
[self.view addSubview:pageControl];
}
- (void)renderMyView
{
if(isPortrait)
{
pageControl.frame = CGRectMake(200, 976, 0, 0);
} else {
pageControl.frame = CGRectMake(200, 720, 0, 0);
}
}
The renderMyView is executed on didLoad and didRotate.
At first time viewDidLoad works well in portrait and landscape, but if I rotate the device the pageControl appears in a different x != 200.
I've also tried pageControl.center, but it didn't work.
How can I keep it centralized?
1) In viewDidLoad call renderMyView.
2) After device has rotated don't call method renderMyView
3) Replace your renderMyView with this one:
- (void)renderMyView
{
if(isPortrait)
{
pageControl.frame = CGRectMake(200, 976, 0, 0);
} else {
pageControl.frame = CGRectMake(200, 720, 0, 0);
}
pageControl.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin;
}
So, don't call my renderMyView more then one time. AutoresizingMask will do all you need.
Tell me, please, if it works for you.
PS: For more information about the autoresizingMask, read the UIView Documentation.
probably a very old question, but I'll share my way to center the UIPageControl. Just set the width of the UIPageControl to be the same width as the view's bounds size width. So, In portrait mode it will be 768 and in the landscape it will be 1024. It works for me.
Set the UIView autoresizingMask in code:
pageControl.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
Or you can also do this in interface builder.