UITextView will get down when i click textField - ios

I have a TextView & a textFile in My ViewController
When I click my textFile , my iPhone doesn't have any problem
but my simulator will get down ,
and ,if i click "Tab" it will get down again,
It was over I set navigation controller,
does anyone know what happened?
Just like this, the black area is my question

could you post the piece of code where the simulator crash or ‘goes down’?
Strange that it doesn’t work on simulator and works on device, normally the other way around :p. You could reset contents of the simulator(Simulator -> Reset Content….) or delete and rebuild the app.

I find my question is in Simulator's keyboard..
I uncheck the hardware > Keyboard > Connect Haredware Keyboard
then it's no problem
It was because this
-(void) keyboardDidShow: (NSNotification *) notification {
NSValue * value = [[notification userInfo] valueForKey:UIKeyboardFrameBeginUserInfoKey];
CGFloat keyboardHeight = [value CGRectValue].size.height;
[UIView animateWithDuration:0.3f animations:^
{
CGRect frame = self.view.frame;
frame.origin.y -= keyboardHeight;
self.view.frame = frame;
}
];
}

Related

The height on my soft keyboard changes when triggered multiple times

I have an observed method that trigger when the soft keyboard is shown. It works fine, but for some reason the height of the soft keyboard changes after it has been hidden, then presented for the second time. I can't find a reason for this and there doesn't seem to be anything in the hide-delegate that changes its value. What causes this? I have worked around the problem by storing the height then using it the second time, but I would like to know the cause of this issue.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGRect visibleRect = self.view.frame;
if (_storedKeyboardHeight.size.height == 0) {
_storedKeyboardHeight.size.height = keyboardSize.height;
}
visibleRect.size.height = _storedKeyboardHeight.size.height;
visibleRect.origin.y = self.view.height - visibleRect.size.height;
CGRect rectOfCellInTableView = [self.loginTableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1]];
//This changes the second time
NSLog(#"🦁 %f", keyboardSize.height);
//so I store the original value here
NSLog(#"🦁 %#", CGRectCreateDictionaryRepresentation(_storedKeyboardHeight));
if ((rectOfCellInTableView.origin.y + rectOfCellInTableView.size.height) > visibleRect.origin.y){
CGPoint scrollPoint = CGPointMake(0.0, (rectOfCellInTableView.origin.y + rectOfCellInTableView.size.height) - visibleRect.origin.y + 50);
[self.loginTableView setContentOffset:scrollPoint animated:YES];
}
}
First time the height is 291, second time it's 233.
The problem is that you are examining the wrong frame:
UIKeyboardFrameBeginUserInfoKey
When the keyboard is shown, what its frame height is at the beginning of the showing process is of no interest to you. What you want to know is the frame at the end of the showing process:
UIKeyboardFrameEndUserInfoKey
Also, it looks like you are getting notified of the wrong thing. You have not shown what notification you are registered for, but the name of your method, keyboardWasShown, suggests that your are getting notified when the keyboard did show. That's too late; this notification is almost never of any interest. You want to know when the keyboard will show.

Move UIToolBar above keyboard on screen with UIScrollview

I have a screen within an iPhone app that consist of a UITextView. This text view is contained within a UIScrollView. The purpose of the screen is for the user to type in text, and to optionally attach an image to what he is writing. Therefore, the screen also has a UIToolbar with a camera button at the bottom of the screen. The structure of the screen is as follows:
-View
--UIScrollView
---UITextView
--UIToolbar
---UIButton
When the user navigates to this screen, the viewDidAppear method assigns first responder to the uitextview element, so the keyboard shows up, which hides the toolbar and the camera button.
I would like the entire toolbar to re-draw itself right above the keyboard, and to position itself again at the bottom of the screen when the keyboard hides.
I have found related posts on SO (like this one). However, such methods introduce undesired behaviours. For example, implementing the solution in the article above, the toolbar does move with the keyboard, but the UIScrollView gets its frame.origin.y coordinate shifted way above the top of the screen, so it's impossible for the user to see what he is typing.
I have also tried to reset the frame of the toolbar, by adding it as an IBOutlet and using cgrectmake to reposition it. However, after several tries, the toolbar remains stuck at the bottom of the screen and hidden by the keyboard:
- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelegate:self];
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:<#(UIViewAnimationCurve)#>]
CGRect frame = self.keyboardToolbar.frame;
frame.origin.y = self.keyboardToolbar.frame.origin.y - 280;
self.keyboardToolbar.frame = frame;
[UIView commitAnimations];
}
I have tried several iterations similar to the code above and they all fail at repositioning the toolbar.
So in short, what is the right way to float a toolbar right on top of a keyboard in a screen whose space is completely utilised by a uitextview element?
Thanks to RoryMcKinnel for the pointer. As the article referenced is in Swift, I thought I might paste the solution that worked for be on ObjC
- (void)keyboardWillShowNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertedKeyboardFrame = [self.view convertRect:keyboardEndFrame fromView:self.view.window];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = CGRectGetMaxY(self.view.bounds) - CGRectGetMinY(convertedKeyboardFrame);
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}
Bear in mind, this code did make the toolbar move as required, but the toolbar was not visible at all. It turned out that it was being hidden behind the UIScrollView. This was easily fixed by shifting the order between the scroll view and the toolbar element in the IB hierarchy.
The method above works for the keyboardWillShow event. You'll need to add the corresponding one for when the keyboard hides, like this:
- (void)keyboardWillHideNotification:(NSNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
double animationDuration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardEndFrame = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
UIViewAnimationOptions rawAnimationCurve = (UIViewAnimationOptions)[userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue] << 16;
_toolBarBottomGuide.constant = 0.0f;
[UIView animateWithDuration:animationDuration delay:0.0 options:rawAnimationCurve animations:^{
[self.view layoutIfNeeded];
} completion:nil];
}

HPGrowingTextView - "textInputView.frame.origin.y" is correct, but the text field actually not moved - sometimes

I'm debugging someone else's code - sorry I have very limited Objective-C experience.
#pragma mark - Keyboard events
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
NSLog(#"Keyboard a Notification user Info %#", info);
printf("keyboardWasShown \\\\\\\\\\\\\\\\\\\\\n");
NSLog(#"textInputView: y: (%.f), height: (%.f), kbHeight: (%.f)",
textInputView.frame.origin.y, textInputView.frame.size.height, kbSize.height);
[UIView animateWithDuration:2.0f animations:^{
if (keyboardNewLine){
bubbleTableFrame = originalBubbleTableFrame;
}
CGRect frame = originalTextViewFrame;
int difference = 0;
if (IsIphone5){
difference = -42;
frame.origin.y -= kbSize.height + difference;
} else {
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f) {
difference = 42;
frame.origin.y -= kbSize.height + difference;
} else {
frame.origin.y -= kbSize.height + 110;
difference = 42;
}
}
textInputView.frame = frame;
frame = bubbleTableFrame;
frame.size.height -= kbSize.height + difference;
bubbleTable.frame = frame;
}];
NSLog(#"textInputView: y: (%.f), height: (%.f), kbHeight: (%.f)",
textInputView.frame.origin.y, textInputView.frame.size.height, kbSize.height);
printf("keyboardWasShown //////////\n");
[bubbleTable scrollBubbleViewToBottomAnimated:YES];
}
When I tap the text input field to bring up the keyboard, the field should move up to just above the keyboard - sometimes. It all depends on the which keyboard is loading first.
The text field without keyboard:
After tapping the text field, I expect:
However the text field stays at the bottom of the screen, leaving only the placeholder:
Strange enough, if I drag down the QuickType row, the text field suddenly appears!
But if I exit from this view and come back afterwards, once again the text field is stuck at the bottom (and guess what, it jumps up if I drag UP the QuickType row):
Switching to another keyboard (input method) by tapping the globe icon always helps to bring up the text field:
It seems that third-party keyboards are not affected:
You can see that I keep monitoring textInputView.frame.origin.y to see what goes wrong. It changes from 472 (no keyboard) to 261 (English keyboard) but the text field simply doesn't go up.
I don't think it is behind the placeholder (if any) because when I tap the white area beside the bubbles, the keyboard moves down and unveils the text field stuck at the bottom.
Someone suggested adding setNeedsDisplay, setNeedsLayout, etc. but none helped.
Thanks in advance.
Eventually I turned off Auto Layout as suggested by someone:
https://www.facebook.com/groups/cocoahk/permalink/1104922892867587/
It worked. Though I needed to adjust the positions of all other objects.

ios keyboardwillshow notification firing late

I am experiencing a strange error on iOS 8 when trying to synchronize an animation in tandem with the keyboard moving up after selecting a textfield.
Specifically, I am trying to get the height of the keyboard in order to know how far up to move the text field by using the following code after registering for the keyboardwillshow notification:
- (void)keyboardWillShow:(NSNotification *)notification
{
CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
self.keyboardHeight = keyboardSize.height;
[self moveToolbarUp];
}
-(void)moveToolbarUp
{
self.keyboardExpanded = YES;
CGRect frame = self.toolbar.frame;
DLog(#"keyboard height now:%f",self.keyboardHeight);
frame.origin.y = (self.view.frame.size.height-toolbarHeight-self.keyboardHeight);
[UIView animateWithDuration:0.1 animations:^{
self.toolbar.frame = frame;
}];
}
However, if I try to set a break point at the keyboardwillshow method, I can see that the keyboard is already all the way up when the method is called, and the animation is therefore delayed (the keyboard pops up and then a second or so later, the textfield follows).
Has anybody else experienced this error? I am running on an iPhone 5s, iOS 8.0.2.
Thanks!!
It's not an error. The fact is that you can remove your animateWithDuration call. In iOS 8, keyboardWillShow: is called inside the keyboard's animation. You don't have to synchronize anything; anything you do will be part of the animation, automatically.

Move UITextField up without moving whole view up

I have a UITableView inside a UIScrollView. The tableView does not span the length of the view as I have a UITextView at the bottom of the view (to enter messages) so the table ends at the textview. However, The scrollView does span the entire length of the view. When the keyboard comes up, I move the entire view up with it,(so nothing is hidden) but that makes the top cells of the table inaccessible (as in, I don't need to see the cells, but when i try to scroll to them I can't get to them) as it is pushing the whole view up. I am wondering if instead, I can push the scrollview underneath up, in turn having it push the keyboard up with it, and then have the tableview stay in place and scroll to the proper cell (for me in this case it is the most recent message, or last cell in the table). Having the tableview stay in place will allow scrolling access to all the cells in the table. Am I going about this the right way or is there an easier and better way to accomplish this? I'm working on a messaging app, and I want the UI to behave in a similar way to the native messages app. When the keyboard comes up, it brings the last message up above the top of the keyboard, but when the keyboard is visible you can still scroll to the top of the table. I will post my code for the movement of the view.
//call move view method and scroll to last cell in table
-(void) keyboardWasShown:(NSNotification*)aNotification
{
NSLog(#"Keyboard was shown");
[self moveView:[aNotification userInfo] up:YES];
[self.chatTable scrollRectToVisible:CGRectMake(0, self.chatTable.contentSize.height - self.chatTable.bounds.size.height, self.chatTable.bounds.size.width, self.chatTable.bounds.size.height) animated:YES];
}
-(void) keyboardWillHide:(NSNotification*)aNotification
{
NSLog(#"Keyboard will hide");
[self moveView:[aNotification userInfo] up:NO];
}
- (void)moveView:(NSDictionary*)userInfo up:(BOOL)up
{
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey]getValue:&keyboardEndFrame];
UIViewAnimationCurve animationCurve;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey]
getValue:&animationCurve];
NSTimeInterval animationDuration;
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey]
getValue:&animationDuration];
// Get the correct keyboard size to we slide the right amount.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDuration:animationDuration];
[UIView setAnimationCurve:animationCurve];
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
int y = keyboardFrame.size.height * (up ? -1 : 1);
self.view.frame = CGRectOffset(self.view.frame, 0, y);
[UIView commitAnimations];
}
What I would do is NOT move the whole view up, but just shrink the scrollView's height by y amount.
So instead of
self.view.frame = CGRectOffset(self.view.frame, 0, y);
you could
CGRect scrlRect = self.myScrollView.frame;
self.myScrollView.frame = CGMakeRect(scrlRect.origin.x, scrlRect.origin.y, scrlRect.size.width, scrlRect.size.height+y);
The first step in dealing with this is modify the insets on the table. This gist would help you ensure that the tableView (or scrollview) scrollable area is no longer covered by the keyboard: https://gist.github.com/TimMedcalf/9505416
It may reveal further issues, but that's always my first port of call.
In your keyboarWasShown method wright below code:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
float kbHeight = kbSize.width > kbSize.height ? kbSize.height : kbSize.width;
self.keyboardHeight.constant = kbHeight+5;
}
Now in your textFieldShouldBeginEditing delegate method of UITextField write below code:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
CGPoint point = [textField.superview convertPoint:textField.frame.origin toView:yourTableViewHere];
NSIndexPath *indexPath = [tblAsset indexPathForRowAtPoint:point];
CGRect tableViewVisibleRect = [tblAsset rectForRowAtIndexPath:indexPath];
if (point.y > (tableViewVisibleRect.size.height - self.keyboardHeight.constant))
{
CGPoint contentOffsetPoint = tblAsset.contentOffset;
contentOffsetPoint.y -= self.keyboardHeight.constant;
CGSize contectSize = tblAsset.contentSize;
contectSize.height += self.keyboardHeight.constant;
[tblAsset setContentSize:contectSize];
[tblAsset setContentOffset:contentOffsetPoint animated:NO];
}
}
Above is from my current project and its working somewhat like what you want. Using this way may help you achive your task.

Resources