Properly remove view, and add subview - objective-c

Im trying to add a subview, and then also remove the previous view.
here is what my code looks like:
HowToPlay *LetsPlay = [[HowToPlay alloc] initWithNibName:#"HowToPlay" bundle:nil];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight
forView:[self view]
cache:YES];
[UIView commitAnimations];
MainViewController *ma = [[MainViewController alloc]init];
[ma.view removeFromSuperview];
[self.view addSubview:LetsPlay.view];
The Mainviewcontroller is the view that its currently on. I want it to dismiss that view, then go ahead and add the new view LetsPlay.
This code runs, and it loads a new view, but when i then load another view from LetsPlay i can see that the mainviewcontroller is still running behind it. I want to permanently dismiss it.
Also im not even sure if im going about this correctly, so if im not could you please give me an example of how to do it correctly.
Thanks :)

You're not going at it the right way: you're creating a new instance of MainViewController (and also of its associated view). You're then attempting to remove this newly created view (call it instance2) from its superview while it hasn't even been added to a view (instance1 has). This is why you're still seeing mainviewcontroller.
Instead, you need to get a hold of the currently running/active MainViewController. I.e. you should be holding on to a reference of that view controller. Then you can call removeFromSuperview on its view.
Hope this helps.

Related

What is a difference between self.view and self.view .superview of a rootViewController?

I have a view controller which is assigned as a rootViewController like below :
self.viewCntrl = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
self.window.rootViewController = self.viewCntrl;
And in the same view controller i have a button and i am performing transition animation on button click like this:
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
but it not works when i write like this:
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
As here self is a ViewController's object, the ViewController which is nothing but assigned to self.window.rootViewController. So why it takes self.view.superview instead of self.view to animate?
Depending on the kind of animation you are trying to execute, possibly the answer is here:
If you want to change the appearance of a view during a transition—for example, flip from one view to another—then use a container view, an instance of UIView, as follows:
Begin an animation block.
Set the transition on the container view.
Remove the subview from the container view.
Add the new subview to the container view.
Commit the animation block.

Become first responder without animation

Is there a way for a UITextField to become first responder without the animation of the keyboard? That is, make it such that the keyboard just appears?
Basically, I'm pushing a second UIViewController over the UIViewController that has the UITextField, and when that second view controller gets popped off the stack, I want the UITextField to immediately have first responder status so that when the second view controller gets popped, the user never notices the text field wasn't first responder.
Right now I have it so that when it's popped, the keyboard animates up the screen, but I don't want that to be seen.
Any ideas?
You can use a UIView animation like so
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.0];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[textField becomeFirstResponder]; // <---- Only edit this line
[UIView commitAnimations];
This will cause the keyboard to suddenly appear.
You can do the same but with -resignFirstResponder
Swift ..
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationDuration(0.0)
UIView.setAnimationDelay(0.0)
someTextView.resignFirstResponder()
UIView.commitAnimations()
Just set it as the first responder in -viewDidAppear to make the user never notice the field having lost its status.
-(void)viewWillAppear:(BOOL)animated {
if ([self isViewLoaded] && self.textField)
[self.textField becomeFirstResponder];
[super viewWillAppear:animated];
}
I've put a short sample project up on dropbox using this code, if you'd like it.
I'm, mot sure what iOS version do you use or at what point do you call becomeFirstResponder
Calling [textFieldReference becomeFirstResponder] in viewWillAppear: for iOS5/iOS6 seems to work just the way you wanted it to:
it's being called just before view controller will show it's view (that's if you don't handle view controller hierarchy manually) and as soon as it appears in navigation controller keyboard is already presented and text field has focus.
That said, there is no public way that I heard off that would allow to specify keyboard appearance style.
I don't think this was an option when the question was first asked, but UIView.performWithoutAnimation works appropriately.
UIView.performWithoutAnimation {
self.composeView.focusTextField()
}

Using buttons on different views and classes to trigger view switch from the main view controller

I am using storyboard to create my page.. each with it's own class... from the mainViewController, I manage the view change with a swipe gesture recognizer... So far so good... But I have certain pages that will appear as "popup" when swiping up and to get rid of them, the user clicks on the X to remove the view... the thing is that doing this and releasing the view from superview is giving me a white screen as the switch is not done by the mainViewController, since the view is release by the popup class... I think I need to use some sort of delegation to do this.. but my brain just doesn't want to sink in how to use the delegate thing, even after reading about it...
Since the view switching is done on index 1, i'd figure that if I put those popup on index 2 and release them, the view at index 1 would still be there, but.. no..
... so at the beginning of my swipe gesture function, I start declaring the animation process... then I have a switch...case that check for the gesture being done.. left will set the animation to curlUP and right to Curl down... this is what happens after the switch... I also put myView into a myViewTemp, and add the new view to myView in the switch..case statement..
if (myView.title == #"popup1") {
[myView viewWillAppear:YES];
[myViewTemp viewWillDisappear:NO];
// [myViewTemp.view removeFromSuperview];
[self.view insertSubview:myView.view atIndex:2];
[myViewTemp viewDidDisappear:NO];
[myView viewDidAppear:YES];
} else {
[myView viewWillAppear:YES];
[myViewTemp viewWillDisappear:YES];
[myViewTemp.view removeFromSuperview];
[self.view insertSubview:myView.view atIndex:1];
[myView viewDidDisappear:YES];
[myViewTemp viewDidAppear:YES];
}
[UIView commitAnimations];
}

UIViewController present another UIViewController

I Have a UIViewController 1 on it UIButton (added as subview), after I pressed Button (see pic.1 below) on it adding another UIViewController 2 with animation from the bottom to top after some action:
[[[UIApplication sharedApplication] keyWindow] addSubview:self.view];
And it overlaps UIButton, how can I add this subview that it does not cover UIButton(see pic.2 below)
pic.1:
pic. 2:
You haven't shown the animation code but I assume you add the subview off-screen, then change it's frame (animated) to slide it into view.
Add the new subview using insertSubview:belowSubview: instead, passing your button as the second argument. This way the button will overlap the new view, instead of the other way round. addSubview: always puts the new view on top of any others.
EDIT
From your comments it seems that you're adding the second view controller to the screen using presentModalViewController: so the above method won't work. As far as I know there is no way to keep an element from the original view controller on top of the new view controller's view if you are presenting it this way.
You may have to create a new UIWindow and set it's windowLevel to UIWindowLevelAlert to hold your button. This will keep it on top of any of the views underneath. Add this window as a subview to the main window.
{
SecondViewController *objComing=[[SecondViewController alloc] init];
[self.view addSubview:objComing.view];
objComing.view.backgroundColor=[UIColor blueColor];
objComing.view.frame=CGRectMake(0,420, 320, 0);
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
objComing.view.frame=CGRectMake(0,0, 320, 420);
[UIView commitAnimations];
}
Put this code in the button action and replace secondViewController with your ViewController.

Creating a navigation view in Interface Builder

I'm trying to create a navigation view in the Interface Builder. It's not in the MainWindow.xib, so the relevant sample project on the Apple Dev. site is useless.
The most logical (and cleanest) way to approach this seems to create a Xib-file where the File's Owner is a subclass of UINavigationController - however, I cannot get this to work at all in IB, (because UINavigationController acts as a folder, and File's Owner doesn't, even when I change the class).
Alternatively, I've got a Xib-file where the File's owner is a subclass of a normal ViewController (VCA). I've added a NavigationController with a ViewController that's another subclass of UIViewController (VCB), and I've specified a Xib view for this ViewController. But I have no idea how to specify the view of VCA in IB, and my attempts to do this programmatically haven't worked.
Please help!
I've had trouble doing things like this when I was getting started and the most workable approach I came up with was to create the UINavigationController programmatically. I adapted my code from the iPhone "utility" Xcode template. Here's a bit of it that will hopefully get you going: (edited for brevity; self is a UIViewController)
self.menuViewController = [[[MenuViewController alloc]
initWithNibName:nil bundle:nil] autorelease];
self.navController = [[UINavigationController alloc]
initWithRootViewController:self.menuViewController];
self.navController.navigationBar.barStyle = UIBarStyleBlackOpaque;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1];
[self.view addSubview:self.navController.view];
[UIView commitAnimations];