KeyBoard Hide Notification call Multiple Time - ios

Sir On Tap Gesture I am hide Keyboard.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.view endEditing:YES];
}
They work fine. But when we edit textView second time.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardWillBeHidden:) name:UIKeyboardWillHideNotification object:nil]; call multiple time. And they execute my code 5-6 time inside keyboardWillBeHidden. Is their any way they not call when textview begin edit.
- (void)textViewDidBeginEditing:(UITextView *)textView
{
if ([textView.text isEqualToString:#"Type your message Here..."]) {
textView.text = #"";
textView.textColor = [UIColor grayColor]; //optional
}
[self scrollToBottomAnimated:YES];
}
- (void)scrollToBottomAnimated:(BOOL)animated
{
NSInteger rows = [tableViews numberOfRowsInSection:0];
if(rows > 0) {
[tableViews scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:rows - 1 inSection:0]
atScrollPosition:UITableViewScrollPositionBottom
animated:animated];
}
}

It depends upon where and how many times you are registering for keyboard notifications with NSNotificationCenter.
If you are adding observer in viewwillappear and remove observer in viewwilldisappear.
If you are adding observer in viewdidload then remove observer in dealloc call.
Just try to change the place in which you register for the notification. To make sure that only the viewController visible is the controller that receive the notification please register for the notification in vieWillAppear and remove the notification in viewWillDisappear.
That will also solve your problem of calling code multiple times.

Related

change position of view when keyboard Opens - Objective c

I am developing a chatting application. The application works fine but i have some problem in the UI design.
I have UiTextField in side the UIview, when ever the user want to type a message the keyboard opens, and UIView moves up.
Then when the user press the return button, i want to bring it back to the original position.
I tried but It looks like this I want it to support for all devices.
Here is my code
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keyboardDidHide:) name:UIKeyboardDidHideNotification object:nil];
[self.view endEditing:YES];
return YES;
}
- (void)keyboardDidShow:(NSNotification *)notification
{
// Assign new frame to your view
[self.view setFrame:CGRectMake(0,-145,320,460)]; //here taken -110 for example i.e. your view will be scrolled to -110. change its value according to your requirement.
}
-(void)keyboardDidHide:(NSNotification *)notification
{
[self.view setFrame:CGRectMake(0,0,320,460)];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.tv_Message resignFirstResponder];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"selected index : %ld", (long)indexPath.row);
}
- (BOOL)textFieldShouldReturn:(UITextField *)aTextField {
[aTextField resignFirstResponder];
[self.view setFrame:CGRectMake(0,0,320,460)];
return YES;
}
Can someone help me to fix this.
You can use this link to manage your view according to device. Also you need to set constraints accordingly.
https://stackoverflow.com/a/11282535/6438500
It seems that you haven't set the trailing constraint of your main view correctly. Then in keyboardDidShow(:) method up your main view dynamically because your view will have height according to device, so make it work on all devices you should move the main view up by calculating the position of textfield and keyboard height and then set the frame of your view accordingly.

IOS textView delegate

I have created a UITextView *mytextview . I want to get event when click textview before UIKeyboardWillShowNotification delegate.
Now, When I click textview, is's call UIKeyboardWillShowNotification. After that, it's call - (void)textViewDidBeginEditing:(UITextView *)textView, it's not good!
I want to mytextview delegate was called before call UIKeyboardWillShowNotification
How to I can resolve this problem
Use textViewShouldBeginEditing provided by the UITextViewDelegate, call your delegate method in it, and return YES from this method to let user edit the text.
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
[yourDelegate yourMethod:textView];
return YES;
}
The sequence of Event execution are
UIKeyboardWillShowNotification
textViewDidBeginEditing
Now as per our requirement I Fire On Notification that is called when KeyBoardWillShow.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textViewDidBeginEditing:)name:UIKeyboardWillShowNotification object:nil]
And in the selector I passed same function which is called after UIKeyBoardWillShown, Also you can set your Own Function, which you want to do Before UIKeyBoardShow
This is My Code
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textViewDidBeginEditing:) name:UIKeyboardWillShowNotification object:nil];
}
- (void)textViewDidBeginEditing:(UITextView *)textView {
NSLog(#"textViewDidBeginEditing");
}

handleKeyboardWillShow notification Handling

I have a Tableview in inside a viewcontroller. I have added following code to get keyboard notifications
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleKeyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(handleKeyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
And on keyboard show i am scrolling my table to bottom.
- (void)handleKeyboardWillShow:(NSNotification *)notification
{
[self scrollToBottomAnimated:YES];
}
But i have a textview in my view controller as well. So when i click on textview the handleKeyboardWillShow method is called as well resulting unnecessary scrolling my tableview which i do not need if textview is clicked.
Can some one please help me figure out how to detect from which sender handleKeyboardWillShow is called.
Thanks
You can do it by checking who is first responder.
- (void)handleKeyboardWillShow:(NSNotification *)notification
{
if ([textFieldForScrolling isFirstResponder]) {
[self scrollToBottomAnimated:YES];
} else {
NSLog(#"Is a different text input");
}
}
Let me know if you need more explanation.
I would register for keyboardWillChange - which covers both showing and hiding. You can get the keyboard rect and adjust your content offset based on the keyboard's location. Note: You can animate the change in content offset - I just didn't do it in this answer.
In your textfield delegate methods willBeginEditing and didEndEditing, you can set the state variable called currentTextField.
-(void)keyboardWillChange:(NSNotification *)notification {
keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
keyboardRect = [self.view convertRect:keyboardRect fromView:nil];
CGPoint currentFieldPoint = [currentTextField convertPoint:currentTextField.frame.origin toView:self.view];
if(keyboardRect.origin.y < currentFieldPoint.y + currentTextField.frame.size.height){
//move stuff here
[[self tableView] setContentOffset:CGPointMake(0, [self tableView].contentOffset.y + offsetValue)];
}
}

UITextField and Keyboard Notifications - strange order

So I've set up a notification for the keyboard appearance event. Now let us consider a UITextView and a UITextField.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
The selector is:
- (void)keyboardWillShow:(NSNotification *)notification {
keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
}
In case of a UITextView, the delegate method - (void)textViewDidBeginEditing:(UITextView *)textView is fired AFTER the keyboardWillShow: method. So keyboardSize has the keyboard's actual size and I'm able to use that inside the textview delegate method.
However in case of a UITextField, the corresponding delegate method - (void)textFieldDidBeginEditing:(UITextField *)textField is fired BEFORE the keyboardWillShow: method.
Why is this so? How do I get the keyboard's CGSize in the textfield's case as now it just returns zero because the textfield delegate is called first and not the keyboard selector.
I've had this same problem. Try using:
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
Weird… Sounds like a mistake on Apple's end.
Maybe you could delay the keyboard popping up? Here's my unfortunately very messy "work around" suggestion -- You could send a notification when the text field is selected, but then only actually begin editing a fraction of a second later so that the text field is in fact known before keyboardWillShow: is called. For example:
-(BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// Notification corresponding to "textFieldSelected:" method
[[NSNotificationCenter defaultCenter] postNotificationName:NOTIFICATION_TEXT_FIELD_SELECTED object:nil userInfo:[[NSDictionary alloc] initWithObjectsAndKeys:textField, #"textField", nil]];
// "textFieldReallyShouldBeginEditing" is initially set as FALSE elsewhere in the code before the text field is manually selected
if (textFieldReallyShouldBeginEditing)
return YES;
else
return NO:
}
- (void)textFieldSelected:(NSNotification*)notification {
// Done in a separate method so there's a guaranteed delay and "textFieldReallyShouldBeginEditing" isn't set to YES before "textFieldShouldBeginEditing:" returns its boolean.
[self performSelector:#selector(startTextFieldReallyEditing:) withObject:(UITextField*)notification[#"textField"] afterDelay:.01];
}
- (void)startTextFieldReallyEditing:(UITextField*)textField {
textFieldReallyShouldBeginEditing = YES;
// To trigger the keyboard
[textField becomeFirstResponder];
}
Then depending on how you're creating the notification, you can insert the value of this now known text field even before it begins editing.

UITextView make keyboard permanent?

I have two UITextViews in one UI, One of the UITextView is the first responder. The other UITextView is non-editable. When I double tap the non-editable UITextView, the keyboard disappears and I want to avoid this. They keyboard should always stay.
If you double tap on a text view, it shows UIMenuController with Cut, Copy, etc options.
So to achieve your requirement, set User Interaction property to NO (False).
Hope this is what you are looking for.
-Mrunal
Make your viewController the delegate of the textView and return NO from the UITextViewDelegate method textViewShouldEndEditing:
- (BOOL)textViewShouldEndEditing:(UITextView *)textView {
if (textView == self.editableTextView) {
return NO;
}
return YES;
}
this is not default behavior. to achieve your requirement try this using delagate method shouldChangeTextInRange and make your textview editable
- (void)viewDidLoad
{
[super viewDidLoad];
//nonEditingTextView.editable = NO;
//make the nonEditingTextView editable
}
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
if ( textView == nonEditingTextView ) {
return NO;
}
return YES;
}
//Firstly add the below code for keyboard notification into your viewdidload method.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keybordWillHide:) name:UIKeyboardWillHideNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(keybordWillShow:) name:UIKeyboardWillShowNotification object:nil];
//Let the two textview's names be, NonEditable and Editable
//declare a flag globally
bool Appearflag;
//Then implement the two methods as follows
-(void)keybordWillHide:(NSNotification *)notification
{
if ([NonEditable isFirstResponder] && Appearflag)
{
[Editable becomeFirstResponder];
}else if ([Editable isFirstResponder])
{
Appearflag = NO;
}
}
-(void)keybordWillShow:(NSNotification *)notification
{
if ([Editable isFirstResponder])
{
Appearflag = YES;
}
}

Resources