2121#import " ASYRootViewFinder.h"
2222
2323static CGFloat const ASYSimpleChatTextViewDefaultAnimationDuration = 0.34 ;
24- static float const ASYSimpleChatTextViewHeightConstraintPriority = 999.0 ;
2524static NSUInteger const ASYSimpleChatTextViewDefaultMinimumNumberOfLines = 1u ;
2625static NSUInteger const ASYSimpleChatTextViewDefaultMaximumNumberOfLines = NSUIntegerMax;
2726
@@ -32,6 +31,8 @@ @interface ASYSimpleChatTextViewHandler () <ASYInputViewObserverDelegate>
3231@property (nonnull , nonatomic , strong , readwrite ) NSLayoutConstraint *scrollViewKeyboardConstraint;
3332@property (nonnull , nonatomic , strong , readwrite ) UIScrollView *observableScrollView;
3433
34+ @property (nonatomic , assign ) CGFloat scrollViewKeyboardConstraintOriginConstant;
35+
3536@property (nonatomic , assign , readwrite ) NSUInteger minimumNumberOfLines;
3637@property (nonatomic , assign , readwrite ) NSUInteger maximumNumberOfLines;
3738
@@ -53,22 +54,18 @@ - (void)dealloc {
5354}
5455
5556- (nullable instancetype )initWithTextView : (nonnull UITextView *)textView
56- heightConstraint : (nonnull NSLayoutConstraint *)heightConstraint
57- scrollViewKeyboardConstraint : (nullable NSLayoutConstraint *) scrollViewKeyboardConstraint
58- andObservableScrollView : (nullable __kindof UIScrollView *) scrollView {
57+ withHeightConstraint : (nonnull NSLayoutConstraint *)textViewHeightConstraint
58+ andObservableScrollView : (nullable __kindof UIScrollView *) scrollView
59+ withKeyboardConstraint : (nullable NSLayoutConstraint *) scrollViewKeyboardConstraint {
5960 self = [super init ];
6061 if (self) {
6162 _chatTextView = textView;
62- _heightConstraint = heightConstraint ;
63+ _heightConstraint = textViewHeightConstraint ;
6364 _scrollViewKeyboardConstraint = scrollViewKeyboardConstraint;
64- /* *
65- @author Aleksandr Sychev
66-
67- Fix 'UIView-Encapsulated-Layout-Height' priority conflict
68- */
69- _scrollViewKeyboardConstraint.priority = ASYSimpleChatTextViewHeightConstraintPriority;
7065 _observableScrollView = scrollView;
7166
67+ _scrollViewKeyboardConstraintOriginConstant = _scrollViewKeyboardConstraint.constant ;
68+
7269 _inputViewObserver = [ASYInputViewObserver new ];
7370 _rootViewFinder = [ASYRootViewFinder new ];
7471 _converter = [ASYAnimationCurveToAnimationOptionsConverter new ];
@@ -94,11 +91,11 @@ - (nullable instancetype)initWithTextView:(nonnull UITextView *)textView
9491}
9592
9693- (nullable instancetype )initWithTextView : (nonnull UITextView *)textView
97- andHeightConstraint : (nonnull NSLayoutConstraint *)heightConstraint {
94+ withHeightConstraint : (nonnull NSLayoutConstraint *)textViewHeightConstraint {
9895 return [self initWithTextView: textView
99- heightConstraint: heightConstraint
100- scrollViewKeyboardConstraint :nil
101- andObservableScrollView :nil ];
96+ withHeightConstraint: textViewHeightConstraint
97+ andObservableScrollView :nil
98+ withKeyboardConstraint :nil ];
10299}
103100
104101#pragma clang diagnostic push
@@ -140,7 +137,7 @@ - (void)setText:(nullable NSString *)text animated:(BOOL)animated {
140137
141138 self.chatTextView .text = text;
142139 if (text.length == 0u ) {
143- [self updateVerticalAlignmentWithHeight :self .minimumHeight animated: animated];
140+ [self updateWithHeight :self .minimumHeight animated: animated];
144141 } else {
145142 [self resizeTextViewAnimated: animated];
146143 }
@@ -153,7 +150,7 @@ - (void)setAttributedText:(nullable NSAttributedString *)attributedText animated
153150
154151 self.chatTextView .attributedText = attributedText;
155152 if (attributedText.length == 0u ) {
156- [self updateVerticalAlignmentWithHeight :self .minimumHeight animated: animated];
153+ [self updateWithHeight :self .minimumHeight animated: animated];
157154 } else {
158155 [self resizeTextViewAnimated: animated];
159156 }
@@ -196,15 +193,23 @@ - (void)handleTextViewTextDidChange:(NSNotification *)notification {
196193#pragma mark - InputViewObserverDelegate methods
197194
198195- (void )observer : (nonnull ASYInputViewObserver *)observer
199- caughtAcessoryViewFrameWillChangeWithHeightDelta : (CGFloat)inputAccessoryViewHeightDelta
200- animationDuration : (NSTimeInterval )inputAccessoryViewAnimationDuration
201- animationCurve : (UIViewAnimationCurve)animationCurve {
202- CGFloat updatedConstraintConstant = inputAccessoryViewHeightDelta + CGRectGetHeight (self.chatTextView .inputAccessoryView .frame );
196+ caughtAcessoryViewFrameWillChangeWithMinY : (CGFloat)inputAccessoryViewMinY
197+ animationDuration : (NSTimeInterval )inputAccessoryViewAnimationDuration
198+ animationCurve : (UIViewAnimationCurve)animationCurve {
199+ CGFloat constraintOffset = CGRectGetMaxY ([UIScreen mainScreen ].bounds ) - inputAccessoryViewMinY +
200+ CGRectGetHeight (self.chatTextView .inputAccessoryView .frame );
203201 CGFloat currentDataInScrollViewOffset =
204202 MAX (CGRectGetHeight (self.observableScrollView .frame ) - self.observableScrollView .contentSize .height , 0.0 );
205- CGFloat updatedContentOffsetY =
206- MAX (self.observableScrollView .contentOffset .y + updatedConstraintConstant - currentDataInScrollViewOffset, 0.0 );
207- self.scrollViewKeyboardConstraint .constant += updatedConstraintConstant;
203+
204+ /* *
205+ Increase because scrollViewKeyboardConstraintOriginConstant should change only for ASYSimpleChatTextViewPositionAtScrollViewBottom
206+ */
207+ CGFloat updatedConstraintConstant = self.scrollViewKeyboardConstraintOriginConstant + constraintOffset;
208+ CGFloat previousConstraintConstant = self.scrollViewKeyboardConstraint .constant ;
209+ self.scrollViewKeyboardConstraint .constant = MAX (self.scrollViewKeyboardConstraintOriginConstant , updatedConstraintConstant);
210+ CGFloat constraintDelta = previousConstraintConstant - self.scrollViewKeyboardConstraint .constant ;
211+ CGFloat updatedScrollViewContentOffsetY =
212+ MAX (self.observableScrollView .contentOffset .y - constraintDelta - currentDataInScrollViewOffset, 0.0 );
208213
209214 UIView *rootView = [self .rootViewFinder findRootViewOf: self .chatTextView];
210215 UIViewAnimationOptions optionsFromCurve = [self .converter convert: animationCurve];
@@ -215,7 +220,7 @@ - (void)observer:(nonnull ASYInputViewObserver *)observer
215220 [rootView layoutIfNeeded ];
216221 if (self.textViewPositionInRelationToScrollView == ASYSimpleChatTextViewPositionAtScrollViewBottom) {
217222 self.observableScrollView .contentOffset =
218- CGPointMake (self.observableScrollView .contentOffset .x , updatedContentOffsetY );
223+ CGPointMake (self.observableScrollView .contentOffset .x , updatedScrollViewContentOffsetY );
219224 }
220225 }
221226 completion: nil ];
@@ -260,19 +265,19 @@ - (NSUInteger)currentNumberOfLines {
260265
261266- (void )resizeTextViewAnimated : (BOOL )animated {
262267 NSUInteger textViewNumberOfLines = self.currentNumberOfLines ;
263- CGFloat verticalAlignmentConstant = 0.0 ;
268+ CGFloat heightConstant = 0.0 ;
264269 if (textViewNumberOfLines <= self.minimumNumberOfLines ) {
265- verticalAlignmentConstant = self.minimumHeight ;
270+ heightConstant = self.minimumHeight ;
266271 } else if ((textViewNumberOfLines > self.minimumNumberOfLines ) && (textViewNumberOfLines <= self.maximumNumberOfLines )) {
267272 CGFloat currentHeight = [self currentHeight ];
268- verticalAlignmentConstant = (currentHeight > self.minimumHeight )
269- ? ((currentHeight < self.maximumHeight ) ? currentHeight : self.maximumHeight )
270- : self.minimumHeight ;
273+ heightConstant = (currentHeight > self.minimumHeight )
274+ ? ((currentHeight < self.maximumHeight ) ? currentHeight : self.maximumHeight )
275+ : self.minimumHeight ;
271276 } else if (textViewNumberOfLines > self.maximumNumberOfLines ) {
272- verticalAlignmentConstant = self.maximumHeight ;
277+ heightConstant = self.maximumHeight ;
273278 }
274- if (self.heightConstraint .constant != verticalAlignmentConstant ) {
275- [self updateVerticalAlignmentWithHeight: verticalAlignmentConstant animated: animated];
279+ if (self.heightConstraint .constant != heightConstant ) {
280+ [self updateWithHeight: heightConstant animated: animated];
276281 }
277282 if (textViewNumberOfLines <= self.maximumNumberOfLines ) {
278283 [self .chatTextView setContentOffset: CGPointZero animated: YES ];
@@ -295,7 +300,7 @@ - (void)updateHeightAndResize {
295300 [self resizeTextViewAnimated: NO ];
296301}
297302
298- - (void )updateVerticalAlignmentWithHeight : (CGFloat)height animated : (BOOL )animated {
303+ - (void )updateWithHeight : (CGFloat)height animated : (BOOL )animated {
299304 CGFloat originalHeight = CGRectGetHeight (self.chatTextView .frame );
300305 CGPoint updatedContentOffset = [self calculateUpdatedScrollViewContentOffsetWithHeight: height];
301306 self.heightConstraint .constant = height;
0 commit comments