I'm currently implementing in my app functionality that my UITextField would not be covered by the keyboard (when edited). It is pretty straight forward with the keyboard notification methods :
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(p_keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(p_keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
But the problem with this is that they do not launch when the keyboard is in a different place (for example top) or split.
Any advice how to handle these situations?
Great article Working With Keyboard on iOS: http://macoscope.com/blog/working-with-keyboard-on-ios/
Related
Is there a way to detect if a phone call is going on on a phone in objective c? You'll notice many views move downwards under this situation and as such I want to know when.
You should not be detecting calls with the status bar frame. Instead you can detect phone calls with NSNotification like this
Put this in you viewDidLoad:
#import <CoreTelephony/CTCall.h>
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callReceived:) name:CTCallStateIncoming object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callEnded:) name:CTCallStateDisconnected object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callConnected:) name:CTCallStateConnected object:nil];
And don't forget to add CoreTelephony.framework
As explained by rmaddy, if you're trying to catch status bar frame changes, detecting phone calls is not the best way.
What you can do is implement the methods - (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame and - (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame of your app delegate or listen for the UIApplicationWillChangeStatusBarFrameNotification and UIApplicationDidChangeStatusBarFrameNotification notifications.
In my application I am loading some webpages embedded with Photos and Videos. Also I am using the following notifications to manage the player,
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(embeddedVideoStarted:) name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(embeddedVideoEnded:) name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
This is working fine in iOS7, but in iOS8 its not working. Any workarounds? Thanks in advance.
This is one option, I have found.. The problem is that is not Will is DID become hidden..
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(embeddedVideoStarted:)
name:UIWindowDidBecomeVisibleNotification
object:self.view.window];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(embeddedVideoEnded:)
name:UIWindowDidBecomeHiddenNotification
object:self.view.window];
If, I find a fix for the second notification I will posted it.. :)
I'm adding a view controller as an observer for UIKeyboardWillShowNotification notification.
I have this code in my viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
And in my dealloc:
[[NSNotificationCenter defaultCenter] removeObserver:self];
The observer is not being removed even though dealloc is called when the view controller is closed. So when I open it for the second time, NSNotificationCenter will attempt to notify the old object, which is released, and the app crashes.
I have seen several questions here on StackOverflow about this particular problem, but non of the answers works for me.
I've tried removing the observer in viewWillDisappear and viewDidDisappear but the same problem happens.
I'm using ARC.
Have you tried this exact chunk of code in viewWillDisappear?
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
From your explanation I don't think the problem is with the removal of the observer.
Try to trigger the Observer from another viewcontroller. If it's not triggered you'll know the removal is successful and the problem occurs when you are adding the observer the second time.
Maybe try by specifying the parameter name that you have set before like this :
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
Looks like the observer is getting set multiple times. Is your controller inherited from a class which also registers for same notification? That could lead to controller instance getting registered as observer more than once. As a workaround try this, in your controller class where you add the observer,
// Remove as observer first
[[NSNotificationCenter defaultCenter] removeObserver:self];
name:UIKeyboardWillShowNotification
object:nil];
// Then add
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
This will ensure that the observer is getting added only once.
Hope that helps!
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"name" object:nil];
it works fine with me
I can add observer twice (by accident) to the notification center and I will get notifications twice.
Is it possible to get only one notification? Do you know more elegant solutions?
I show you this example because this may lead to bugs.
- (void)viewDidLoad
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)keyboardDidShow:(NSNotification *)ntf
{
}
If you're not sure if you added the observer somewhere else, you can use the following code everytime you're adding an Observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:aName object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:aSelector name:aName object:nil];
This way you are removing the old one (if it existed) and adding a new one.
It's not 100% fail proof but it's a start. This could fail in Multi-Threaded apps where the calls are being made async or other unique situations.
You can also set an object to nil and then later use that object as if was still valid.
Not everything can be made fail safe.
Hi is there any way to detect iPad keyboard hiding button ? i mean when user press this button :
something going to happen !
I'm not sure what you want to accomplish, but maybe this can help you: Register with NSNotificationCenter to receive the UIKeyboardWillHideNotification and/or UIKeyboardDidHideNotification.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myKeyboardWillHideHandler:)
name:UIKeyboardWillHideNotification
object:nil];
...
- (void) myKeyboardWillHideHandler:(NSNotification *)notification {
NSLog(#"Keyboard wants to hide. What a coward.");
}
put this to viewDidLoad
// register to track event when user presses hide keyboard button on bottom right cornor for iPAD
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldShouldReturn:) name:UIKeyboardWillHideNotification object:nil];
and this will make your - (BOOL)textFieldShouldReturn:(UITextField *)textField; delegate method to get called when keyboard down button is pressed in iPAD.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textFieldShouldReturn:) name:UIKeyboardWillHideNotification object:nil];
This actually crashes on the go.
But if you call a custom method, like:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myCustomeMethodToResignTextFieldResponder) name:UIKeyboardWillHideNotification object:nil];
Then it will work just fine.. :-)
with Javascript
I found a workaroud for iPad IOS7. I will test on IOS8 to make sure it works. So basically I create a listener on every FOCUSOUT event (for all my texts) and I call my function.
It fires when you have your keyboard open and when you close your "keyboard". It doesn't fire when you select another text field or button, because it targets on null. If you use in combination with keydown, you can save multiple value and call your submit function only when you release your keyboard.
document.addEventListener('focusout', function(e) {
if (e.relatedTarget == null){
alert("close keyboard without click on something else");
callYourFunction();
}
});