I want to write a simple menubar app for Mac OS X. The user will only want to use that app when Safari is opened. To not clutter the menubar unnecessarily, I want to hide and show the menubar icon depending on whether Safari is open or not.
Is there maybe some notification that my app could register for? The only workaround I can imagine is poll the running processes and see if Safari is launched, but that doesn't seem to be an elegant way to solve my problem...
NSWorkspaceDidLaunchApplicationNotification and NSWorkspaceDidTerminateApplicationNotification. (There are equivalent Carbon Events.)
Use kEventAppFrontSwitched in Carbon Event Manager to get notifications when another application becomes active.
Use this code: http://cl.ly/2LbB
// usleep(40500);
ProcessNotif * x = [[ProcessNotif new] autorelease];
[x setProcessName: #"Safari"];
[x setTarget: self];
[x setAction: #selector(doStuff)];
[x start];
This will run the selector -doStuff when Safari runs. If you get an error, uncomment the usleep() line.
Got same problem, but thanks to JWWalker, documentation and google wrote this code:
// i need to register on button event, you can do it even in applicationDidFinishLaunching
- (IBAction)Btn_LoginAction:(id)sender {
...
NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
[center addObserver:self selector:#selector(appLaunched:) name:NSWorkspaceDidLaunchApplicationNotification object:nil];
[center addObserver:self selector:#selector(appTerminated:) name:NSWorkspaceDidTerminateApplicationNotification object:nil];
}
// remember to unregister
- (void)ManageLogout:(NSInteger)aResult {
...
NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter];
[center removeObserver:self name:NSWorkspaceDidLaunchApplicationNotification object:nil];
[center removeObserver:self name:NSWorkspaceDidTerminateApplicationNotification object:nil];
}
- (void)appLaunched:(NSNotification *)note {
[GTMLogger myLog:kGTMLoggerLevelDebug fmt:#"MainWinDelegate::appLaunched: %# (%#)\n", [[note userInfo] objectForKey:#"NSApplicationBundleIdentifier"], [[note userInfo] objectForKey:#"NSApplicationProcessIdentifier"]];
if ( [[[note userInfo] objectForKey:#"NSApplicationBundleIdentifier"] isEqualToString:#"app.you.monitor.bundle.identifier"] ) {
// do stuff
}
}
- (void)appTerminated:(NSNotification *)note {
[GTMLogger myLog:kGTMLoggerLevelDebug fmt:#"MainWinDelegate::appTerminated: %# (%#)\n", [[note userInfo] objectForKey:#"NSApplicationBundleIdentifier"], [[note userInfo] objectForKey:#"NSApplicationProcessIdentifier"]];
if ( [[[note userInfo] objectForKey:#"NSApplicationBundleIdentifier"] isEqualToString:#"app.you.monitor.bundle.identifier"] ) {
// do stuff
}
}
Related
I'am trying to call a function when the app com back to Foreground by applicationDidBecomeActiveNotification. I have it in iOS 8 and iOS 7 and it works well. But not in iOS 9 ? It docent call first time you open the app
-(void) viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationDidBecomeActiveNotification:)
name:UIApplicationDidBecomeActiveNotification
object:[UIApplication sharedApplication]];
}
- (void)applicationDidBecomeActiveNotification:(NSNotification *)notification {
//stuff
}
It is every notification center that is not calling at startup...
I hade the same problem and for me it worked to move the addObserver code to awakeFromNib. Another solution could be to add a delay to the addObserver as in the example below:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
});
See Apple Foundation update for NotificationCenter
This is what you need,
NSNotificationCenter.defaultCenter().addObserverForName(UIApplicationDidBecomeActiveNotification, object: nil, queue: nil) { note in
self.applicationDidBecomeActiveNotification(note)
}
I followed the Apple documentation to move a textfield upwards when the keypad appears.
The code works fine my problem is that I need that one specific textfield is moved towards the other, instead of implementing the code Apple every textfield I select is moved upwards ... How can I do to move a specific textField and not all?
Thank you very much, I insert the following code used
-(void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
}
// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification {
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect bkgndRect = changePasswordTextField.superview.frame;
bkgndRect.size.height -= kbSize.height;
[scrollView setContentOffset:CGPointMake(0.0, changePasswordTextField.frame.origin.y+kbSize.height) animated:YES];
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification {
[scrollView setContentOffset:CGPointZero animated:YES];
}
You can achieve your functionality by following steps.
Set delegate of your UITextField.
Implement textFieldDidBeginEditing method which will be called when keyboard open for textfield. So you may change frame of textfield in this method as below.
-(void)textFieldDidBeginEditing:(UITextField *)textField{
[textField setFrame:CGRectMake(0.0, textField.frame.origin.y-VALUE,textField.frame.size.width,textField.frame.size.height) animated:YES];
// VALUE = textfield you want to move upward vertically
}
Now, to handle keyboard hiding event, you can set frame of your textfield to its origin in textFieldDidEndEditing method as below.
- (void)textFieldDidEndEditing:(UITextField *)textField{
[textField setFrame:CGRectMake(0.0, textField.frame.origin.y+VALUE,textField.frame.size.width,textField.frame.size.height) animated:YES];
// VALUE = textfield you want to move downward vertically
}
I hope it may help you.
I have a TabBarController, supportedInterfaceOrientations - UIInterfaceOrientationMaskPortrait. Navigation bar moves up under the status bar when I start watching video from one of tabs, rotate device to landscape and then exit from fullscreen. Why it's happens and how fix it?
This is a kind of hack, but works in my view controller contains UIWebView and fullscreen videos start from <video> tags.
You will see jerking of navigation bar because UIWindowDidBecomeHiddenNotification is called after video fullscreen window just disappear.
- (void)viewDidLoad
{
[super viewDidLoad];
// NOTE: I'm not sure, but MPMoviePlayerWillExitFullscreenNotification won't work
// [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidBecomeHidden:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidBecomeHidden:) name:UIWindowDidBecomeHiddenNotification object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)windowDidBecomeHidden:(NSNotification *)notification
{
UIView *navbar = self.navigationController.navigationBar;
CGRect barFrame = navbar.frame;
barFrame.origin.y = 20;
self.navigationController.navigationBar.frame = barFrame;
UIView *navbarBack = nil;
for (UIView *view in navbar.subviews) {
if ([NSStringFromClass([view class]) isEqual:#"_UINavigationBarBackground"]) {
navbarBack = view;
break;
}
}
CGRect backFrame = navbarBack.frame;
backFrame.origin.y = -20;
backFrame.size.height = 64;
navbarBack.frame = backFrame;
[navbar.superview setNeedsLayout];
}
UIView *navbarBack = [navbar.subviews bk_match:^BOOL(UIView *view) {
return [NSStringFromClass([view class]) isEqual:#"_UINavigationBarBackground"];
}];
I have met the same issue.I tried to use js to get the "webkitendfullscreen" event,and then found navbar.frameOriginY = 0,which should be 20.
I was wondering how to swipe the ViewController with a visible keyboard?
in iOS 7 I can swipe the ViewController from side to side, but the keyboard stays put.
in short, I would like to get to the following state:
Thanks!
Update:
I can't recommend the original solution. While it performed well (when it performed at all), it was an unreliable hack, and could easily break the pop gesture recognizer.
My colleague Dave Lyon came up with a great solution using iOS 7 view controller transitions and packaged it up into a pod:
https://github.com/cotap/TAPKeyboardPop
Once installed, just import the main file and you should be good to go.
Original:
I'd love to know if there's a better way of doing this, but I was able to achieve the behavior by adding the keyboard's view as a subview of the view controller's main view:
- (void)viewDidLoad
{
[super viewDidLoad];
self.textView.inputAccessoryView = [UIView new];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:#selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)keyboardWillHide:(NSNotification *)note
{
if (self.textView.isFirstResponder) {
UIView *keyboardView = self.textView.inputAccessoryView.superview;
if (keyboardView) {
dispatch_async(dispatch_get_main_queue(), ^{
[self.view addSubview:keyboardView];
});
}
}
}
I've found you can also animate the keyboard with the gesture (via addTarget:action:), but the performance is abysmal and doesn't cleanly animate if the gesture is prematurely canceled.
when I get local notification I want to open my specific screen.
currently in my app i have used both navigation controller as well as model view controller so at the time of navigation controller, app is switching any view but when model controller exit . it is not opening the screen.
Plz suggest any solution?
There are two way to launch app when notification comes.
1- app is running in background.then open specific screen like
- (void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
{
// write this line
[[NSNotificationCenter defaultCenter] postNotificationName:#"reloadData" object:self];
}
in which controller class you are create notification.
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(reloadTable)
name:#"reloadData"
object:nil];
}
- (void)reloadTable
{
// create object of that controller which your want to open.
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
AddToDoViewController *cvc = (AddToDoViewController *)[sb instantiateViewControllerWithIdentifier:#"AddToDo"];
[self presentModalViewController:cvc animated:YES];
}