When I try to present a modal view controller, it functions as its supposed to, but it appears with the wrong orientation and only goes half way along the screen (only the top half of it is showing). The code seems simple enough -
-(void)showAboutView {
AboutViewController *aboutViewController = [[AboutViewController alloc] init];
if (aboutViewController != NULL) {
[self presentModalViewController:aboutViewController animated:YES];
}
}
All the shouldAutorotateToInterfaceOrientation are set to "landscapeRight"
I realise I'm probably doing something really stupid, but I can't figure out what it is... any help gratefully received!
If it's showing up in the wrong orientation, I'd say that you've got an issue in your XIB file for AboutViewController.
Did you create that XIB in a different orientation than your app is currently in? Look at the third tab on the property inspector -- is the autoresizing set up properly?
Related
Hi I am trying to provide screen orientation in my app and I have read many docs online but when I try that It just is a total disaster (I tried emulator and iphone). On one partwhen the screen is rotated to landscape half of the views are not visible any more. Their position is on the left side and right side is empty, plus if I open a next view controller and then rotate again I can see through the second view parts of the first view it just is terrible I don't know how to fix it (Excluding blocking the possibility to lock orientation in portrait).
I know in android you can provide different xml layouts for portrait and landscape. Is there a way to fo that in iphone? If so how?
each of my views are composed of a controller and .xib
There is a "main" controller and the other controllers are called like that:
ayuda=[[AyudaView alloc]
initWithNibName:#"AyudaView"
bundle:nil];
[self.view addSubview:ayuda.view];
also I have already added these metods to the maincontroller:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if(UIDeviceOrientationIsValidInterfaceOrientation(orientation)) {
[self handleInterfaceRotationForOrientation:orientation];
}
}
#pragma mark -
#pragma mark Screen Orientation Handling
- (void)handleInterfaceRotationForOrientation:(UIInterfaceOrientation)interfaceOrientation {
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
[self handleInterfaceRotationForOrientation:interfaceOrientation];
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
[self handleInterfaceRotationForOrientation:toInterfaceOrientation];
}
as indicated here
and have tried to play with the autosizing param but it only gets worse
Thank you very much
EDIT: ok I have been reading some more:
http://www.geckogeek.fr/iphone-forcer-le-mode-landscape-ou-portrait-en-cours-dexecution.html
http://www.cocoaosx.com/2011/11/10/rotatingviewcontroller-display-a-different-uiviewcontroller-depending-on-the-rotation-of-the-device/
and basically what I have found is that you have to create 2 controllers but this solution is problematic for me because of the nib files. I mean I would also have to create 2 nibs so double the amount of code (or use the library above). What if I have values in my textfields , do I just have to send them around?
So, apart from the comments suggesting you don't have any idea about what's going on in your code (which may or may not be true -- who am I to judge?), I see a few problems.
The first issue is that I don't think you understand MVC and how iOS handles the view hierarchy. You're correct in having each of your views controlled by a controller and designed by a .xib (there are cases where a view doesn't need its own controller, but for simplicity, we'll assume yours do). However, you are incorrect in the way you are presenting those views on screen. A view's controller is responsible for presenting or removing a view from the screen. The view only knows what it displays, such as labels or buttons. The controller is responsible for telling the view what to display on those labels and buttons. Instead of adding the new VC's view as a subview of your main view, push it onto a navigation controller's stack or present the view modally. If you're in your main VC, you can say
ayuda = [[AyudaView alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:ayuda animated:YES];
I'm thinking that getting the view hierarchy correct might just be enough to solve your landscape/portrait swapping chaos. But while we're on that topic...why are you creating this handleInterfaceRotation method? View Controllers already have a method for this called
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
Use this method to handle rotation.
I have the beginnings of my app working pretty well but I have one small issue that I can't figure out how to fix.
It's a view based app and I have a NavigationController in my appDelegate file which is pushing various ViewControllers as required. Going in the "forwards direction" everything works well, seems perfect actually, but the problem I have is when VC's are popped off the stack. This is the code I'm using to show the VC and then just using the back button to go back.
UINavigationController *iaxNC = [[UINavigationController alloc] init];
LogInViewController *logInVC = [[LogInViewController alloc] init];
[iaxNC pushViewController:logInVC animated:NO];
[logInVC release];
[_window addSubview:iaxNC.view];
[_window makeKeyAndVisible];
That loads my login view and then the code checks to see if there are any users before it loads the SetUp screen (if there are none) as follows:
setUpVC = [[SetUpViewController alloc] init];
setUpVC.firstUse = self.firstUse;
[self.navigationController pushViewController:setUpVC animated:YES];
[setUpVC release];
The problem happens when I hit the back button from the SetUp view to go back to the LogIn view.
I have a portrait and a landscape view for most of the VC's and these VC's are subclasses of Michael Tyson's TPMultiLayoutViewController. The portrait view is hooked up as *portraitView and also as *view, the landscape view is hooked up as *landscapeView.
The problem is this:
If I push a VC into view and change the orientation of the device before I hit the back button then when I do hit "Back" the previous VC is displayed in its original format (i.e. NOT rotated to the current orientation) it also appears that the lower left corner of the view is in the lower left of the screen. It then "sticks" like that until I rotate the device again and then all is good and functions as expected.
So the thing is I'm working through the contents of the TPMultiView subclass but I don't pretend to understand all of it yet (and therein probably lies my REAL problem) but as a stopgap solution is there a way to force the view of the "pusher" VC to appear in it's previous orientation (albeit briefly - and THEN allow it to rotate once it has been displayed) when the "pushee's" VC is popped?
Does that make sense?
SOLVED IT! The problem was I had included my own viewWillAppear method in LogInVC but I hadn't called [super viewWillAppear] so the effect of the superclass was never really going to work, was it! Thanks for the input. I can recommend the TPMultiView drop in subclass BTW works very nicely.
You should first verify your implementation of shouldAutoRotateToInterfaceOrientation: is correct for all your view controllers.
Then make sure the views of your view controller's have an appropriate autoresizingMask set. If you have created the view controllers and their views in Interface Builder you should set the resizing mask there.
Otherwise in your -loadView or -viewDidLoad methods you should have this line:
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
I'm very new to xCode and objective-C so I wanted to make a simple textRPG.
I'm currently making a character creation process consisting of 4 xib-files. The only way I got switching views to work was to look at the utility-template. Problem is, now I have the first screen being the delegate for the second screen, being the delegate for the third screen etc. So by the end of the character creation process I can't dismiss the views because that just "steps back" through the views.
When I've searched around for a solution I've found a addSubview-method but it seems like that makes a new view, like, empty to arrange programmatically.
All I need is a simple way to switch from one loaded xib to another xib. Have I misunderstood addSubview or do I need something completely different?
(If it helps: I've worked with VB for several years, in case you notice that I missed some kind of concept concerning views and such)
Thanks in advance! :)
Use this code. It is really simple and works well.
View *view = [[View alloc] initWithNibName:#"xibNameGoesHere" bundle:nil];
view.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:view animated:YES completion:nil];
This will switch to another xib file and the two views won't own one another. I am using it in my own game right now.
#Joakim Ok, this is the way I do it. I have a class called RootViewController : UIViewContoller, whose view I add directly to the window. Then I make a subclass of UIView i.e. MyView. All of my views then subclass MyView. I also make an enum for all my views. In RootViewController you should have a switchView:(int)view method that looks something like this:
-(void) switchView:(myView) view
{
[_currentView removeFromSuperview];
switch(view)
{
case titleView:
_currentView = [[TitleView alloc] initWithRoot:self];
break;
case homeView:
_currentView = [[HomeView alloc] initWithRoot:self];
break;
default: break;
}
[self.view addSubview:_currentView];
[_currentView release];
}
in #interface RootViewContoller define MyView *_currentView;
TitleView and HomeView both subclass MyView and have a common method -(id)initWithRoot:(RootViewController*) rvc.
To switch between views use [_rvc switchView:homeView];
Hope this helps :)
It is called UINavigationController. Idea is
1) You push corresponding 'next' controller into navigation controller each time user submits current screen. Bonus - you'll get 'back' button for free on each step of character creation.
2) After character is created you pop all character creation controllers from stack.
Please read View Controller Programming Guide for iOS before trying to 'switch views' and such. You'll save tons of time and nerves.
another idea is not to use interface builder at all. i have been working with iphone apps for two years now and found that interface builder really prolongs the time to actually make something. make your own root controller and think about the logic you need to navigate through the views.
I've finally gotten a working "alpha" version of my first app installed and (mostly) working on my iPhone 3G. So excited I came into the house and danced a little jig while my wife rolled her eyes at me. Don't care - totally stoked that I figured it out on my own (with lots of help here - thanks again, guys).
I've never really dabbled with or cared about animation; I'm more into utility-type apps. However, I've decided that I'd like to animate my app's opening image / default.png / splash screen similar to the flipside view controller animation - where the image spins from a view on the front to a different view on the back. I've found code for animating between views using the flipside animation, but how would I go about animating from a static *.png image to my navigation-based table view? I'm just not even sure where to start with this one - literally the first time I've ever even searched for anything graphics-related in the documentation.
Any help will be appreciated. As usual, thanks in advance!
You can't do anything with your Default.png, and just for form I'll point out that that HIG guidelines say that you shouldn't use it as a splash screen :-).
I would suggest that you use your initial view controller to duplicate the Default.png, and copy the flip animation code from a basic Utility app template - you probably want to use [NSObject performSelector:#selector(...) afterDelay:0] to get it to flip, called from your initial viewDidLoad:.
You can just present a modal view controller when you first launch using the flip transition instead of the default slide. Have your initial view controller loaded from your xib just display the same image you are using for your Default.png. Once you get the -viewDidLoad call in your initial view controller, push the modal view specifying the transition you want. Something like this:
- (void)showMainView;
{
MainViewController *controller = [[MainViewController alloc] init];
[controller setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentModalViewController:controller animated:YES];
[controller release], controller = nil;
}
As Paul suggested, you should call this using performSelector:withObject:afterDelay:
[self performSelector:#selector(showMainView) withObject:nil afterDelay:0.15];
Hope that helps.
I have a problem, using presentModalViewController to display a UIView. Within the Application I have a NavigationController with a list of Items. Touching a Cell calls the first ViewController, responsible for only showing a background picture. Within the viewDidLoad method I create another ViewController which has a UiScrollView, displaying some information about the item.
So far so good.
Now, an item can consist of subitems, so if I click on a subitem, I use presentModalViewController to create a new instance of the first ViewController. My problem is, that this newly displayed controller is show around 180px(a guess) lower than it should be. I thought, this was due to relative coordinates I set wrong, but if I click on a subitem with the new (lower) controller, I would expect it to be displayed lower again (say 360px) - relative to the topleft corner of the Iphone.
Anyway, this doesnt happen. My question is why is the new controller displayed lower than it should be/I expect it to be. Spent a few hours on this, so any ideas are appreciated!
Edit: Some Code - this is the part, where i present the controller:
ItemDetailsViewController *itemScrl= [[ItemDetailsViewController alloc] initWithNibName:#"ItemDetailsViewController" bundle:nil];
itemScrl.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:itemScrl animated:YES];
This is the part, where I create the scrollable View:
- (void)viewDidLoad {
[super viewDidLoad];
ItemScrollController *itemScrl = [[ItemScrollController alloc] initWithNibName:#"ItemScrollController" bundle:nil];
itemScrl.title = self.title;
itemScrl.view.frame = CGRectMake(20 , 0, 280, 400);
[self.view addSubview:itemScrl.view];
}
I think my problem was, not having added a Navigationbar in the parentviewController and not telling the subview, that there actually was one. There are various ways to do this, I suppose, anyways, in IB you can checkmark the Navigationbar box for the actual view and thus it shouldnt be resizing anything.