iOS7의 UITextView는 텍스트 문자열의 마지막 줄을 자릅니다.
iOS7의 UITextView는 정말 이상했습니다. UITextView의 마지막 줄을 입력하고 입력 할 때 스크롤보기가 예상대로 아래쪽으로 스크롤되지 않고 텍스트가 "잘립니다". clipsToBound 속성을 NO로 설정하려고 시도했지만 여전히 텍스트를 자릅니다.
나는 "setContentOffset : animated"를 호출하고 싶지 않습니다. 왜냐하면 하나는 매우 엉뚱한 솔루션입니다. 둘째, 커서가 텍스트 뷰의 중간 (수직)에 있으면 원하지 않는 스크롤이 발생합니다.
다음은 스크린 샷입니다.
어떤 도움이라도 대단히 감사하겠습니다!
감사!
문제는 iOS 7 때문입니다. 텍스트보기 대리자에 다음 코드를 추가합니다.
- (void)textViewDidChange:(UITextView *)textView {
CGRect line = [textView caretRectForPosition:
textView.selectedTextRange.start];
CGFloat overflow = line.origin.y + line.size.height
- ( textView.contentOffset.y + textView.bounds.size.height
- textView.contentInset.bottom - textView.contentInset.top );
if ( overflow > 0 ) {
// We are at the bottom of the visible text and introduced a line feed, scroll down (iOS 7 does not do it)
// Scroll caret to visible area
CGPoint offset = textView.contentOffset;
offset.y += overflow + 7; // leave 7 pixels margin
// Cannot animate with setContentOffset:animated: or caret will not appear
[UIView animateWithDuration:.2 animations:^{
[textView setContentOffset:offset];
}];
}
}
내가 찾은 해결책 여기가 당신이 UITextView를 만든 후 한 줄 수정을 추가했다 :
self.textview.layoutManager.allowsNonContiguousLayout = NO;
이 한 줄 은 iOS7에서 구문 강조 표시를 사용하여 UITextView 기반 코드 편집기를 만드는 세 가지 문제를 해결했습니다 .
- 편집 할 때 텍스트를 계속 볼 수 있도록 스크롤 (이 게시물의 문제)
- UITextView가 키보드를 닫은 후 가끔 점프
- 보기를 스크롤하려고 할 때 UITextView 임의 스크롤 점프
참고로 키보드가 표시되거나 숨겨 질 때 전체 UITextView의 크기를 조정했습니다.
다음 -textViewDidChangeSelection:
과 같이 UITextViewDelegate에서 delegate 메소드를 구현해보십시오 .
-(void)textViewDidChangeSelection:(UITextView *)textView {
[textView scrollRangeToVisible:textView.selectedRange];
}
다음은 davidisdk가 선택한 답변의 수정 된 버전입니다.
- (void)textViewDidChange:(UITextView *)textView {
NSRange selection = textView.selectedRange;
if (selection.location + selection.length == [textView.text length]) {
CGRect caretRect = [textView caretRectForPosition:textView.selectedTextRange.start];
CGFloat overflow = caretRect.origin.y + caretRect.size.height - (textView.contentOffset.y + textView.bounds.size.height - textView.contentInset.bottom - textView.contentInset.top);
if (overflow > 0.0f) {
CGPoint offset = textView.contentOffset;
offset.y += overflow + 7.0f;
[UIView animateWithDuration:0.2f animations:^{
[textView setContentOffset:offset];
}];
}
} else {
[textView scrollRangeToVisible:selection];
}
}
textView의 콘텐츠 크기가 경계보다 크고 커서가 화면에서 벗어난 경우 (예 : 키보드 사용 및 화살표 키 누르기) textView가 삽입되는 텍스트에 애니메이션이 적용되지 않는 버그가 발생했습니다.
Imho 이것은 iOS 7의 모든 일반적인 UITextView 스크롤 / 키보드 관련 문제에 대한 확실한 대답 입니다. 깔끔하고 읽기 쉽고 사용하기 쉽고 유지 관리가 쉽고 쉽게 재사용 할 수 있습니다.
기본 트릭 : 콘텐츠 삽입이 아닌 UITextView의 크기를 변경하기 만하면됩니다!
다음은 실습 예제입니다. Autolayout을 사용하는 NIB / Storyboard 기반 UIViewController가 있고 UITextView가 UIViewController에서 전체 루트 뷰를 채운다는 것은 당연한 일입니다. 그렇지 않은 경우 필요에 맞게 textViewBottomSpaceConstraint를 변경하는 방법을 조정해야합니다.
어떻게:
다음 속성을 추가합니다.
@property (nonatomic, weak) IBOutlet NSLayoutConstraint *textViewBottomSpaceConstraint;
@property (nonatomic) CGFloat textViewBottomSpaceConstraintFromNIB;
Interface Builder에서 textViewBottomSpaceConstraint를 연결하십시오 ( 잊지 마세요! ).
그런 다음 viewDidLoad에서 :
// Save the state of the UITextView's bottom constraint as set up in your NIB/Storyboard
self.textViewBottomSpaceConstraintFromNIB = self.textViewBottomSpaceConstraint.constant;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShowNotification:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHideNotification:)
name:UIKeyboardWillHideNotification
object:nil];
다음 메서드를 추가하여 키보드 크기 조정을 처리합니다 ( https://github.com/brennanMKE/Interfaces/tree/master/Keyboarding 덕분에 -이 메서드는 brennan에서 제공합니다!).
- (void)keyboardWillShowNotification:(NSNotification *)notification {
CGFloat height = [self getKeyboardHeight:notification forBeginning:TRUE];
NSTimeInterval duration = [self getDuration:notification];
UIViewAnimationOptions curve = [self getAnimationCurve:notification];
[self keyboardWillShowWithHeight:height duration:duration curve:curve];
}
- (void)keyboardWillHideNotification:(NSNotification *)notification {
CGFloat height = [self getKeyboardHeight:notification forBeginning:FALSE];
NSTimeInterval duration = [self getDuration:notification];
UIViewAnimationOptions curve = [self getAnimationCurve:notification];
[self keyboardWillHideWithHeight:height duration:duration curve:curve];
}
- (NSTimeInterval)getDuration:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
NSTimeInterval duration;
NSValue *durationValue = [info objectForKey:UIKeyboardAnimationDurationUserInfoKey];
[durationValue getValue:&duration];
return duration;
}
- (CGFloat)getKeyboardHeight:(NSNotification *)notification forBeginning:(BOOL)forBeginning {
NSDictionary *info = [notification userInfo];
CGFloat keyboardHeight;
NSValue *boundsValue = nil;
if (forBeginning) {
boundsValue = [info valueForKey:UIKeyboardFrameBeginUserInfoKey];
}
else {
boundsValue = [info valueForKey:UIKeyboardFrameEndUserInfoKey];
}
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (UIDeviceOrientationIsLandscape(orientation)) {
keyboardHeight = [boundsValue CGRectValue].size.width;
}
else {
keyboardHeight = [boundsValue CGRectValue].size.height;
}
return keyboardHeight;
}
- (UIViewAnimationOptions)getAnimationCurve:(NSNotification *)notification {
UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
switch (curve) {
case UIViewAnimationCurveEaseInOut:
return UIViewAnimationOptionCurveEaseInOut;
break;
case UIViewAnimationCurveEaseIn:
return UIViewAnimationOptionCurveEaseIn;
break;
case UIViewAnimationCurveEaseOut:
return UIViewAnimationOptionCurveEaseOut;
break;
case UIViewAnimationCurveLinear:
return UIViewAnimationOptionCurveLinear;
break;
}
return kNilOptions;
}
마지막으로, 키보드 알림에 반응하는 이러한 메서드를 추가하고 UITextView의 크기를 조정합니다.
- (void)keyboardWillShowWithHeight:(CGFloat)height duration:(CGFloat)duration curve:(UIViewAnimationOptions)curve
{
CGFloat correctionMargin = 15; // you can experiment with this margin so the bottom text view line is not flush against the keyboard which doesn't look nice
self.textViewBottomSpaceConstraint.constant = height + correctionMargin;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
- (void)keyboardWillHideWithHeight:(CGFloat)height duration:(CGFloat)duration curve:(UIViewAnimationOptions)curve
{
self.textViewBottomSpaceConstraint.constant = self.textViewBottomSpaceConstraintFromNIB;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:duration delay:0 options:curve animations:^{
[self.view layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
또한 이러한 메서드를 추가하여 사용자가 클릭 한 위치로 자동으로 스크롤합니다.
- (void)textViewDidBeginEditing:(UITextView *)textView
{
[textView scrollRangeToVisible:textView.selectedRange];
}
- (void)textViewDidChangeSelection:(UITextView *)textView
{
[textView scrollRangeToVisible:textView.selectedRange];
}
textView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 10.0, 0.0);
이것은 또한 당신의 문제를 해결할 것입니다
StoryBoard를 사용하는 경우 AutoLayout을 켜고 (기본적으로) UITextView에 대한 상단 / 하단 제약 조건을 설정하지 않은 경우에도이 동작이 발생할 수 있습니다. 파일 검사기를 확인하여 AutoLayout 상태를 확인하십시오.
다음은 davididsk의 가장 우수한 솔루션의 MonoTouch 버전입니다 (위에서).
TextView.SelectionChanged += (object sender, EventArgs e) => {
TextView.ScrollRangeToVisible(TextView.SelectedRange);
};
TextView.Changed += (object sender, EventArgs e) => {
CGRect line = TextView.GetCaretRectForPosition(TextView.SelectedTextRange.Start);
nfloat overflow = line.Y + line.Height -
(TextView.ContentOffset.Y +
TextView.Bounds.Height -
TextView.ContentInset.Bottom -
TextView.ContentInset.Top );
if ( overflow > 0 )
{
// We are at the bottom of the visible text and introduced
// a line feed, scroll down (iOS 7 does not do it)
// Scroll caret to visible area
CGPoint offset = TextView.ContentOffset;
offset.Y+= overflow + 7; // leave 7 pixels margin
// Cannot animate with setContentOffset:animated:
// or caret will not appear
UIView.Animate(0.1,()=> {
TextView.ContentOffset = offset;
});
}
};
이 줄은 마지막 텍스트 줄이 표시되지 않도록합니다.
textView.scrollEnabled = false
이것을 제거하고 무슨 일이 일어나는지보십시오 ...
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
이것은 나를 위해 문제를 해결했습니다.
.m에서 theViewDelegate를 "self"로 설정하고 .h에서 사용한 다음이 코드를 .m에 추가하십시오.
텍스트가있는 다음 줄로 이동 (래핑 또는 캐리지 리턴) 및 타이핑하기 위해 발생하는이 결함의 버전을 모두 처리합니다. 그리고 캐리지 리턴 만 있고 타이핑없이 다음 줄로 이동합니다 (다른 코드와 달리이 코드는 이 두 번째 글리치 시나리오에서 잘리지 않는 깜박이는 커서를 표시하기 위해 스크롤됩니다.)
//!!!*!!****!*!**!*!*!!!MAKE SURE YOU SET DELEGATE AND USE THE <UITEXTVIEWDELEGATE>
-(void)textViewDidChange:(UITextView *)textView {
[theTextView scrollRangeToVisible:[textView selectedRange]];//resizing textView frame causes text itself "content frame?" to still go below the textview frame and get clipped... auto-scrolling must be implimented. (iOS7 bug)
}
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if (([text isEqualToString:@"\n"]) && (range.location == textView.text.length)) {//"return" at end of textView
[textView scrollRectToVisible:CGRectMake(5,5,5,999999999999999999) animated:NO];//for some reason the textViewDidChange auto scrolling doesnt work with a carriage return at the end of your textView... so I manually set it INSANELY low (NOT ANIMATED) here so that it automagically bounces back to the proper position before interface refreshes when textViewDidChange is called after this.
}
return YES;
}
참조 URL : https://stackoverflow.com/questions/18966675/uitextview-in-ios7-clips-the-last-line-of-text-string
'Nice programing' 카테고리의 다른 글
jquery 데이터 테이블 기본 정렬 (0) | 2021.01.10 |
---|---|
JQuery select2는 목록의 옵션에서 기본값을 설정합니까? (0) | 2021.01.10 |
IE 브라우저의 텍스트 필드에서 Selenium WebDriver 입력이 매우 느림 (0) | 2021.01.10 |
'Microsoft.Build.Tasks.v14.0.dll'을 찾을 수 없기 때문에 Visual Studio 2015에서 빌드 할 수 없습니다. (0) | 2021.01.10 |
클래스의 모든 인스턴스 인쇄 (0) | 2021.01.10 |