When i push Back button on Navigation controller app is successfully return to the controller view, but dont stop video streaming.
I write:
- (void)viewDidUnload
{
[self setDescText:nil];
[super viewDidUnload];
[moviePlayerController stop];
[moviePlayerController.view removeFromSuperview];
// Release any retained subviews of the main view.
}
but not help.
Please, give me advice.
viewDidUnload is only called in low-memory conditions. You want viewDidDisappear.
- (void)viewDidDisappear:(BOOL)animated
UIViewController Class Reference
Related
I am using tab bar based iPhone application.I have set NSTimer in first two tabs.i want to invalidate this timer. so i am invalidating in viewDidDisappear. But when i am clicking on different tab, it will never call viewDidDisappear. I don't know how to call this method?please help me...thanking you in advance...
are you put [super viewWillDisappear:animated]; in viewWillDisappear some time it happaned becouse we forget to put this line in to viewWillDisappear
- (void) viewWillDisappear:(BOOL) animated {
[super viewWillDisappear:animated];
}
set time invalid in viewWillDisappear: method , like bellow..
-(void)viewWillDisappear:(BOOL)animated
{
[yourTimer invalidate];
yourTimer = nil;
}
I have a uiwebview that plays a youtube video. How can I handle the done button action?
Right now, when I tap the done button it changes back to my app main menu (not the menu that was supposed to dismiss to) and it just freezes. Can anyone help me please?
Ps: the menu where the uiwebview is located, was previously presented modally.
The YouTube plug-in player is itself a modal view controller. It is returning to its presentingViewController when the done button is pressed. Its presentingViewController is not your modal view controller but is instead the viewController that called [presentModalViewController:animated:] to present your modal view controller. Since the original modal view controller is still active, the app behaves badly.
To fix the problem,
1) Track whether the modal view controller has been presented but not dismissed.
2) In the viewDidAppear method of the presenting view controller, if the modal view controller was presented and not dismissed, dismiss and present it again.
For example, in controller that is presenting the modal web view controller:
- (void) presentModalWebViewController:(BOOL) animated {
// Create webViewController here.
[self presentModalViewController:webViewController animated:animated];
self.modalWebViewPresented = YES;
}
- (void) dismissModalWebViewController:(BOOL) animated {
self.modalWebViewPresented = NO;
[self dismissModalViewControllerAnimated:animated];
}
- (void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.modalWebViewPresented) {
// Note: iOS thinks the previous modal view controller is displayed.
// It must be dismissed first before a new one can be displayed.
// No animation is needed as the YouTube plugin already provides some.
[self dismissModalWebViewController:NO];
[self presentModalWebViewController:NO];
}
}
This thread is very useful and help me to find the problem!
The answer of lambmj works fine, but I found a better way.
In presenting view controller:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (self.presentedViewController) {
UIViewController *vc = self.presentedViewController;
[vc dismissModalViewControllerAnimated:NO];
[self presentModalViewController:vc
animated:NO];
}
}
Hope this helps!
#Gdx Wu
#lambmj
Thanks for your methods, they work fine. But there is some small problem that after clicking the done button & jumping directly to the presenting view controller, we need to dismiss the presented modal view controller and present it again, which would bring some dither(like flash) between these view controller switches.
Based on this, I highly recommend #IsaacCisneros 's method which would switch seamlessly.
Simply remove UIWebView when it enters full screen; add back UIWebView when it exit full screen. Sample code below assuming a UIViewController with subview of UIWebView, and your UIWebView should have youtube iframe.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Add observer for "Done" button click
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerWillExitFullscreen:)
name:#"UIMoviePlayerControllerWillExitFullscreenNotification"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerDidEnterFullscreen:)
name:#"UIMoviePlayerControllerDidEnterFullscreenNotification"
object:nil];
}
- (void)viewDidDisappear:(BOOL)animated {
// Remove observers for "Done" button click
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
}
- (void)playerWillExitFullscreen:(NSNotification *)notification {
// Before exit full screen, add back UIWebView that have been removed earlier
[self.view addSubview:self.webView];
}
- (void)playerDidEnterFullscreen:(NSNotification *)notification {
if (self.presentingViewController) { // UIWebView is presenting the build-in movie player controller
[self.webView removeFromSuperview]; // Built-in movie player controller is already entering full screen mode
}
}
I have a view with a navigation bar in my iphone app. The navigation bar has a back button on it to go the the previous view. Within the view is a webview. If the webview is loading while the user presses the back button on the navigation bar, the app crashes with the error message:
[WebViewController respondsToSelector:]: message sent to deallocated instance
I am assuming that I release some things when the view unloads. I believe my viewWillDisapear method takes care of stopping the webview from loading... But still, when I press back while the view is not fully loaded, it crashes.
It seems to happen when I let the view finish loading about 20% of the time - and only if I press the back button really quickly after the page finishes loading.
Here is the code that I believe runs during this shinanigans....:
- (void)viewDidLoad {
[super viewDidLoad];
webView.scalesPageToFit = YES;
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString: url]]];
[addressBar setText:url];
}
and then when the webview is loading:
- (void)webViewDidStartLoad:(UIWebView *)webView {
if (first) {
//mtns is a uiimageview
mtns.alpha = .8;
first = NO;
}
[activityIndicator startAnimating];
}
and after a suggestion, I added this method:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.webView stopLoading];
self.webView.delegate = nil;
}
I don't know why it is crashing so I am sort of at a loss
Thanks,
R
You could override -viewWillDisappear: to stop the UIWebView from loading and set the delegate to nil.
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[self.webView stopLoading];
self.webView.delegate = nil;
}
This may be because of before the execution code that you have written in viewwillDisapper application crashes.try to put breakpoint and check whether viewwillDisapper method is called or not.If its not called then write the code that mark has suggested before the application navigates to second view controller.
You have to be sure to set the delegate property of the web view to nil before it goes away. Do this both in your dealloc and viewDidUnload methods, since viewDidUnload is not always called before dealloc. What’s happening is that after your view controller is deallocated, the web view still has a reference to its address, and is trying to send it a message (-respondsToSelector:).
- (void)dealloc {
webView.delegate = nil;
[super dealloc];
}
- (void)viewDidUnload {
webView.delegate = nil;
[super viewDidUnload];
}
I need to fully UNLOAD the flipview don't ask me why but i NEED to. i have tried [super release]; and it didnt work below is my back button and then the did finish. Please help me to unload the view.
on the first view which gets activated once the flipview has finished.
- (void)flipViewControllerDidFinish:(FlipViewController *)controller
{
[self dismissModalViewControllerAnimated:YES];
}
on the flip view which is a button that hides the flip view just hides doesn't unload
- (IBAction)Back:(id)sender
{
[self.delegate flipViewControllerDidFinish:self];
}
[myFlipViewController.view removeFromSuperview];
On Facebook's iPhone app, the news feed refreshes every time the app becomes active. I would like to do something similar, but I'm concerned about a race condition. The general bootstrapping of my app is as follows:
UIApplicationDelegate
- (void)applicationDidFinishLaunching:(UIApplication*)application
{
[window addSubview:[self.navigationController view];
[window makeKeyAndVisible];
}
- (void)applicationDidBecomeActive:(UIApplication*)application
{
[rootViewController refresh];
}
RootViewController
#pragma mark custom
- (void)refresh
{
if (self.newsFeedModel == nil) {
self.newsFeedModel = [[NewsFeedModel alloc] initWithDelegate:self];
}
[self.newsFeedModel request];
}
#pragma mark UIViewController
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
}
#pragma mark NewsFeedDelegate
- (void)newsFeedSucceeded:(NSMutableArray*)feed
{
// reload table view with new feed data
}
After sprinkling NSLog everywhere, I determined the order of operations to be:
applicationDidFinishLaunching
applicationDidBecomeActive
refresh
viewDidLoad
newsFeedSucceeded
Notice how refresh is called before the root view has been loaded. While we're busy querying the server, the root view loads. When the server responds, the root view is populated with the feed. This works in most cases because the network operation takes a long time. However, if the network operation finishes faster than view can be loaded, then I will be attempting to construct the news feed before the view has been loaded. This would be bad. What is the best Cocoa Touch practice for solving this race condition? I would just set a bunch of flags to determine what state we're in and refresh the news feed depending on the state, but I'm wondering if there were built in events in Cocoa Touch to handle this for me.
I think you want to take a look at applicationWillEnterForeground: instead.
applicationDidBecomeActive: can be called while your app is still running in the foreground. For instance if a text message comes while your app is in the foreground and the user dismisses it, applicationDidBecomeActive: will get called.
You can subscribe to the UIApplicationWillEnterForegroundNotification event in your RootViewController using NSNotificationCenter. I would do this in RootViewController initWithNibName: or whichever init method you are using.
Now you just need to call refresh in 2 places. Once at the end of viewDidLoad and again whenever applicationWillEnterForeground: is called.
This should solve your race condition problem. Since RootViewController is handling it's own refreshing when it knows it is ok to do so.
RootViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
}
return self;
}
- (void)viewDidLoad
{
// initialize the table
// add subviews and whatnot
[self refresh];
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
[self refresh];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}