Using Autolayout for Animation Resizing the UITextView Lower Limit When Scrolling Content

Background

I am working on a quick and dirty notes app to try and understand autorun. Therefore, I am looking for a solution to solve this problem.

I am quite sure that my terminology and understanding of this subject may be wrong in places, therefore, if I am wrong or omit information from ignorance that would otherwise be useful, I am very happy to update this question with better features.

Brief Description of the Problem

  • This app is a simple note taking app. In the note detail view, there are two text input views, UITextField and UITextView.
  • The goal is to use autostart to animate the change in height in the UITextView when editing it (making room for the keyboard), and then update the UITextView to its original size when editing is complete.
  • The animation code that I have works, however, when the UITextView scrolls near the bottom of the text, the animation with the size "edit" to the "uneditable" size does not display correctly, bullying the animation. (The end result of the animation, however, is correct.)
  • I am open to alternative β€œright” ways to do this if there is a common template for the solution. However, I am looking for an autorun solution, which I believe means that you should not directly change the presentation frame. (Perhaps this is wrong).

Details and code

A short video of the problem is available here:
http://pile.cliffpruitt.com/m/constraint_problem.mp4

This is the animation code:

// self.bodyFieldConstraintBottom refers to an outlet referencing the UITextView bottom constraint // This animation occurrs when the text view is tapped - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { [self enterEditingMode]; [UIView animateWithDuration:2.35 animations:^{ NSLayoutConstraint *bottom_constraint = self.bodyFieldConstraintBottom; bottom_constraint.constant = 216; [self.view layoutIfNeeded]; }]; return YES; } // This animation occurrs when editing ends and the text field size is restored - (BOOL)textViewShouldEndEditing:(UITextView *)textView { [self exitEditingMode]; [UIView animateWithDuration:2.35 animations:^{ NSLayoutConstraint *bottom_constraint = self.bodyFieldConstraintBottom; bottom_constraint.constant = 20; [self.view layoutIfNeeded]; }]; return YES; } 

The full source of the project (in all its dirty glory) can be downloaded here:
http://pile.cliffpruitt.com/dl/LittleNotebooks.zip

Additional comments

My understanding of cocoa terminology is not the best, so it’s hard for me to find effective Google searches and document searches. My best guess about the problem (based on watching the animation at a slow speed) is that it is related to the scroll shift anyway, because if the text does not scroll past a certain point, the problem does not appear.

I read quite a few questions and answers, including:

The problem is that these answers either do not work ([self.bodyField setContentInset: UIEdgeInsetsMake (0, 0, 216, 0)] does not seem to have any effect) or seem to rely on setting a UIText presentation frame which, like I suppose it should not be executed when using autorun.

Final side note

I worked for about 4 days, so my understanding and remembrance of everything that I read and tried was actually a little less clear than when I started. Hopefully I will explain it well enough to convey this issue.

EDIT:

I noticed that this code actually comes a little closer to the desired result:

 - (BOOL)textViewShouldBeginEditing:(UITextView *)textView { [self enterEditingMode]; [UIView animateWithDuration:2.35 animations:^{ [self.bodyField setContentInset:UIEdgeInsetsMake(0, 0, 216, 0)]; [self.view layoutIfNeeded]; }]; return YES; } - (BOOL)textViewShouldEndEditing:(UITextView *)textView { [self exitEditingMode]; [UIView animateWithDuration:2.35 animations:^{ [self.bodyField setContentInset:UIEdgeInsetsMake(0, 0, 0, 0)]; [self.view layoutIfNeeded]; }]; return YES; } 

The problem with this version is that the scroll indicator scrolls past the visible area of ​​the text content, which means that it is lost behind the key. Also, this does not help me understand the correct way to animate the lower bound of a UITextView (UIScrollView?).

+6
source share
1 answer

The problem looks strange, and I'm really not sure what the main problem is, but I found that for best results you should call [self.view setNeedsUpdateConstraints]; before the animation.

My sample code to animate the view when the keyboard appears:

 -(void)keyboardWillShow:(NSNotification *)notification { CGSize kbSize = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; //BH: iOS7 is messed up CGFloat keyboardHeight = kbSize.width; if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) { keyboardHeight = kbSize.height; } self.centerYConstraint.constant = keyboardHeight; [self.view setNeedsUpdateConstraints]; [UIView beginAnimations:nil context:NULL]; [UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]]; [UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]]; [UIView setAnimationBeginsFromCurrentState:YES]; [self.view layoutIfNeeded]; [UIView commitAnimations]; } 

I use commit animation to animate a view using animationCurve since iOS animates the keyboard, so the view moves 1 to 1 according to the keyboard. Also, please note if the expression is for iOS8 vs iOS7, where Apple finally fixed the window size.

0
source

Source: https://habr.com/ru/post/973443/


All Articles