raising keyboard pressing on a text field - ios

I want to raise my keyboard when i press on a determinate UITextField, so I create a touch down action, but at the first call it doesn't work, by second call it work fine.
here's the code (naturally keyboardSize is a global variable with CGSize type):
- (void)viewWillAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification {
keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
}
- (void)keyboardWillHide:(NSNotification *)notification {
[self moveFrameToVerticalPosition:0.0f forDuration:0.3f];
}
- (void)moveFrameToVerticalPosition:(float)position forDuration:(float)duration {
CGRect frame = self.view.frame;
frame.origin.y = position;
[UIView animateWithDuration:duration animations:^{
self.view.frame = frame;
}];
}
- (IBAction)insert:(id)sender {
float newVerticalPosition = - keyboardSize.height;
[self moveFrameToVerticalPosition:newVerticalPosition forDuration:0.0f];
}

In keyboardWillShow: add:
[self moveFrameToVerticalPosition:-keyboardSize.height forDuration:0.0f];
You don't really need insert:.

Related

Obj-C - NSNotification executing twice?

For some reason, UIKeyboardWillHideNotification is being executed twice in my below code - I haven't a clue as to why. I know this because my NSLog ("Closed!") appears twice in my console. Am I missing something obvious (and no, I don't have UIKeyboardWillHideNotification pasted somewhere in my code a second time).
-(void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleKeyboard:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleKeyboard:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)handleKeyboard:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
NSValue* value = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval duration = 3;
[value getValue:&duration];
if (aNotification.name == UIKeyboardWillShowNotification) {
self.upView.frame = CGRectOffset(self.upView.frame, 0, -self.keyboardHeight); self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -self.keyboardHeight);
[self moveCustomView:YES duration:duration];
}
if (aNotification.name == UIKeyboardWillHideNotification) {
/** KEYBOARD HIDE **/
self.upView.frame = CGRectOffset(self.upView.frame, 0, self.keyboardHeight); self.tableView.frame = CGRectOffset(self.tableView.frame, 0, self.keyboardHeight);
[self moveCustomView:NO duration:duration];
NSLog(#"CLOSED!");
}
}
Make sure to remove observers in viewDidDisappear as , view controller may be not reallocated from some reason and code in viewDidLoad is executed twice as observer is added twice
// Objective c
- (void)viewWillDisappear:(BOOL)paramAnimated{
[super viewWillDisappear:paramAnimated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
// Swift
override func viewDidDisappear(_ animated: Bool)
{
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
Be sure to remove the observer from the dealloc method. If you do not remove it and its memory is not released, it will listen for keyboard behavior on other pages. In addition, you should not add the same notification twice to the same observer.
Instead of Using same method for Hide and show notification. You can use two different Methods.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification object:nil];
Now, for Change your frame You can use following code
NSDictionary* info = [aNotification userInfo];
CGSize *kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -kbSize.height);
Please, try it like this:
What I did:
• moved subscription to viewWillAppear
• added "unsubscribe" in viewWillDisappear
• added "unsubscribe" in dealloc (shouldn't be related to your issue, but that's the right way to do it still)
• replaced == with isEqual in your handler (also not related to your issue, most likely).
There may be some typos there. Sorry, if that's the case.
-(void)viewWillAppear {
[super viewWillAppear];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillChange:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleKeyboard:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleKeyboard:) name:UIKeyboardWillShowNotification object:nil];
}
-(void)viewDidLoad {
[super viewDidLoad];
//Leaving this method here just to point out that everything was moved to viewWillAppear
}
- (void)handleKeyboard:(NSNotification*)aNotification{
NSDictionary* info = [aNotification userInfo];
NSValue* value = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval duration = 3;
[value getValue:&duration];
if ([aNotification.name isEqual: UIKeyboardWillShowNotification]) {
self.upView.frame = CGRectOffset(self.upView.frame, 0, -self.keyboardHeight);
self.tableView.frame = CGRectOffset(self.tableView.frame, 0, -self.keyboardHeight);
[self moveCustomView:YES duration:duration];
}
if ([aNotification.name isEqual: UIKeyboardWillHideNotification]) {
/** KEYBOARD HIDE **/
self.upView.frame = CGRectOffset(self.upView.frame, 0, self.keyboardHeight);
self.tableView.frame = CGRectOffset(self.tableView.frame, 0, self.keyboardHeight);
[self moveCustomView:NO duration:duration];
NSLog(#"CLOSED!");
}
}
-(void)unsubscribe {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-(void)viewWillDisappear {
[super viewWillDisappear];
[self unsubscribe];
}
-(void)dealloc {
[self unsubscribe];
}

Add UISearchBar above keyboard

I want to display a search bar above the keyboard. Whenever the keyboard appears search bar should also come. How to do this?
You can simply use textField.inputAccessoryView = your search bar
textField.inputAccessoryView = mySearchBar;
Create an object of UISearch bar and add an observer for keyboard in textFieldDidBeginEditing/textViewDidBeginEditing
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
}
- (void)keyboardWasShown:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
int height = MIN(keyboardSize.height,keyboardSize.width);
int width = MAX(keyboardSize.height,keyboardSize.width);
//set frame for searchbar
searchBar.frame = CGRectMake(0, self.view.frame.size.height - height, width, 50);
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.view.frame;
f.origin.y = -keyboardSize.height;
self.view.frame = f;
}];
}
-(void)keyboardWillHide:(NSNotification *)notification
{
[UIView animateWithDuration:0.3 animations:^{
CGRect f = self.view.frame;
f.origin.y = 0.0f;
self.view.frame = f;
}];
}

IOS8 keyboard event not executing properly

Hi I am developing one iphone application in which I am using few keyboard events but those are not working properly in IOS8 as working in previous IOS versions. So here is my problem. I have two text fields. I am listening for two events (void)keyboardWillBeHidden:(NSNotification *)notification and (void)keyboardWasShown:(NSNotification *)notification. Inside these methods I am scrolling my content according to keyboard height. In previous IOS version it is working properly but in IOS8 it is causing problem. Whenever I select any text field it is triggering keyboardWasShown but whenever I select another text field then again it is triggering same event even though keyboard already shown. In previous versions it is triggering only once but for IOS 8 it is triggering twice. Here is my code
- (void)registerForKeyboardNotifications {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillBeHidden:)
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)deregisterFromKeyboardNotifications {
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:UIKeyboardWillHideNotification
object:nil];
}
- (void)keyboardWasShown:(NSNotification *)notification {
[LogRecords showLog:#"keyboard shown ... "];
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone || (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])))
{
//scroll content here according to height of keyboard ;
}
}
- (void)keyboardWillBeHidden:(NSNotification *)notification
{
[LogRecords showLog:#"keyboard hide "];
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone || (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad && UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])))
{
//scroll content here according to height of keyboard ;
}
}
Am I doing anything wrong or it is problem with new version? Need Help. Thank you.
I have been experiencing the same thing, only in iOS8.
I worked around the issue by adding a semaphore for the handling of the notification:
#implementation MyViewController
//workaround to iOS 8 bug where the keyboard notification is fired up twice
static BOOL flag;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}
- (void)keyboardWillShow:(NSNotification *)note {
if (flag) {
return;
}
flag = YES;
//your code for handling keyboard display
}
- (void)ga_keyboardWillHide:(NSNotification *)note {
if (!flag) {
return;
}
flag = NO;
// your code for handling keyboard hiding
}
#end

Whatsapp style - keyboard appear under the toolbar

How do I do it whatsapp style, where the message space, when clicked, would push a keyboard up from the bottom, as well as pushing the toolbar up as well. And then when cancelled (i.e. clicking in the background), it'll push the keyboard back down with the toolbar
This is done with the UIKeyboardWillShowNotification, UIKeyboardDidShowNotification, UIKeyboardWillHideNotification and UIKeyboardDidHideNotification notifications.
Then when you handle the notification you adjust the height of the frame:
For example:
- (void) keyboardWillShow:(NSNotification *)aNotification{
NSDictionary* info = [aNotification userInfo];
NSTimeInterval duration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
NSValue* aValue = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
CGFloat keyboardHeight = [aValue CGRectValue].size.height;
self.keyboardVissible = YES;
[UIView animateWithDuration:duration animations:^{
CGRect frame = self.contentView.frame;
frame.size.height -= keyboardHeight;
self.contentView.frame = frame;
}];
}
You will need to register to receive the notification, you should only listen to the keyboard notification when the view is visible, strange thing could happen if you do it in the viewDidLoad:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

App is crashing when moving to other app and then moving back

I have an issue with my app..
It's crashing when i'm using home button for multitasking to move to another app and when i want to go back again to my app it's crashing and i get the message:
*** -[UIView convertRect:toView:]: message sent to deallocated instance 0x81e4020
It started since i've implemented "inner-view" ad's.
do i need to do something in my code to make it disspapear?
I tried to solve it but no success.
This is my code of the ad's:
CGRect frame = CGRectMake(0, 480, 320, 50);
self.adBanner = [[UIView alloc] initWithFrame:frame];
[self.view convertRect:adBanner.frame toView:nil]; --->This is a line i tried to put...
[self.view addSubview:self.adBanner];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdReceived:) name:#"iaAdReceived" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaDefaultAdReceived:) name:#"iaDefaultAdReceived" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdFailed:) name:#"IaAdFailed" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdClicked:) name:#"IaAdClicked" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdWillShow:) name:#"IaAdWillShow" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdDidShow:) name:#"IaAdDidShow" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdWillHide:) name:#"IaAdWillHide" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdDidHide:) name:#"IaAdDidHide" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdWillClose:) name:#"IaAdWillClose" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdDidClose:) name:#"IaAdDidClose" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdWillResize:) name:#"IaAdWillResize" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdDidResize:) name:#"IaAdDidResize" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdWillExpand:) name:#"IaAdWillExpand" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAdDidExpand:) name:#"IaAdDidExpand" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAppShouldSuspend:) name:#"IaAppShouldSuspend" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(iaAppShouldResume:) name:#"IaAppShouldResume" object:nil];
// Display ad
if (![InneractiveAd DisplayAd:#"iOS_Test" withType:IaAdType_Banner withRoot:self.adBanner withReload:60 withParams:optionalParams])
{
[adBanner removeFromSuperview];
}
}
-(void) viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[adBanner removeFromSuperview];
}
- (IBAction)iaAdReceived:(id)sender
{
// The ad view has finished loading a paid ad
}
- (IBAction)iaDefaultAdReceived:(id)sender
{
// The ad view has finished loading a default ad
}
- (IBAction)iaAdFailed:(id)sender
{
// The ad view has failed to load an ad
}
- (IBAction)iaAdClicked:(id)sender
{
// The ad has been clicked
}
- (IBAction)iaAdWillShow:(id)sender
{
// The ad is about to show
}
- (IBAction)iaAdDidShow:(id)sender
{
// The ad did show
}
- (IBAction)iaAdWillHide:(id)sender
{
// The ad is about to hide
}
- (IBAction)iaAdDidHide:(id)sender
{
// The ad did hide
}
- (IBAction)iaAdWillClose:(id)sender
{
// The ad is about to close
}
- (IBAction)iaAdDidClose:(id)sender
{
// The ad did close
}
- (IBAction)iaAdWillResize:(id)sender
{
// The ad is about to resize
}
- (IBAction)iaAdDidResize:(id)sender
{
// The ad did resize
}
- (IBAction)iaAdWillExpand:(id)sender
{
// The ad is about to expand
}
- (IBAction)iaAdDidExpand:(id)sender
{
// The ad did expand
}
- (IBAction)iaAppShouldSuspend:(id)sender
{
// The app should suspend (for example, when the ad expands)
}
- (IBAction)iaAppShouldResume:(id)sender
{
// The app should resume (for example, when the ad collapses)
}
I attached a screenshot...
What could it be?
Thanks...
Your problem is that when running :
[self.view convertRect:adBanner.frame toView:nil];
your view doesn't exists anymore.
in your appDelegate you should work on this method :
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}
anyway, what did you try to achieve with this line ? because it's returning a CGRect which you're not using.

Resources