Cannot properly rotate a translated UIView on the iPad - iphone

I have an UIViewController that has two UIViews inside, whose layout (set in Interface Builder) is something like this (the magenta colored view is the UIViewController default view):
and I added the main view to a root view obtaining this effect (by not showing the darker view placing its frame at the bottom):
Now when the device rotates, what I obtain is this:
whereas I'd like to still hide the darker view.
This is the code I use to hide it when it appears (I use it in the viewDidLoad method):
- (void)hideAll:(float)time{
CGRect hiddenFrame = CGRectMake(0, 1024, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame:hiddenFrame];
[self.view setNeedsDisplay];
}
and it appears to work, but when I call a variant of it when rotating (in willRotateToInterfaceOrientation:duration:), nothing happens:
CGRect hiddenFrame = CGRectMake(0, 748, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame:hiddenFrame];
[self.view setNeedsDisplay];
What am I missing? have I to set some other view property in Interface Builder?
UPDATE
It seems to me that the coordinate system does not change after the device has been rotated (ie the origin set in the upper-left corner in portrait mode will become the upper-right after a clockwise rotation in landscape mode)

Check your struts and springs in IB. It maybe that when you autorotate, the strut fixing you to the top of the screen moves your frame back to the top.
Try adding your code to the didRotateToInterfaceOrientation method so it can run after rotation has occurred.

Why to you change the frame to hide it, and not just
[self.view setHidden:YES];
second thing is that you should try to set the "Autoresizing" panel to handle the orientation changes, and not by changing the frame of the view.
hope i understood you right.
shani

The problem I encountered can be faced in two ways (I hope this can save some time for someone in the future):
using an UIViewcontroller (loaded from xib) and only its view as the rotating view, that is my original attempt to solve it. In this case you have to programmatically set the frame for the view when you want to hide it, and by doing so you have to consider that the coordinate system for the controller remains untouched and does not rotate (ie. it is always originated from the same corner)
using a UIView (loaded from xib) inside an already existing UIViewcontroller, in this way the view will automatically rotate and resize and you will not have to take the proper coordinates value into account at each rotation (this is by far the simplest way)

Related

Change view alternative

I have an window based app with some ViewController.
I switch from one view to another using :
[self.view addSubview:newViewController.view];
Everything works fine but I have a problem:
When I change the view to a scrollView which has frames more than 320x480 I can not return to previous frames.I mean I change the the views further normally but I have a bigger frame and I see the rest of the content from the scrollView which is not covered by the current view.
Is there any method to set the superview size back to 320x480?
Thanks
You can set the frame of a view back to 320X480 manually by doing something like:
yourView.frame = CGRectMake(0,0,320,480);
When you switch back are you removing the scrollview from the superview as well? [scrollview removeFromSuperView]; ?

How do you programmatically force a scroll using UIScrollView?

I have a horizontal UIScrollview set up (meaning its not one that scrolls up and down but one that only scrolls left-right) and upon the app launching, I want this scrollview to scroll itself left, then right - kind of "demonstrating" its ability to scroll - and finally then stop, letting the user then take over and control the scroll manually with their finger.
Everything works - except for this on-load left-right demo-scrolling.
I'm not using Interface Builder for any of this, I'm doing everything with code:
//(this is in viewDidLoad:)
// Create the scrollView:
UIScrollView *photosScroll = [[UIScrollView alloc] initWithFrame: CGRectMake(0, 0, 320, 200)];
[photosScroll setContentSize: CGSizeMake(1240, 200)];
// Add it as a subview to the mainView
[mainView addSubview:photosScroll];
// Set the photoScroll's delegate:
photosScroll.delegate = self;
// Create a frame to which to scroll:
CGRect frame = CGRectMake(10, 10, 80, 150);
// Scroll to that frame:
[photosScroll scrollRectToVisible: frame animated:YES];
So the scrollView loads successfully and I'm able to scroll it left and right with my finger - but it doesn't do this "auto-scroll" like I was hoping it would.
I tried calling the scrollRectToVisible before and after adding the
scrollView as a subview - didn't work.
Thinking maybe this should
happen in loadView and not in viewDidLoad? But if so, how?
Any ideas?
A couple of ways to do this:
Use scrollRectToVisible:animated: for a zero X value and then a largeish positive one, then set it back to your middle point. You can call the method after the scroll view is added as a subview (probably before too, but best be safe). You'll need to calculate what value of X is off-screen to the left using your contentSize and knowledge about how wide your various elements inside the scroll view are.
Since you're just doing a quick animation and will give the user control, this can really be a quick-and-dirty animation, so you could use setContentOffset:animated: to force the content of the scrollview to move relative to your current view position. Move the elements right for a left scroll (positive X value), then left twice as far for a right scroll (negative X value), then set the offset back to zero.
You shouldn't put either of these in viewDidLoad or loadView; put them in viewDidAppear, which is after your scrollview is actually drawn on screen. You only care about animations when the user can see them!

How To Present Half Screen Modal View?

I have a UIViewController and when a button is pressed, I want a half screen view to slide up with a UIPicker in it.
I made a UIView in IB with the UIPicker along with a UIToolBar with Done/Cancel buttons.
How can I make it so that just this half view slides up and the background view is still showing but dimmed or cant be played with.
I'm using this code so far:
- (void)showModalView
{
[self.popupView setFrame:CGRectMake(0, self.view.frame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:self.popupView];
[UIView animateWithDuration:.2 animations:^{
[self.popupView setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
}];
}
Here is a pic: http://www.box.net/shared/static/08ji4s0f6i1b8qubrtz6.png
#Jon:
METHOD-1:
Make your main view transperant by setting its alpha value to 0 and add a subview to the main view which is only half of the main screen and keep it opaque (alpha value as 1) as it would be by default.
Then simply present the view controller using present Modal View Controller.
Keep in mind that because of the transperancy you would be able to see half of the previous view, but wont be able to touch it as there is a transperant view.
METHOD-2:
Another work around is to animate a UIView which is of size half of the existing view.
Then you have to simply follow animation of the UIView.
Here as it is just a UIView that will be added as subview to existing view, you will be able to touch the rest of the screen.
So you can follow either of the methods as per your requirement.
Hope this helps you.
Here is what u need its an open source code on github TDSemiModalView having a half view date picker. Check the demo project inside the code. Here is the link.. Hope it solves your problem.
TDSemiModalClass

UIView subview is not autorotating or auto-sizing for iPad

In my iPhone app, I have a UIViewController with two subviews: a main UIView (let's call it mainView), and a secondary UIView (let's call it secondView), which is usually hidden but is sometimes shown (e.g. user settings). In my UIViewController, self.view is set to mainView. When the user switches to the subview, I call [self.view addSubview:secondView] and when the user switches back to the main UIView, I call [secondView removeFromSuperview].
There are two issues which I am dealing with at present:
When the user rotates the iPhone or iPad, the main UIView (mainView) autorotates properly and all of its UI items follow its autoresize rules which I have set up in Interface Builder. However, when the secondary UIView (secondView) is displayed, and the iPhone or iPad is rotated, the secondView & all of its UI items do not follow their autoresize rules. I have found that when I set self.view = secondView, and then rotate the device, the view rotates properly.
In the iPad specifically, when I pull up the secondView using [self.view addSubview:secondView], it is not resized to fill the full screen just as the main UIView has been resized for the iPad version. So I end up with a screen that displays the mainView UIView in the background, and the secondView UIView in the top-left corner without taking up the whole screen.
My instinct tells me that these two issues are related to one another. Has anyone else experienced these kinds of issues with secondary UIViews which they add to their UIViewControllers using addSubview:?
When using addSubview,
[secondView setFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
Not very elegant. But it worked for me:
I had a similar problem. I solved the size issue by setting the content mode of the view.
Exp:[_yourView setContentMode:UIViewContentModeScaleAspectFill];
I hope this helps...

UIView Subview Does not autoresize on orientation change

In my iPhone app, I have a view controller with two views (essentially, a front & back view). The front view is the main UIView, and the back view is a secondary UIView which is added as a subview using [self.view addSubview:backView] when showing the back and [backView removeFromSuperview] when hiding it. However, when the orientation changes, I have the following issue: the main UIView (frontView) rotates & all of its elements resize properly, but the secondary/subview UIView (backView) does not rotate & all of its elements do not resize properly. Does anyone have suggestions on how to make the secondary UIView autoresize properly according to the rules I have set in Interface Builder?
In the end, the solution I found was simply to separate my UIViews into separate UIViewControllers, and make sure that any views that I wanted to be able to rotate only had one UIView.
If I understand correctly, at the time of rotation 'backView' has been removed from it's superview, yeah? If so, that's the cause of the problem. The autoresize property determines how the view resizes relative to it's superview. If it doesn't have a superview it won't resize.
Perhaps using [backView setHidden:YES] instead of [backView removeFromSuperview] will be sufficient for your needs.
I had the same problem, here is how I fixed it based on imaginaryboy's
suggestions (thanks!)
Add the backview to the viewcontroller at viewDidLoad and hide it at the same time. Show it when needed, Hide it again. Set the resizing of the backview to UIViewAutoresizingFlexibleWidth in IB (or code I guess, I used IB)
Not that this is the same problem, but I found a similar problem when adding 2 subviews in my application:didFinishLaunchingWithOptions method. Since your reference above is using [self.view addSubview:view], I would understand that to mean that self is not your UIWindow. When adding an additional view controller to your App Delegate window (UIWindow), the second view controller will NOT receive any rotation events and will never rotate. Only the first view controller added to UIWindow will rotate. See:Technical Q&A QA1688 I believe this also affects views added after the first view where the first view is later removed from the superview.
I ended up following the suggestion I read elsewhere to use separate views for each orientation, thereby eliminating the need to worry about resizing behavior. As always, YMMV.
Or; if you want to avoid an additional controller, you can achieve the same effect by setting view.frame in willRotateToInterfaceOrientation:: like so
if(UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) ;//set stubborn view.frame for landscape orientation
else ; //set stubborn view.frame for portrait orientation
Although it feels like a hack; it's simple.