gpt4 book ai didi

ios - 在 UIScrollVIew 中确定 UITextView 的滚动偏移量

转载 作者:可可西里 更新时间:2023-11-01 06:10:18 25 4
gpt4 key购买 nike

我在 UIScrollView 中的 textView 下方和之后有 UITextView 和其他 View 。当用户输入文本时,我更改 textView.contentSize.height 上的 textView 框架高度。这个想法是为用户保留查看所有文本和其他元素的可能性。我有一些问题。当用户点击时,我想滚动到这一行。这看起来一定是这样的:

enter image description here

我无法确定如何计算偏移量并始终滚动到当前插入符号。

我的初始屏幕:

enter image description here

所有 View 都是 UIScrollView 的 subview 。每次当用户输入 @"\n" 时,我都会更改 UITextView 框架:

CGRect textViewFrame = textView.frame;
CGSize textViewContentSize = textView.contentSize;
NSLog(@"textView content size: %@", NSStringFromCGSize(textViewContentSize));
textViewFrame.size.height = textViewContentSize.height;
[textView setFrame:textViewFrame];

然后我增加 UIScrollView contentSize。我的问题 - 我不明白如何在键盘下滚动到 textView 的 CURSOR。我尝试做一些事情:

CGPoint cursorPosition = [textView caretRectForPosition:textView.selectedTextRange.start].origin;

CGPoint relativeCursorPoint = [textView convertPoint:cursorPosition toView:scrollView];

if(textView.isFirstResponder && relativeCursorPoint.y >= scrollViewFrame.size.height + scrollView.contentOffset.y)
{
int offset = relativeCursorPoint.y - scrollViewFrame.size.height + 18.0f;
//int offset = textViewRect.origin.y - scrollViewFrame.size.height + 18.0f;
[scrollView setContentOffset:CGPointMake(0, offset) animated:YES];
}

但是没有用。

最佳答案

enter image description here

A.) 为了实现与 Apple Notes 滚动 + 键盘关闭类似的效果,我首先在 UIScrollView 中添加了一个 UITextView。

B.) 然后将自己添加为键盘变化的观察者:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewDidBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];

C.) 然后当用户点击 TextView /文本字段时,将调用下面的方法。您获取键盘的开始高度和结束高度,并将名为 keyboardHeight 的变量设置为 endHeight 值(稍后使用)。

下面计算的“差异”用于在用户上下移动自动更正/建议栏时上下移动文本。如果您不想这样做,您可以将 textView 上的“autocorrectionType”设置为 false。

-(void)keyboardWillChangeFrame:(NSNotification *)n {

float beginHeight = [[n.userInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size.height;
float endHeight = [[n.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size.height;
float difference = beginHeight-endHeight;
keyBoardHeight = endHeight; //set the var

//animate change
if (difference != 0){ //animate frame change in your textview }
}

D.) 在 textViewDidBegin 方法中,将 UIScrollview 移动到屏幕顶部,因此 textview 与顶部齐平 (setContentOffset)。

您计算 TextView 的高度,因为它应该在 View 顶部和键盘顶部之间,在下面称为“initialTVHeight”。

您应该强制 TextView 启用滚动,因此将 textView.contentSize 设置为最小尺寸 (initialTVHeight) + 一个像素 - 这会强制滚动。

-(void)textViewDidBeginEditing:(UITextView *)textView {

//need to move the tv up to the top
float yOff = 0;
yOff += durationCell.frame.size.height;
yOff += reminderCell.frame.size.height;
yOff += fixedCell.frame.size.height;
yOff += repeatCell.frame.size.height;
[mainScroller setContentOffset:CGPointMake(0, yOff) animated:true];

//resize the textview to meet the top of the keyboard
float padding = 0; //padding between keyboard and last line in the textview
initialTVHeight = h - 60 - keyBoardHeight - padding; //the height when text does not overflow
textTV.frame = CGRectMake(0, textTV.frame.origin.y, w, initialTVHeight); //set the frame to that size

//if smaller than minimum, increase (if editing existing text)
if (textTV.contentSize.height < initialTVHeight){
textTV.contentSize = CGSizeMake(w, initialTVHeight+1); //force initial scroll
}
}

E.) 此方法将 textView contentSize 更新为最小高度以确保启用滚动(即,如果只有两行文本,用户仍然可以反弹滚动)。在 textView 内容比初始大小长的地方,让它自然增长。

-(void)textViewDidChange:(UITextView *)textView {
//require minimum height for scroll
if (textTV.contentSize.height < initialTVHeight){ //content height comes in under, force scroll
textTV.contentSize = CGSizeMake(w, initialTVHeight+1); //adding one forces scroll
}
}

F.) 添加这些方法,确保键盘仅在用户拖动时关闭(而不是在用户输入新行时)

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
if ([scrollView isEqual:textTV]){
enableDragDismiss = true;
}
}
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
if ([scrollView isEqual:textTV]){
enableDragDismiss = false;
}
}

G.) 最后,添加这个方法,如果用户拖动到键盘高度以下,它会关闭键盘。

-(void)scrollViewDidScroll:(UIScrollView *)scrollView {

if (enableDragDismiss && [scrollView isEqual:textTV]){

float y = [textTV.panGestureRecognizer locationInView:self.view].y;
float keyboardY = h-keyBoardHeight;

if (y > keyboardY){
enableDragDismiss = false; //allow only once
[textTV resignFirstResponder];
[UIView animateWithDuration:0.5f
delay:0.0f
usingSpringWithDamping:1.0f
initialSpringVelocity:0.8f
options:UIViewAnimationOptionCurveEaseOut
animations:^{
mainScroller.contentOffset = CGPointMake(0, 0);
textTV.contentOffset = CGPointMake(0, 0);
}
completion:^(BOOL finished){
}];

float yOff = 60;
yOff += durationCell.frame.size.height;
yOff += reminderCell.frame.size.height;
yOff += fixedCell.frame.size.height;
yOff += repeatCell.frame.size.height;
textTV.frame = CGRectMake(0, textTV.frame.origin.y, w, h-yOff);
}
}
}

关于ios - 在 UIScrollVIew 中确定 UITextView 的滚动偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18122289/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com