简介

在iOS开发中,有时候需要完全自主的定义键盘,用于完整的单词输入,例如计算机应用中,需要一次性的输入sin(,在移动光标时要完整的跳过sin(,在删除时也要完整的删除,这就需要对光标的位置进行精确控制,而iOS并没有相关的函数可以直接操作光标,只给出了选择某个区域的功能,本文将介绍基于区域选择设计的UITextField扩展,用于获取光标位置以及移动光标。

实现原理

  • 光标位置的获取

    在textField中,有一个属性称之为selectedTextRange,这个属性为UITextRange类型,包含[start,end)两个值,通过实验我们可以发现,在没有文字被选取时,start代表当前光标的位置,而end=0;当有区域被选择时,start和end分别是选择的头和尾的光标位置,从0开始,并且不包含end,例如选择了0~3的位置,则start=0,end=4。

  • 光标的移动

    通过setSelectedTextRange:方法可以设置选取范围,我们只要设置一个选取单个字符的范围,即可移动光标而不选中。

关键属性

// 内容为[start,end),无论是否有选取区域,start都描述了光标的位置。
@property (nullable, readwrite, copy) UITextRange *selectedTextRange;
// 文首和文尾的位置
@property (nonatomic, readonly) UITextPosition *beginningOfDocument;
@property (nonatomic, readonly) UITextPosition *endOfDocument;

关键方法

// 获取以from为基准的to的偏移,例如abcde,光标在c后,则光标相对文尾的偏移为-2。
- (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition;
// 获取以from为基准偏移offset的光标位置。
- (nullable UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset;
// 创建一个UITextRange
- (nullable UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition;

具体实现

  • 下面的代码为UITextField创建了一个分类(Category),包含三个方法,分别用于获取光标位置、从当前位置偏移、从头偏移。
#import <UIKit/UIKit.h>

@interface UITextField (Extension)

- (NSInteger)curOffset;
- (void)makeOffset:(NSInteger)offset;
- (void)makeOffsetFromBeginning:(NSInteger)offset; @end
#import "UITextField+Extension.h"

@implementation UITextField (Extension)

- (NSInteger)curOffset{

    // 基于文首计算出到光标的偏移数值。
return [self offsetFromPosition:self.beginningOfDocument toPosition:self.selectedTextRange.start]; } - (void)makeOffset:(NSInteger)offset{ // 实现原理是先获取一个基于文尾的偏移,然后加上要施加的偏移,再重新根据文尾计算位置,最后利用选取来实现光标定位。
UITextRange *selectedRange = [self selectedTextRange];
NSInteger currentOffset = [self offsetFromPosition:self.endOfDocument toPosition:selectedRange.end];
currentOffset += offset;
UITextPosition *newPos = [self positionFromPosition:self.endOfDocument offset:currentOffset];
self.selectedTextRange = [self textRangeFromPosition:newPos toPosition:newPos]; } - (void)makeOffsetFromBeginning:(NSInteger)offset{ // 先把光标移动到文首,然后再调用上面实现的偏移函数。
UITextPosition *begin = self.beginningOfDocument;
UITextPosition *start = [self positionFromPosition:begin offset:0];
UITextRange *range = [self textRangeFromPosition:start toPosition:start];
[self setSelectedTextRange:range];
[self makeOffset:offset]; } @end

(一三〇)UITextField的光标操作扩展的更多相关文章

  1. 文本域光标操作(选、添、删、取)的jQuery扩展

    ; (function ($) { /* * 文本域光标操作(选.添.删.取)的jQuery扩展 @Mr.Think http://mrthink.net/text-field-jquery-exte ...

  2. jquery 文本域光标操作(选、添、删、取)

    一.JQuery扩展 ; (function ($) { /* * 文本域光标操作(选.添.删.取)的jQuery扩展 http://www.cnblogs.com/phpyangbo/p/55286 ...

  3. mysql(三) 数据表的基本操作操作

    mysql(三) 数据表的基本操作操作 创建表,曾删改查,主键,外键,基本数据类型. 1. 创建表 create table 表名( 列名 类型 是否可以为空, 列名 类型 是否可以为空 )ENGIN ...

  4. 学习PHP中好玩的Gmagick图像操作扩展的使用

    在 PHP 的图像处理领域,要说最出名的 GD 库为什么好,那就是因为它不需要额外安装的别的什么图像处理工具,而且是随 PHP 源码一起发布的,只需要在安装 PHP 的时候添加上编译参数就可以了. G ...

  5. 苹果新的编程语言 Swift 语言进阶(三)--基本运算和扩展运算

    一 基本操作运算 1. 赋值操作 在Swift 中,能够使用赋值操作为一个常量或一个变量赋值,也能够使用多元组一次为多个常量或变量赋值. Swift 的赋值操作与其他语言最大的不同是赋值操作除了可以为 ...

  6. 从零开始使用git第三篇:git撤销操作、分支操作和常见冲突

    从零开始使用git 第三篇:git撤销操作.分支操作和常见冲突 第一篇:从零开始使用git第一篇:下载安装配置 第二篇:从零开始使用git第二篇:git实践操作 第三篇:从零开始使用git第三篇:gi ...

  7. .net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能

    原文:.net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能         接上篇,上篇已经学习了界面的各种功能以及各种配置,这篇准备学习下代码控制许可证. ...

  8. python自动化开发-[第三天]-编码,函数,文件操作

    今日概要 - 编码详解 - 文件操作 - 初识函数 一.字符编码 1.代码执行过程 代码-->解释器翻译-->机器码-->执行 2.ASCII ASCII:一个Bytes代表一个字符 ...

  9. Python开发【第三章】:文件操作

    一.文件操作模式概述 1.打开文件的模式: r, 只读模式[默认] w,只写模式[不可读:不存在则创建:存在则删除内容:] a, 追加模式[不可读:不存在则创建:存在则只追加内容:] 2." ...

随机推荐

  1. JDBC查询优化,统计条数

    JDBC查询优化分析: 现有以下查询语句: String sql1 = "select * from userinfo";// 创建语句 String sql2 = "s ...

  2. 教你从手机中提取system镜像制作线刷救砖包的简单方法

    其实在制作刷机包的过程中,有时候没有官方或者第三方提供的救砖包(线刷),那怎么办?常规的方法有两种:(此处为常规方法,回读的方式暂不说明)     1.卡刷包转线刷包     2.dd命令导出分区镜像 ...

  3. [USACO 12DEC]Running Away From the Barn

    Description It's milking time at Farmer John's farm, but the cows have all run away! Farmer John nee ...

  4. 2015 多校联赛 ——HDU5299(树删边)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission ...

  5. salt基本使用之二(2)

    1.Event和Reactor Event是saltstack里面的对每个事件的一个记录,相比job更加底层. 一,查看Event事件 可以在master下再开一个终端执行以下命令可以查看Event事 ...

  6. WPF 窗口居中 & 变更触发机制

    窗口居中 & 变更触发机制 解决: 1.单实例窗口,窗口每次隐藏后再显示时,位置居中显示 2.多屏幕下单实例窗口,当父窗口移动到其它屏幕时,单实例窗口再次弹出时,位置才更新到父窗口屏幕. 3. ...

  7. JavaScript正则表达式模式匹配(6)——常用的正则表达式

    1.检查邮政编码 var pattern=/[1-9][0-9]{5}/; // 必须是6位,必须是数字,第一位不能为0 var str='274200'; alert(pattern.test(st ...

  8. JavaScript正则表达式模式匹配(4)——使用exec返回数组、捕获性分组和非捕获性分组、嵌套分组

    使用exec返回数组 var pattern=/^[a-z]+\s[0-9]{4}$/; var str='google 2012'; alert(pattern.exec(str)); //返回一个 ...

  9. Apache 443端口占用解决方法

    当运行httpd.exe时,出现如下问题 原因是启动Apache会占用443端口,而443被其他程序占用了.我们只需将Apache默认端口443改掉就行.网上搜了一下,说是更改Apache24\con ...

  10. word_count

    网址:http://www.wimoney.xin/HTML/upload.html 在我的网站上干不起,不晓得是不是文件保存的问题,也可能是windows和linux有些地方有差异,妈个鸡,我得再去 ...