How can I get a UIView to transition via addSubview like the presentModalViewController does? The available animations don't seem to do this.
I would use the modal but I have a navigation bar at the top and don't want to disable it. Also, the modal overlays on the navigation bar. If there is a way to have it so the modal doesn't disable the nav bar, I can go with that approach. But since it is a modal, I don't think that is possible.
Pushing a modal view controller with the same navigation state seems like it would break the stack metaphor modeled by the navigation controller, which is weird, but I'll assume you've thought that through.
If you want to just add a subview that animates in from the bottom of the screen, you can do it like this:
CGRect onScreenFrame = viewToAdd.frame;
CGRect offScreenFrame = onScreenFrame;
offScreenFrame.origin.y = self.view.bounds.size.height;
viewToAdd.frame = offScreenFrame;
[UIView beginAnimations:#"FakeModalTransition" context:nil];
[UIView setAnimationDuration:0.5f];
[self.view addSubview:viewToAdd];
viewToAdd.frame = onScreenFrame;
[UIView commitAnimations];
If you use presentModalViewController with a any UIViewController as an argument you will have #property(nonatomic, readonly, retain) UINavigationItem *navigationItem available there and you can copy or create the navigation bar with it.
Related
I'm creating an iPhone app with a standard "Master-Detail" navigation, where you choose an item from a UITableView, and see the Detail view for the item in a ViewController that pushes onto the screen.
However: unlike a traditional UINavigationController, which pushes the detail screen from the right-hand side of the window, I'd like to have my detail screen come down from the top of the screen.
What would I need to accomplish this? Do I have to subclass UINavigationController? (I've heard that's not a good idea). What class(es) should I consider subclassing?
Subclass UINavigationController and override pushViewController:animated:.
Don't immediately call super and do you custom animation stuff like this:
nextViewController.view.transform = CGAffineTransformMakeTranslation(0, -nextViewController.view.frame.size.height);
void(^animationBlock)(void) = ^{
[super pushViewController:nextViewController animated:NO];
nextViewController.view.transform = CGAffineTransformIdentity;
};
if (animated) {
[UIView animateWithDuration:0.3f animations:animationBlock];
}
else{
animationBlock();
}
Update:
You actually don't need to subclass UINavigationController. You also can do the animation stuff above every time you push a VC to a regular UINavigationController.
I have a viewController and I am trying to add a subview to it such that it will cover the whole screen, however this has a navigationController in it so that adding a subView always adds it below the navigation bar, is there a way to simulate a presentModalViewController in cases like this?
You can add the subview to the view controller and then hide the navigation controller from the top or you could still push it to the navigation controller and then just remove the navigation controller from the top again and then you could use pop to go back and forth.
the code to push a view controller is
if(!self.YOURVIEWCONTROLLER){
self.YOURVIEWCONTROLLER = [[YOURVIEWCONTROLLER alloc] initWithNibName:#"YOURVIEWCONTROLLER" bundle:nil] autorelease];
}
[self.navigationController pushViewController:self.YOURVIEWCONTROLLER animatedLYES];
and on the next NEXTView.m add
[self.navigationController setNavigationBarHidden:YES];
remember to create an instance of YOURVIEWCONTROLLER in the .h file. Or you could do a simple
[self.view addSubview:NEWVIEW];
[self.navigationController setNavigationBarHidden:YES];
at least at bear minimum the line for making the navigationController hide is there.
I seem to recall once having a similar problem, and I seem to recall the solution was to add the subview to the navigation controller (as the view controller is already a sub view of the navigation controller) rather than adding it to the view controller.
I recently have similar problems and after spending 5 to 10 min I get the exact solution...
According to my solution I simply add my custom UIView to subview of navigationController.view
Like This :-
[self.navigationController.view addSubview:popOver];
popOver - Your custom UIView
Happy Codding :)
Add the view to the superview of the navigationController's view.
[navigationController.view.superview addSubview:viewController.view];
Perhaps you could hide the navigation bar when you add the subview. I have a method on my ViewController that looks like this:
self.navigationController.navigationBarHidden = YES;
UIView *v = [[UIView alloc] initWithFrame:self.view.frame];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
When that code executes, my navigation bar disappears and a full screen red view replaces it.
I want to slide a UITableVIew into a view (NOT by pushing the view on top of Navigation Controller) on click of a button and then hide it back by sliding , on clicking of the same button.
I want the tableView to slide inside a present view.
You animate the frame property of the table view to move it off screen or back onto screen.
Here is some sample code that moves a table view off screen and moves another on screen in its place:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kSlideTableDuration];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(tableAnimationDidStop:finished:context:)];
self.tableView1.frame = offScreen;
self.tableView2.frame = onScreen;
[UIView commitAnimations];
You can read about animation blocks like this in the UIView documentation.
Check out the documentation of UINavigationController. To implement you would do something similar to this:
iPhoneCustomViewController *newView = [[iPhoneCustomViewController alloc] initWithNibName:#"iPhoneCustomViewController" bundle:nil];
[self.navigationController pushViewController:newView animated:YES];
[newView release];
Then, when your done with the CustomViewController do:
[self.navigationController popViewControllerAnimated:YES];
You get the nice slide animations for free if you use a UINavigationController. It will take care of sliding views in (push them on the navigation controller stack) and sliding them out (pop them off the navigation controller stack).
Hey all... I have a view controller (A) which on some action, alloc init's another view controller (B) and then adds B's view to its view as a subview. So now ViewController B's view is a subview of ViewController A. The problem I have is If I simply remove B's view from A it seems to still stick around for example. View B contains a web view, when I load a video on the webView, even after I remove the view from view Controller A's view I can still hear the video??
How can I destroy viewcontroller B and remove its subview from A? Im finding this tricky as I dont really push it onto a navigationcontroller's stack which I can just pop from... I hope this makes sense, if not please say and I will try and clarify.
Many thanks
Jules
-(void)showNewsWebView:(int)index {
NewsWebViewController *myWebView = [[[NewsWebViewController alloc] initWithNibName:#"NewsWebViewController" bundle:nil]autorelease];
//setup webview with request etc
[[self.view.superview superview] addSubview:myWebView.view];
myWebView.alpha = 0.
[UIView beginAnimations:#"test" context:nil];
[UIView setAnimationDuration:.3];
myWebView.view.alpha = 1.;
[UIView commitAnimations];
}
//called after delegate callback from webviewcontroller
- (void)newsWebViewDismissedView:(NewsWebViewController *)controller {
[UIView beginAnimations:#"test" context:nil];
[UIView setAnimationDuration:.3];
controller.view.alpha = 0.0;
[self performSelector:#selector(removeView:) withObject:controller.view afterDelay:.5];
[UIView commitAnimations];
}
-(void) removeView:(UIView *)view {
[view removeFromSuperview];
view = nil;
}
Does ViewController B really need to be a ViewController?
If you're adding subviews you should probably have B subclass UIView instead of UIViewController. Adding B's view as a subview essentially negates any advantage you'd have of B being a ViewController.
Anyway to answer your question. You might want to make viewcontroller B an ivar of A so that viewcontroller A can manage the memory of viewController B. Once you remove the view of B from A, you can release viewcontroller B from memory (I still don't support this as it sounds like ineffective code. You should probably state what you're aiming to do, and post some code as to how you're doing it so we can help you out better :) )
EDIT:
From your code seems like you should just be pushing and popping. Are you using MyWebViewController just to show a webpage? You might be better off using a simple UIWebView.
I also noticed something wrong in your animation code for setting alpha to 0. If you want some method to be executed after an animation ends you should use the following code:
//called after delegate callback from webviewcontroller
- (void)newsWebViewDismissedView:(NewsWebViewController *)controller {
[UIView beginAnimations:#"test" context:nil];
[UIView setAnimationDuration:.3];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(removeView)];
controller.view.alpha = 0.0;
[UIView commitAnimations];
}
ViewControllerB *vc = [[[ViewControllerB alloc] initWithNibName:#"SomeNib" bundle:nil] autorelease];
This should do the trick. Autoreleasing the view controller at the end of its initial allocation should tell the application to deallocate it after you remove the view from viewcontroller A since nothing else is holding a retain value on it. Though using a navigation controller might be an easier solution if you are willing to rework your code to push and pop the view instead
I have a navigation view controller and I want a subview to slide on top of it when a button in the parent view is clicked. Now, the thing is when I do this:
[parentView addSubview:slideView];
[UIView beginAnimations]
//setting the frame for sliding
[UIView CommitAnimations]
the sliding view goes under the navigation bar after sliding. I would like it to slide on top of the navigation bar of the parent view. How do I achieve this?
Essentially, all I am trying to do is: replicate the iPhone Add Contact application with the only difference being; unlike me, they don't have a navigation controller on the parentView but just a navigation bar with a system add button.
Anyone!!
Hows about using a Modal View Controller....
UsernamePasswordViewController *usernamePasswordView = [[UsernamePasswordViewController alloc] initWithNibName:#"UsernamePassword" bundle:[NSBundle mainBundle]];
[self.navigationController presentModalViewController:usernamePasswordView animated:YES];
[usernamePasswordView release];
This will slide upwards by default over anything
How about something like:
[parentView addSubview:slideView];
[parentView bringSubviewToFront:slideView];
// etc