欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

IOS 开发之UITextField的光标操作扩展

程序员文章站 2023-12-19 13:45:04
ios 开发之uitextfield的光标操作扩展 简介 在ios开发中,有时候需要完全自主的定义键盘,用于完整的单词输入,例如计算机应用中,需要一次性的输入sin(,...

ios 开发之uitextfield的光标操作扩展

简介

在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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

上一篇:

下一篇: