如何让光标在UITextView中自动可见

如何让光标在UITextView中自动可见,第1张

正常情况下在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 Object

Dim 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光标位置并插入文字等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/9381990.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存