正常情况下在UITextView中系统会自动处理光标可见,然而实际开发中产品设计并不会局限于系统本身的空间,但作为开发者必须尽其所能的去实现,满足产品设计,达到最佳的用户体验,才能让产品有立足之地。
下面有一种情形可能是我们经常遇到的,如邮件的编辑界面。
该界面有如下控件
UITextField toTextField; // 收件人
UITextField ccTextField; // 抄送
UITextField subjectTextField; // 主题
UITextView contentTextView; // 内容
如果内容过多时,就显示不全,那么我们还必须加一个UIScrollView将上面的控件包着,支持上下滑动界面,以便查看所有内容
UIScrollView scrollView;
也许有人发现,textView本身是可以滑动的,而scrollView也可以滑动,这样会造成体验非常糟糕的结果。这种糟糕的体验起码我是决不能让其发生的,相信大家也是如此。
解决方案就是让textView的frame自适应其contentSize,然后再动态改变scrollview的contentSize,这样textview就不会独自滑动了。
上边的具体实现,相信大部分人都能知道。然后实现过的人又会遇到一个棘手的问题,内容过多时,光标不会自动向上移动,导致光标不见了。就是在这篇文章主要介绍的问题:“光标自动可见”
// 这里只介绍textview 自适应及光标自动可见的问题,所以其他的细节都省略。
#pragma mark -- KVO --
- (void)addContentView
{
contentTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 157, 3200f, 346)];
// 设置底部间距50,这个非常重要。不加的话,会出现异常的问题,可以自己动手试一试
contentTextViewcontentInset = UIEdgeInsetsMake(0, 0, 50, 0);
// 使用KVO 观察contentSize的动态
[contentTextView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
CGSize size = scrollViewframesize;
sizeheight = CGRectGetMaxY(contentTextViewframe);
scrollViewcontentSize = size;
[scrollView addSubview: contentTextView]
}
- (void)observeValueForKeyPath:(NSString )keyPath
ofObject:(id)object
change:(NSDictionary )change
context:(void )context
{
// 监听textview 的contensize是否改变
if ([keyPath isEqualToString:@"contentSize"])
{
UITextView view = object;
// 获取textView最新的contentSize的高度
CGFloat contentHeight = viewcontentSizeheight;
CGSize scrollViewContentSize = scrollViewcontentSize;
if (contentHeight > 346) { // 346 是textview的默认高度
CGRect frame = viewframe;
framesizeheight = contentHeight + 50; // 50 是底部间距
viewframe = frame;
scrollViewContentSizeheight = viewframeoriginy + viewframesizeheight;
}else {
scrollViewContentSizeheight = viewframeoriginy + viewframesizeheight - 14;
}
scrollViewcontentSize = scrollViewContentSize;
// 获取光标的位置区域
CGRect cursorPosition = [view caretRectForPosition:viewselectedTextRangestart];
// 光标相对顶层视图(scrollView)frame的坐标高度
CGFloat height = cursorPositionoriginy + viewframeoriginy - _mailScrollViewcontentOffsety;
//
CGFloat currentPoint = cursorPositionoriginy;
// 可见scrollView区域, 由于键盘有中英输入法,所以会导致可见区域的变化
CGFloat cursorValueMax = [UIScreen mainScreen]boundssizeheight - 64 - selfkeyboardkeyboardHeight;
if (height > cursorValueMax - 50) { // 当光标在可见区域底部50pix内,即距离键盘50pix内
[scrollView setContentOffset:CGPointMake(0, currentPoint + viewframeoriginy - cursorValueMax + 50) animated:YES];
} else if (height < 20) { // 当光标在可见区域顶部20pix内,即距离顶部20pix内
[scrollView scrollRectToVisible:CGRectMake(0, cursorPositionoriginy - 20, 320, 60) animated:YES];
}
}
}
如果是 <input> <textarea> 一类输入框, 内部纯文本, 比较好模拟
我的方案是使用相同的样式, 维护一份拷贝, 取出标签的宽度即可,
复杂一些的话就在结尾加一个标签, 能从标签获取到光标的位置
windowgetSelction()getRangeAt(0)startOffset 去取位置,
sel = getSelection()
documentonclick = function(event) {
eventpreventDefault();
range = new Range;
rangeselectNode(eventtarget);
selremoveAllRanges();
seladdRange(range)
}
documentonclick = function(event) {
eventpreventDefault()
consolelog(eventtargetgetClientRects()[0])
}
Selection 对应的是界面上的选中内容, 而 Range 是 Selection 当中的一个选中的区域
简单的理解是, 一个 Selection 里会有多个 Range, Range 包含起始位置结束位置等等,
起始未知需要知道在哪个节点, 偏移量是多少等等
当然还有根据 Selection 跟 Range 用上面的位置信息来 *** 作的 API
具体 *** 作的代码大概要结合 StackOverflow 上具体的用例来理解的了
简单的自己写一个比如, 选中点击位置
这个两个 API 的兼容性有一些问题, 比如 new Range 会在 Safari 保存,
比如 rangebaseNode 在 Firefox 下不存在
为了减少兼容性造成的影响, 可以用 rangy 这个模块:
>
有点答跑题了 后面回到重点 答案在 MDN 关于这两个 API 的文档当中,
在 Range 的示例当中, 有试验的新 API 来提供对应的功能
>
RangegetBoundingClientRect()
Returns a ClientRect object which bounds the entire contents of the Range; this would be the union of all the rectangles returned by rangegetClientRects()
RangegetClientRects()
Returns a list of ClientRect objects that aggregates the results of ElementgetClientRects() for all the elements in the Range
这两个 API 就可以返回选中的 range 的像素位置了
然后按照文档的提示, 对于元素还有 getClientRects 这个 API 可以用于获取标签的像素位置:
>
The ElementgetClientRects() method returns a collection of rectangles that indicate the bounding rectangles for each box in a client
写个脚本测试一下, 确实 OK:
关于具体用例看网上的文章: >
关于浏览器兼容性可以看这里, 似乎蛮好的: >
代码如下:
Dim wdapp As ObjectDim wd As Object
Private Sub Command1_Click()
Set wdapp = CreateObject("WordApplication") '创建Word运用环境
Set wd = wdappDocumentsopen(AppPath & "\midocx") '打开Word
wdappVisible = True
End Sub
Private Sub Command2_Click()
wdappselectioninsertafter "Hello World!" '插入相关字符!
MsgBox wdappselectionrangestart
End Sub
Private Sub Form_Unload(Cancel As Integer)
wdClose True '关闭Word文件
wdappQuit '退出word运用环境
End Sub
附件如下:
话说大哥,一分悬赏分都不给吗?专门给你写的代码和测试文件啊,你这个题怎么滴也得50分吧,我觉得!
用椭圆工具(不是椭圆选框工具哦)按住shift+alt 画出一个正圆
从上 左拉出两条参考线自动吸附路径圆的中心 选择自由形状工具 里面找个三角形 按住shift画出三角 自由变换路径对准圆的中心不就好了(路径圆和路径三角都存在)
你也可以先画出圆做出样式后再添加三角嘛 方法很多的
稍等上代码!!
<html><head>
<script type="text/javascript">
function show_coords(event){
var x = eventclientX;
var y = eventclientY;
var say = documentall("coords");
sayinnerHTML = "X:"+x+" Y:"+y;
saystyleposition = "absolute";
saystyleleft = x + 30;
saystyletop = y;
}
</script>
</head>
<body onmousemove="show_coords(event)">
<p id="coords"></p>
</body>
<html>
希望我的回答对你有用,有用就采纳!!!谢谢!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 401 Transitional//EN" ">
以上就是关于如何让光标在UITextView中自动可见全部的内容,包括:如何让光标在UITextView中自动可见、HTML contenteditable 标签里怎样获取光标像素位置、vb 获取word光标位置并插入文字等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)