国外推广网站有什么广州十大传媒公司
news/
2025/9/24 2:41:05/
文章来源:
国外推广网站有什么,广州十大传媒公司,wordpress 自定义目录结构,百姓网地址怎么创建对于IOS涉及文本输入常用的两个View是UITextView和UITextField#xff0c;一个用于复杂文本输入#xff0c;一个用于简单文本输入#xff0c;在大多数开发中涉及文本输入的场景使用这两个View能够满足需求。但是对于富文本编辑相关的开发#xff0c;这两个View就无法满足自…对于IOS涉及文本输入常用的两个View是UITextView和UITextField一个用于复杂文本输入一个用于简单文本输入在大多数开发中涉及文本输入的场景使用这两个View能够满足需求。但是对于富文本编辑相关的开发这两个View就无法满足自己业务的需要了。
在多数情况下设计富文本开发的业务大多需要根据键盘输入的内容根据业务场景对文本进行布局排版这方面有个开源的富文本编辑View那就是YYText网上也有很多对其源码分析的文章这里就不过多介绍了这个自定义的YYTextView堪称大神级性能和效果都很不错代码质量相当高可以细细研读。但是这个代码相对比较复杂对于研究如何自定义文本编辑View不太友好。然而苹果官方提供了一个简单版自定义文本编辑View的开源项目SimpleTextInput这个简单易理解下面就基于此说下如何自定义一个文本编辑的view
对于文本编辑而言设计两个关键点1、和键盘交互当点击键盘上的按键时屏幕上如何显示2、内容排版屏幕上的内容如何布局显示。
对于第一点iOS提供了两个相应协议1、UIKeyInput简单的键盘交互
2、UITextInput复杂的键盘交互可以看出UITextInput继承UIKeyInput因此包含了UIKeyInput所有接口
UIKeyInput只能输入字符因此提供的接口也简单只有是否有文本内容插入、删除三个接口 UITextInput用于输入点击键盘时屏幕不是显示最终内容时比如输入汉字时在输入拼音时屏幕显示的是拼音字符有个蓝色底色只有最终选中汉字时会将蓝色底色包围的拼音替换为汉字 对比只继承UIKeyInput的view继承UITextInput的view键盘多了红框选字的部分。
那么如何使用这两个协议呢很简单基于UIView创建一个自定义View子类继承UIKeyInput或者UITextInput
interface APLEditableCoreTextView : UIView UITextInput end
为了使自定义的view能够接受输入需要重载方法canBecomeFirstResponder返回YES这样自定义view才能相应输入
如果是继承UIKeyInput就只需实现
implementation APLEditableCoreTextView- (BOOL)canBecomeFirstResponder
{return YES;
}- (BOOL)hasText
{return (self.text.length ! 0);
}- (void)insertText:(NSString *)text
{}- (void)deleteBackward
{}end
这三个接口就可以了当点自定义的view处于第一响应时系统会触发hasText先判断是否有内容当点击键盘字母时会调insertText:(NSString*)text方法当点击键盘delete键会触发deleteBackward方法
如果是继承UITextInput需要实现的就比较多了这个协议的required下所有方法都必须实现再加上UIKeyInput的三个方法
/* Methods for manipulating text. */
// 根据给定的范围返回一个字符串一般是屏幕上已有的内容取range范围内的子字符串
- (nullable NSString *)textInRange:(UITextRange *)range;
// 用给定的字符串替换给定范围部分一般是屏幕上已有内容range范围内替换为text
- (void)replaceRange:(UITextRange *)range withText:(NSString *)text;/* Text may have a selection, either zero-length (a caret) or ranged. Editing operations are* always performed on the text from this selection. nil corresponds to no selection. */// 已选的范围
property (nullable, readwrite, copy) UITextRange *selectedTextRange;/* If text can be selected, it can be marked. Marked text represents provisionally* inserted text that has yet to be confirmed by the user. It requires unique visual* treatment in its display. If there is any marked text, the selection, whether a* caret or an extended range, always resides within.** Setting marked text either replaces the existing marked text or, if none is present,* inserts it from the current selection. */ // 标记的文本范围如果没有标记文本返回nil标记文本可以理解为输入内容时屏幕上蓝色包裹的字符串
property (nullable, nonatomic, readonly) UITextRange *markedTextRange; // Nil if no marked text.
// 标记文本如何显示
property (nullable, nonatomic, copy) NSDictionaryNSAttributedStringKey, id *markedTextStyle; // Describes how the marked text should be drawn.
// 用给定范围设置标记文本内容
- (void)setMarkedText:(nullable NSString *)markedText selectedRange:(NSRange)selectedRange; // selectedRange is a range within the markedText
// 解除标记文本可以理解为用键盘内容替换蓝色包裹部分比如选中键盘上汉字替换为屏幕上拼音时拼音就是要解除的标记文本
- (void)unmarkText;/* The end and beginning of the the text document. */
// 文本开始位置一般是0
property (nonatomic, readonly) UITextPosition *beginningOfDocument;
// 文本结束位置一般是屏幕文本长度
property (nonatomic, readonly) UITextPosition *endOfDocument;/* Methods for creating ranges and positions. */
// 用给定的开始和结束位置返回一个range
- (nullable UITextRange *)textRangeFromPosition:(UITextPosition *)fromPosition toPosition:(UITextPosition *)toPosition;
// 用给定位置和偏移量返回一个新的位置
- (nullable UITextPosition *)positionFromPosition:(UITextPosition *)position offset:(NSInteger)offset;
// 用给定的位置、方向和偏移量返回一个新的位置
- (nullable UITextPosition *)positionFromPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction offset:(NSInteger)offset;/* Simple evaluation of positions */
// 比较两个位置关系
- (NSComparisonResult)comparePosition:(UITextPosition *)position toPosition:(UITextPosition *)other;
// 返回给定起始位置和结束位置的偏移量
- (NSInteger)offsetFromPosition:(UITextPosition *)from toPosition:(UITextPosition *)toPosition;/* A system-provided input delegate is assigned when the system is interested in input changes. */
// 输入代理这个代理不需要自己继承UITextInputDelegate协议定义一个类系统会给其分配一个实例的
property (nullable, nonatomic, weak) id UITextInputDelegate inputDelegate;/* A tokenizer must be provided to inform the text input system about text units of varying granularity. */
// 分词器需要给其创建如果没有特殊需求直接使用UITextInputStringTokenizer就可以了
property (nonatomic, readonly) id UITextInputTokenizer tokenizer;/* Layout questions. */
// 根据给定的布局范围和方向返回一个最远的新位置
- (nullable UITextPosition *)positionWithinRange:(UITextRange *)range farthestInDirection:(UITextLayoutDirection)direction;
// 根据给定的位置和方向返回一个字符的范围
- (nullable UITextRange *)characterRangeByExtendingPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction;/* Writing direction */
// 根据给的位置和记录方向返回书写方向
- (NSWritingDirection)baseWritingDirectionForPosition:(UITextPosition *)position inDirection:(UITextStorageDirection)direction;
// 设置指定范围内的指定的书写方向
- (void)setBaseWritingDirection:(NSWritingDirection)writingDirection forRange:(UITextRange *)range;/* Geometry used to provide, for example, a correction rect. */
// 返回给定范围内的rect
- (CGRect)firstRectForRange:(UITextRange *)range;
// 返回给定位置的光标rect一般输入框都会有个闪烁的竖线这个竖线其实是个矩形为了能让这个竖线在文本间显示且不与文字重叠需要给字与字之间留够空隙这个空隙是文字布局时做到但是空隙大小是通过这个方法得到的
- (CGRect)caretRectForPosition:(UITextPosition *)position;
// 返回给定范围内的选区这是个数组因为选区内可能有个多个rect
- (NSArrayUITextSelectionRect * *)selectionRectsForRange:(UITextRange *)range API_AVAILABLE(ios(6.0)); // Returns an array of UITextSelectionRects/* Hit testing. */
// 返回给定点的最近位置
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point;
// 返回给定范围内指定点的最近位置
- (nullable UITextPosition *)closestPositionToPoint:(CGPoint)point withinRange:(UITextRange *)range;
// 返回给定点出的文本范围一般是用于分词比如在“今天天气不错”这个内容的“气”字位置处可能想要的的是“天气”这个词的范围
- (nullable UITextRange *)characterRangeAtPoint:(CGPoint)point;
这些方法的触发都是在与键盘交互时相应的。其中UITextInput有个属性inputDelegate这个不需要设置由系统设置分配的UIKeyboardImpl实例 通过调用堆栈可以看出当设置view为第一响应者时会给inputDelegate设置一UIKeyboardImpl的实例
其中tokenizer属性需要给其分配实例self.tokenizer [[UITextInputStringTokenizer alloc] initWithTextInput:self];用户给键盘使用实际view中并不怎么用这个属性
以上就是关于和键盘交互的所有说明记住UIKeyInput/UITextInput的接口都是有键盘触发的可以在这些接口实现断点调试看下堆栈比如hasText当点击键盘时会立即触发 再比如markedTextRange 等等通过堆栈发现执行UITextInput的接口时都是通过UIKeyboardImpl这个实例最终执行到UITextInput的接口实现这个UIKeyboardImpl就是inputDelegate的实例这个UITextInputDelegate协议有四个接口 我们在selectedTextRange方法处断点调试通过堆栈可以看出这个方法就是inputDelegate执行selectionDidChange最终执行了selectedTextRange 最后我们看下UITextInput中涉及到的两个类UITextPosition和UITextRange
interface UITextPosition : NSObjectendinterface UITextRange : NSObjectproperty (nonatomic, readonly, getterisEmpty) BOOL empty; // Whether the range is zero-length.
property (nonatomic, readonly) UITextPosition *start;
property (nonatomic, readonly) UITextPosition *end;end
通过定义可以看出UITextPosition是个空类没有任何变量和属性通过类名可以知道这是个定义位置的类但是并没有变量和属性如何知道位置的值呢。同时UITextRange是一个选区类有个属性empty显然是为了说明选区是否为空但是并没有实现这两个类都只给了定义并没有实现。因此需要开发者继承这两个类自定义UITextPosition和UITextRange。
interface APLIndexedPosition : UITextPositionproperty (nonatomic) NSUInteger index;
property (nonatomic) id UITextInputDelegate inputDelegate; (instancetype)positionWithIndex:(NSUInteger)index;endimplementation APLIndexedPosition#pragma mark IndexedPosition implementation// Class method to create an instance with a given integer index.(instancetype)positionWithIndex:(NSUInteger)index
{APLIndexedPosition *indexedPosition [[self alloc] init];indexedPosition.index index;return indexedPosition;
}end
interface APLIndexedRange : UITextRangeproperty (nonatomic) NSRange range;(instancetype)indexedRangeWithRange:(NSRange)range;endimplementation APLIndexedRange// Class method to create an instance with a given range(instancetype)indexedRangeWithRange:(NSRange)range
{if (range.location NSNotFound) {return nil;}APLIndexedRange *indexedRange [[self alloc] init];indexedRange.range range;return indexedRange;
}// UITextRange read-only property - returns start index of range.
- (UITextPosition *)start
{return [APLIndexedPosition positionWithIndex:self.range.location];
}// UITextRange read-only property - returns end index of range.
- (UITextPosition *)end
{return [APLIndexedPosition positionWithIndex:(self.range.location self.range.length)];
}// UITextRange read-only property - returns YES if range is zero length.
-(BOOL)isEmpty
{return (self.range.length 0);
}
这就是在selectedTextRange方法中返回的是APLIndexedRange的原因
以上是如何键盘交互对于已经在屏幕上的内容如何布局排版显示涉及文字绘制可以参考官方文档Core Text这是一个纯C语言的较为底层的文本排版渲染的框架其中UITextInput中- (CGRect)caretRectForPosition:(UITextPosition *)position接口就涉及core text相关方法来计算字间距这里就不对此进行详细阐述了网上对core text详解有很多而对UITextInput的使用较少这里对此做详细说明
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914626.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!