destroy uiviewcontroller containing UIWebView when playing video? - iphone

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

Related

iOS: Animation is effecting my other ViewController for some odd reason

I do not know why my NewViewController is getting my ViewController's animations. Everything in my NewViewController.xib is acting strange.For example, my UITableView is popping in with an ease in animation as well as other objects. I checked my NewViewController and it is NOT hooked up with my ViewController. If you have any suggestions on how to stop this I will appreciate it.
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[self start];
}
-(void)start{
CGContextRef *imageContext = UIGraphicsGetCurrentContext();
[UIView beginAnimations:nil context:imageContext];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDelegate:self];
image.alpha = 1;
image1.alpha = 1;
[self performSelector:#selector(change) withObject:nil afterDelay:3];
}
-(void)change{
NewViewController *newViewController = [[NewViewController alloc]init];
[self.navigationController pushViewController:newViewController animated:NO];
}
Your new view controller is pushed during an animation from view controller. Thus, it is not surprising that you get results that affect the new controller. You will need to move your new view controller creation and presentation out of the animation.
Also, I do not see where you call [UIView commitAnimations] to properly finish the animation block.
Also, you are calling interface animations in viewDidLoad when maybe the view is not even visible yet, again with unpredictable results. Instead, you should be calling initial animations in viewDidAppear.
Just to clarify, how is your NewViewController springing into existence?
It sounds like you have a nib file set up for it, but are then calling it in your code with init, as opposed to initWithNibNamed.
It also sounds like you may have included an instance of NewViewController from within your navigationController's nib as well, although I can't quite tell if that's the case from your statements.
To summarize, it looks like you may be using 2 or 3 different ways to create an instance of NewViewController, when you only need to do it once.
I'll go out on a limb and assume that you'd like to use the custom designed NewViewController.xib file that you've made. If so, you'd want to do this:
Make sure there are no ViewController objects in your navigation controller with a class of NewViewController.
You don't technically have to add a property or instance variable to your class of type NewViewController, since the navigationController will take over the retain count once you push, but there's a really good chance you'll want to have the NewViewController scoped to your class anyway to handle events later / reuse, etc...
When you create an instance of NewViewController, instantiate it from the nib like this (note I've assumed you've declared #property (strong, nonatomic) NewViewController* nvc;)
-
nvc = [[NewViewController alloc] initWithNibNamed:#"nameOfNibGoesHereWithoutAppendingDotXib" bundle:[NSBundle mainBundle]];
Now when newViewController loads, you should see it behaving like you laid out in your Nib.
I made a lot of assumptions here, feel free to correct and re-direct your question as needed, and we'll try to help!

ViewController with NavigationController loops to itself

To put it simply, I've built an app which started without a Navigation Controller so everything was controlled through my ViewController. Since adding the Navigation Controller, I added a button to flip to my main Navigation Controller window from my ViewController. However, when I push the button, it reloads the same window with the Navigation Bar now across the top(I hid it in the original view). If I push the same button again, it then loads the proper view. What did I do wrong to cause this loop?
My button's code below
-(IBAction) btnSettings_Clicked: (id) sender {
self.navigationController.navigationBarHidden = FALSE;
[UIView beginAnimations:#"Flip View" context:nil];
[UIView setAnimationDuration:1.25];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
MyAppDelegate* appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:[self.navigationController view] cache:YES];
[UIView commitAnimations];
[appDelegate.navigationController popViewControllerAnimated:NO]; }
If this code is in ViewController and, as you say, this controller is not pushed on a navigation controller, then the error is:
[self.navigationController view] ;
because there are no navigation controller for self. You have to replace it with:
[appDelegate.navigationController view] ;
As I asume that is the correct navigation controller to use.
And then, why are you popping the top view controller? If you want to remove self.view, then you only have to do it:
[self.view removeFromSuperview];
I believe it is this line
[self.navigationController view]
You should set the animation to the controller you wish to show and not to the current controller.

Flip View error - accessing unknown getter method

I am having a view called NView on which I am having a design button clicking on which I want another view DView in flipview, but it's not working. Below is my code. I got an error called accessing unknown getter method:
NSLog(#"yuppii");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:([NView superview] ? UIViewAnimationTransitionFlipFromLeft : UIViewAnimationTransitionFlipFromRight)
forView: DView cache:YES];
It's probably because you aren't using a container view as the transition view. Refer to the documentation on setAnimationTransition:forView:cache:
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:
1. Begin an animation block.
2. Set the transition on the container view.
3. Remove the subview from the container view.
4. Add the new subview to the container view.
5. Commit the animation block.
Try using self.view.superview in the animation transition view of the showMoreInfo:
The reason the showLessInfo: method works is you are using a container view.
or use this way-may be helped u......
CustomViewController *vc = [[CustomViewController alloc]
initWithNibName:#"CustomViewController" bundle:nil];
vc.delegate = self;
// The magic statement. This will flip from right to left.
// present the modal view controller then when you dismissModalViewController
// it will transition flip from left to right. Simple and elegant.
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:vc animated:YES];
[vc release];

how to go to the new view controller using UIWindow?

i have coded following in appDelegeate .m file .but i cant run presentModalViewController method.if i run [self.window addSubview:mview] ,it does not show the result..?any help
to go from one controller to another controller?here mtController is Navigationcontroller.
- (void)flip
{
MViewController *mview = [[MViewController alloc] init];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:2.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft
forView:window
cache:YES];
[mtController.view removeFromSuperview];
[self.window addSubview:mview];
// [self presentModalViewController:mailView animated:YES];
[UIView commitAnimations];
[mailView release]
}
If you want to add a NavigationController to a window you are supposed to call
[self.window addSubview:mview.view];
And if you want to go from one view in a NavigationController to another view, the correct thing to do would be to push the new ViewController.
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
In your code sample you create an object called mview, but then below in the presentModalViewController you reference mailView (and in the release). Is that a mistake?
After you add the mview.view to the window, is it the only view on the stack? If not, you might need to bring it to the front. Also, assuming the release statement at the bottom was meant to be [mview release] you're going to have another problem if you don't save/retain that view controller. I don't believe adding it to the window subviews retains it.

How to animate View swap on simple View iPhone App?

Have a simple iPhone app with a single UIViewController and two Views in one xib.
the first view is very simple with a button and upon button press the second more complex view is loaded via setting the view property on the controller.
what I would like is to animate the view swap (flip the views).
The samples I have seen all require having multiple view controllers and building a hierachy, but that would be overkill in this case, any suggestions?
Make sure you declare IBOutlets for the two views in your view controller I am assuming that in your xib you have a 'container view' that occupies the whole screen, and two views of the same size that you add to this contatiner (one for each side of your 'flip'):
//Inside your .h:
IBOutlet UIView *firstView;
IBOutlet UIView *secondView;
Make sure on initial load you have the firstView show up:
-(void) viewDidLoad {
NSAssert(firstView && seconView, #"Whoops: Are first View and Second View Wired in IB?");
[self.view addSubview: firstView]; //Lets make sure that the first view is shown
[secondView removeFromSuperview]; //Lets make sure that the second View is not shown at first
}
Then you can wire up a button like this, make sure the button is wired to this metod in IB:
-(IBAction) flipButtonPressed:(id) sender {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
if ([firstView superview]) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:YES];
[firstView removeFromSuperview];
[self.view addSubview:secondView];
}
else if ([secondView superview]) {
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:YES];
[secondView removeFromSuperview];
[self.view addSubview:firstView];
}
[UIView commitAnimations];
}