I'm working on a iPad project(xcode 7.21+iOS9) and NSNotificationCenter doesn't work.
When user open my app, the tab bar controller will appear.
- (void)viewWillAppear:(BOOL)animated {
if (false == [[MyClass sharedData] getLoginStatus])
{
LoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"myCustomPopoverLoginVC"];
loginViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:loginViewController animated:YES completion:^{
}];
...
}
}
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationLogin:) name:#"afterLogin" object:nil];
[super viewDidLoad];
...
}
-(void)notificationLogin:(NSNotification *)notification{
NSLog(#"OhOhOh");
}
In my loginView,
-(IBAction)login:(id)sender{
...
[[NSNotificationCenter defaultCenter] postNotificationName:#"afterLogin" object:nil];
...
}
First of all:
- (void)viewWillAppear:(BOOL)animated {
if (false == [[MyClass sharedData] getLoginStatus])
{
LoginViewController *loginViewController = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"myCustomPopoverLoginVC"];
loginViewController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:loginViewController animated:YES completion:^{
}];
...
}
}
- (void)viewDidLoad
{
// Add log here to check when its called
-------> NSLog("Add Observer");
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationLogin:) name:#"afterLogin" object:nil];
[super viewDidLoad];
...
}
-(void)notificationLogin:(NSNotification *)notification{
NSLog(#"OhOhOh");
}
then add another log here :
-(IBAction)login:(id)sender{
...
-------> NSLog("Post notification");
[[NSNotificationCenter defaultCenter] postNotificationName:#"afterLogin" object:nil];
...
}
So you can check what called first. Then refer #Sandeep Kumar comment :))
NSNotificationCenter doesn't work in popup view(ios objC)
Related
I am doing one application. In that I used the AVPlayerViewController to play the video. But its not dismiss after play the video.
Please check the my source:
_player = [AVPlayer playerWithURL:self.videoURL];
_avVideoController = [[AVPlayerViewController alloc]init];
_avVideoController.view.frame = self.view.frame;
_avVideoController.delegate =self;
_avVideoController.player.actionAtItemEnd = AVPlayerActionAtItemEndAdvance;
_avVideoController.player = _player;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_avVideoController.player currentItem]];
[_player play];
[self.view addSubview:_avVideoController.view];
[self presentViewController:_avVideoController animated:YES completion:nil];
- (void)playerItemDidReachEnd:(NSNotification *)notification
{
[_avVideoController dismissViewControllerAnimated:YES completion:nil];
[_avVideoController.view removeFromSuperview];
NSLog(#"IT REACHED THE END");
}
After this AVPlayerViewController is not dismissing.
Not hundred percent sure, but might be because of NSNotificationCenter still keeps a reference to self. Try to remove observer in
- (void)playerItemDidReachEnd:(NSNotification *)notification function. As of that
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemDidPlayToEndTimeNotification
object:nil];
Currently I am showing a UIAlertView on viewDidLoad, however once it goes into the background and brought back up, it does not appear again. How do I resolve this issue? What delegates do I need and how do I go about doing that?
- (void)viewDidLoad {
[super viewDidLoad];
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:#"Alert!" message:#"This is an Alert!" delegate:nil cancelButtonTitle:#"Cancel!" otherButtonTitles:nil, nil];
[myAlert show];
}
apple doc: UIApplicationDidBecomeActiveNotification
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(yourMethod) name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// don't forget remove it
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
- (void)yourMethod
{
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle:#"Alert!" message:#"This is an Alert!" delegate:nil cancelButtonTitle:#"Cancel!" otherButtonTitles:nil, nil];
[myAlert show];
}
If you want to show Alert only one time when app comes in Foreground or become active than you can write alert code in following method of Appdelegate.
applicationDidBecomeActive
use viewWillAppear method to show alert, if you need to perform this action everytime view appears
You can override viewDidLoad and subscribe to UIApplicationDidBecomeActiveNotification:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(showAlert:) name:UIApplicationDidBecomeActiveNotification object:nil];
[self showAlert:nil];
}
- (void)showAlert:(NSNotification *)noti {
[[[UIAlertView alloc] initWithTitle:#"Test" message:#"This is a test" delegate:nil cancelButtonTitle:#"Done" otherButtonTitles: nil] show];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}
AppDelegate.m has default delegates methods ,make use of it.
- (void)applicationWillEnterForeground:(UIApplication *)application{
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
}
I'm working on developing an app that uses the camera for a variety of different purposes. Right now, I'm struggling getting a tidbit of code to run when I launch the application:
UIImagePickerController *imageView = [[UIImagePickerController alloc]init];
imageView.delegate = self;
imageView.sourceType = UIImagePickerControllerSourceTypeCamera;
imageView.showsCameraControls = NO;
[self presentViewController:imageView animated:YES completion:NULL];
I need this to execute on the imageView UIView object at launch so when the application is opened, it goes straight to UIImagePickerController. Here is all of my code for the application:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)applicationDidBecomeActive
{
UIImagePickerController *imageView = [[UIImagePickerController alloc]init];
imageView.delegate = self;
imageView.sourceType = UIImagePickerControllerSourceTypeCamera;
imageView.showsCameraControls = NO;
[self presentViewController:imageView animated:YES completion:NULL];
}
#end
If you want to be informed in any controller, you should listen for UIApplicationDidBecomeActiveNotification or similar notifications.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
to unregister, do
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
in dealloc or whenever you don't want to receive the notification anymore.
If you use storyboards, your app delegate should be like this
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
return YES;
}
//…
#end
if you don't use storyboards your app delegate might be
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[ViewController alloc] init];
return YES;
}
//…
#end
and your view controller
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidBecomeActive)
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIApplicationDidBecomeActiveNotification
object:nil];
}
- (void)applicationDidBecomeActive
{
UIImagePickerController *imageViewPickerController = [[UIImagePickerController alloc] init];
imageViewPickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:imageViewPickerController
animated:NO
completion:NULL];
}
#end
If you want code to run when you launch the app you should put it in:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
If you want the UIImagePickerController to be the first viewController presented you should set it as the window's rootViewController like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Set up imageView here
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
self.window.rootViewController = imageView;
return YES;
}
Use presentViewController if/when you want to present it from another viewController that is already onscreen.
I have a popover, which I present from the TabBarItem thats why I make it in AppDelegate, but I need to reshow popover in new place if the screen orientation has changed. In other places of my app I just use the didRotateFromInterfaceOrientation method, but it doesn't called in AppDelegate. How can I solve this?
I present a popover by this code:
- (BOOL)tabBarController:(UITabBarController *)tabBarController shouldSelectViewController:(UIViewController *)viewController
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
if (viewController == [self.objTabBarController.viewControllers objectAtIndex:2])
{
if (self.settingsPopover == nil) {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main - iPad" bundle: nil];
SettingsViewController *settingsController = [mainStoryboard instantiateViewControllerWithIdentifier: #"SettingsPopover"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:settingsController];
self.settingsPopover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
CGSize tabBarSize = self.objTabBarController.tabBar.frame.size;
CGPoint center = [self.window.rootViewController.view convertPoint:self.objTabBarController.tabBar.center fromView:self.objTabBarController.tabBar.superview];
center.x += 105;
center.y -= tabBarSize.height / 2;
CGRect rect = {center, CGSizeZero};
[self.settingsPopover presentPopoverFromRect:rect inView:self.window.rootViewController.view permittedArrowDirections:UIPopoverArrowDirectionDown animated:YES];
} else {
[self.settingsPopover dismissPopoverAnimated:NO];
self.settingsPopover = nil;
}
return NO;
}
}
return YES;
}
You can register a Notification as follow:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleDidChangeStatusBarOrientationNotification:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
Then, implement it in the AppDelegate:
- (void)handleDidChangeStatusBarOrientationNotification:(NSNotification *)notification;
{
NSLog(#"The orientation changed to %#", [notification.userInfo objectForKey: UIApplicationStatusBarOrientationUserInfoKey]);
}
Enjoy. :)
I've been trying several approaches to get the rotation working as expected but so far I've been facing some problems.
Now I would like to have one class with one xib file containing the 2 orientation views. One for portrait, one for landscape.
I am trying this in my main ViewController (the root controller set in the app delegate. But somehow it's failing : when I rotate, the view is switched but the outlets are not rotated. For instance a simple label from the landscape view will be shown as if the device was in portrait mode.
Here's bits of code :
In my app delegate
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
} else {
//self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil withOrientation:UIInterfaceOrientationPortrait];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
self.window.rootViewController = self.viewController;
In Viewcontroller.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification object:nil];
}
- (void)orientationChanged:(NSNotification *)notification
{
[self performSelector:#selector(updateLandscapeView2) withObject:nil afterDelay:0];
}
- (void)updateLandscapeView2
{
UIDeviceOrientation deviceOrientation = [UIDevice currentDevice].orientation;
if (UIDeviceOrientationIsLandscape(deviceOrientation))
{
self.view = self.landscapeView;
[[NSNotificationCenter defaultCenter] postNotificationName:#"landscape" object:nil];
}
else if (deviceOrientation == UIDeviceOrientationPortrait && isShowingLandscapeView)
{
self.view = self.portraitView;
[[NSNotificationCenter defaultCenter] postNotificationName:#"portrait" object:nil];
}
}
I intend to forward the orientation change to the subviews of Viewcontroller by using local notifications.
Anyway, what am I missing here ? I don't understand why this is failing.
What i have found is that when you call
[UIDevice currentDevice].orientation
inside the context of a
[viewController performSelector .....]
It didn't work.
Some body with a solution for these?