- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在 UIScrollView
中的 textView 下方和之后有 UITextView
和其他 View 。当用户输入文本时,我更改 textView.contentSize.height 上的 textView 框架高度。这个想法是为用户保留查看所有文本和其他元素的可能性。我有一些问题。当用户点击时,我想滚动到这一行。这看起来一定是这样的:
我无法确定如何计算偏移量并始终滚动到当前插入符号。
我的初始屏幕:
所有 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];
}
但是没有用。
最佳答案
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/
抱歉这个奇怪的标题,但是,这正是我所需要的。我知道这是可以做到的,因为我见过其他应用程序这样做。 基本上,我的应用程序有一个启用分页的大 ScrollView ,其中包含一些嵌套的 ScrollVie
我还没有尝试过,但我假设一旦我知道用户想要在子 ScrollView 中滚动,我就必须禁用父 ScrollView 的滚动,对吗? 两个 ScrollView 都是水平滚动的。 如何暂时禁用父级的滚动
我需要实现这个方法: - (CGRect)zoomRectForScale:(float)scale withCenter:(CGPoint)center { 但我不知道如何获得我需要的中心坐标。通常
我想根据 UIAccelerometer 值滚动 ScrollView 。实现这一目标的最佳方法是什么? 最初,我根据获得的加速度计值将内容偏移设置为一个值。然后在每个 scrollViewDidEn
我有一个 UIScrollView,我需要底部淡入透明,这样它就不会突然切断内容。 UIScrollView 的背景是自定义颜色。这是我到目前为止所拥有的,但图层显示为白色,而不是自定义颜色。这就是我
我有一个 UIScrollviews 彼此存在的层次结构。 如何将特定区域的滑动事件重定向到内部 ScrollView ? 最佳答案 如果您将 UIScrollViews 设置为只能在一个轴或另一轴上
在我的应用程序中,我有一个扩展 UIScrollView 并在用户滚动时填充其内容的 View 。但是,如果用户滚动太快,则 UIScrollView 内填充的 View 不会及时创建,您实际上可以看
我有一个包含内容的 UIScroll View 。如果该内容溢出,使 ScrollView 可滚动,我想将 View 的底部设置为某种颜色。如果没有,我想将其设置为不同的颜色。 我的问题是,我不知道如
我有一个 ScrollView ,其中包含一个 UIImageView,以及一个额外的 UIScrollView 和 UIImageView。 我想要实现的是独立缩放和平移每个 ScrollView
类似的问题也有人问过这个,但我的困境其实和他们正好相反。我有一个全屏、分页 UIScrollView,每个页面都是屏幕的大小。在其中,我有一些页面本身就是 UIScrollViews,它们的宽度大于屏
我有一个 UIScrollView 和另一个 UIScrollView 。它们都水平滚动并且具有 pagingEnabled = YES。假设我开始滚动内部 ScrollView 并到达最右边界。如果
我有一个 UIScrollView,里面有一个(自定义)UIView。 在我的 scrollViewDidScroll 方法中,我正在调用 [myCustomView setNeedsDisplay]
我有一个水平滚动的 UICollectionView,其中填充了垂直滚动的 UITableViews(两者都是 UISCrollView 的子类)。当滚动手势开始沿任一方向滚动时,在其减速完成之前不会
iOS 8, swift 。我试图在水平 ScrollView 上创建垂直 ScrollView 。它们都是 UIScrollView。垂直 ScrollView 允许从底部向上滑动 View 。顶部
我需要一个分页的 UIScrollView,它以 UIScreenEdgePanGestureRecognizer 的方式检测屏幕边缘的平移,而不是像 UIPanGestureRecognizer 那
假设我有多个 ScrollView ,并且我希望在任何给定时间只打开其中一个 (scrollView.contentOffset != 0)。因此,当 scroll view 1 打开且 scroll
我在分页 UIScrollView(外部)中的 VC 中有 UIScrollView(内部 - UICollectionView 是诚实的)。两者都是水平的。当我向内滚动到边缘(左侧或右侧)时,它开始
如何在不干扰现有 UIScrollView 的情况下从现有 UIScrollView 获取重复的 UIScrollView。 第一个 ScrollView , UIScrollView *firstS
我的应用程序中有一个点,我删除了一个 ScrollView 并添加了另一个。我希望新 ScrollView 中也能出现上一个 ScrollView 中的相同手势。我尝试过: s
请告诉我如何在类似嵌套进程的 ScrollView 中设置 ScrollView 。 以下代码部分有效。 int x=10; int y=10; for(int i=0; i<5; i++) {
我是一名优秀的程序员,十分优秀!