UITextView:定制选中文字的菜单和用代码选择文字
来源:互联网 发布:如何在知乎添加话题 编辑:程序博客网 时间:2024/06/06 10:07
前言
先看一篇文章中的文字(原文出处:iOS 7系列译文:认识 TextKit):
iOS 4:iOS 3.2 发布仅仅几个月后就发布了,文本方面没有一丁点新功能。(个人经历:在 WWDC,我走近工程师们,告诉他们我想要一个完善的 iOS 文本布局系统。回答是:“哦…提交个请求。”不出所料…)
iOS 5:文本方面没啥变化。(个人经历:在 WWDC,我和工程师们谈及 iOS 上文本系统。回答是:“我们没有看到太多的请求…” 靠!)
iOS 6:有些动作了:属性文本编辑被加入了UITextView。很不幸的是,它很难定制。默认的UI有粗体、斜体和下划线。用户可以设置字体大小和颜色。粗看起来相当不错,但还是没法控制布局或者提供一个便利的途径来定制文本属性。然而对于(文本编辑)开发者,有一个大的新功能:可以继承 UITextView 了,这样的话,除了以前版本提供的键盘输入外,开发者可以“免费”获得文本选择功能。必须实现一个完全自定义的文本选择功能,可能是很多对非纯文本工具开发的尝试半途而废的原因。(个人经历:我,WWDC,工程师们。我想要一个 iOS 的文本系统。回答:“嗯。吖。是的。也许?看,它只是不执行…” 所以毕竟还是有希望,对吧?)
iOS 7:终于来了,TextKit。
很久之前就写了关于本文所说的两个功能的Demo,现在才有空总结下,清下草稿箱里的笔记。
看了以上文字才知道原来定制选中文字菜单和选择文字是iOS 6才能获取的特性,以上文字出处的作者绝对是个元老级iOS开发者了,从iOS 2玩到了iOS 7。
Anyway,定制UITextView绝对是件好玩的事。
继承UITextView
1.定制选中文字的菜单
首先新建一个类,继承自UITextView,假设类名为MyTextView,关键代码如下:
/* 选中文字后是否能够呼出菜单 */- (BOOL)canBecameFirstResponder { return YES;}/* 选中文字后的菜单响应的选项 */- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { if (action == @selector(copy:)) { // 菜单不能响应copy项 return NO; } else if (action == @selector(selectAll:)) { // 菜单不能响应select all项 return NO; } // 事实上一个return NO就可以将系统的所有菜单项全部关闭了 return NO;}
以上第一个方法用来确保我们选中文字后的菜单可以弹出,第二个方法用来关闭菜单中所有系统的菜单项,如copy, select, select all等。
然后使用UIMenuController定制菜单:
// 自定义text view选中文字后的菜单 UIMenuItem *selectItem = [[UIMenuItem alloc] initWithTitle:@"选择文字" action:@selector(callSelectText:)]; UIMenuItem *cancelItem = [[UIMenuItem alloc] initWithTitle:@"取消选中" action:@selector(cancelSelection:)]; [UIMenuController sharedMenuController].menuItems = @[selectItem, cancelItem];
注意必须实现两个MenuItem的响应方法才能显示出菜单:
#pragma mark - Menu Item Actions- (void)callSelectText:(id)sender { self.currentSelection_ = self.myTextView.selectedRange; self.selectOptionView.hidden = NO; [self.location_inputTextField becomeFirstResponder];}- (void)cancelSelection:(id)sender { self.myTextView.selectedRange = NSRangeZero;}
最终效果如下:
之前的项目没有要求定制菜单项的图像,直接看SDK的内容的话貌似也没有Image之类的属性或方法,所以深层次定制菜单项的内容不得而知了。
2.通过代码选中一段文字
这个很简单,直接改变UITextView的selectedRange属性的值就可以了:
@property(nonatomic) NSRange selectedRange;
例如我们点击选择文字后弹出一个文字选择的输入视图,这个我用一个XIB文件定制:
小心了,将xib中的UI组件和View Controller中的Outlet连接时,在代码中要先从xib文件中加载视图,才能使用其中的UI组件,例如:
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:@"SelectOptionView" owner:self options:nil]; self.selectOptionView = nibViews[0]; self.selectOptionView.center = CGPointMake(self.view.center.x, self.view.bounds.size.height / 3); self.selectOptionView.hidden = YES; [self.view addSubview:self.selectOptionView]; // 要先加载了nib,IBOutlet才有意义,然后再设置其属性 self.location_inputTextField.delegate = self; self.length_inputTextField.delegate = self;
如果将
self.location_inputTextField.delegate =self;
self.length_inputTextField.delegate =self;
这两行代码置于loadNibNamed方法之前,那么两个文本输入框的delegate将为空(因为他们本身都是空,还没有加载)。选择文字的Action代码为:
#pragma mark - Select View Actions- (IBAction)selectText:(id)sender { NSInteger loc = self.location_inputTextField.text.integerValue; NSInteger len = self.length_inputTextField.text.integerValue; NSUInteger textLength = self.myTextView.text.length; if (loc < 0 || len < 0 || loc > textLength || len > textLength) { UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"错误" message:@"输入出错,输入的数不能小于0和大于文本长度" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil]; [alerView show]; return; } self.currentSelection_ = NSMakeRange(loc, len); [self finishSelectingText];}- (IBAction)cancelSelectText:(id)sender { [self finishSelectingText];}- (void)finishSelectingText { [self.location_inputTextField resignFirstResponder]; [self.length_inputTextField resignFirstResponder]; self.selectOptionView.hidden = YES; [self.myTextView becomeFirstResponder]; self.myTextView.selectedRange = self.currentSelection_;}
没错,只要一句self.myTextView.selectedRange =self.currentSelection_;就可以了。
另外,我们可以在UITextView的以下方法中监听到某段文字被选中:
#pragma mark - UITextView Delegate- (void)textViewDidChangeSelection:(UITextView *)textView { NSLog(@"Selection changed"); NSLog(@"loc = %d", self.myTextView.selectedRange.location); NSLog(@"len = %d", self.myTextView.selectedRange.length);}
控制台输出如下:
2014-02-16 23:33:56.197 MyTextView[4890:70b] Selection changed2014-02-16 23:33:56.198 MyTextView[4890:70b] loc = 5072014-02-16 23:33:56.198 MyTextView[4890:70b] len = 02014-02-16 23:33:56.334 MyTextView[4890:70b] Selection changed2014-02-16 23:33:56.335 MyTextView[4890:70b] loc = 5072014-02-16 23:33:56.335 MyTextView[4890:70b] len = 52014-02-16 23:34:05.291 MyTextView[4890:70b] Selection changed2014-02-16 23:34:05.292 MyTextView[4890:70b] loc = 102014-02-16 23:34:05.292 MyTextView[4890:70b] len = 100
3.让键盘主动出现
为了让用户更省心,我们可以在一个带输入框的视图出现时就让键盘弹出来,而不用用户再点一下输入框了。方法很简单,就一行代码:
[self.location_inputTextField becomeFirstResponder];
4.两个输入框按return时仿回车功能
有多个输入框,在一个输入框中按了return,然后好像在网站输入框中按了回车,直接跳到下一个输入框,这个也非常简单,就是resignFirstResponder和becomeFirstResponder方法结合使用而已,在UITextField的委托方法中实现:
#pragma mark - UITextField Delegate- (BOOL)textFieldShouldReturn:(UITextField *)textField { if ([self.location_inputTextField isFirstResponder]) { [self.location_inputTextField resignFirstResponder]; [self.length_inputTextField becomeFirstResponder]; } else if ([self.length_inputTextField isFirstResponder]) { [self.length_inputTextField resignFirstResponder]; } return YES;}
Demo已经上传,有兴趣的可以下载看看:点此进入下载页
0 0
- UITextView:定制选中文字的菜单和用代码选择文字
- UITextView:定制选中文字的菜单和用代码选择文字
- UITextView:定制选中文字的菜单和…
- UITextView自定文字选择后菜单
- IOS----UITextView自定文字选择后菜单
- RichEdit选中文字右键菜单的实现
- JS根据当前文字选择返回被选中的文字
- UIMenuItem 文字选择菜单
- 屏蔽UITextView 中文字选择功能的方法
- UITextView的Placeholder占位文字
- 怎样设置JTextArea 文本域中选中的文字的颜色和选择区域背景颜色
- tabBarItem 的选中和不选中文字属性
- UITextView垂直方向上光标和文字显示文字的问题
- 用JavaScript获取选中的文字
- UITextView设置文字垂直居中和LinkAttribute
- VS Code修改选中文字或代码的颜色
- 如何限制UITextView上文字的长度
- 改变UITextView文字之间的间距
- 电信采集项目的一个小总结
- Hadoop 伪分布模式下关机后,fs端口连接不上问题解决方案
- Android opengl 2d绘图/贴图详细教程
- 关于“IOS6_内置字体库下载”的文章网址
- 文件读写
- UITextView:定制选中文字的菜单和用代码选择文字
- 计算机操作系统——存储器管理(6)
- modem建链过程详述
- 即使没有读者,你应该写博客(You should blog even if you have no readers)
- poj 2524 Ubiquitous Religions
- Fedora 20下Eclipse Ingido中配置hadoop插件,并运行Wordcount例程
- SQL join
- .net序列化及反序列化
- Eclipse快捷键大全