iOS IM开发建议(四)UIMenuController 怎么使用

  这应该是这个系列最后一篇了。我写了很多都不是很好,不过如果不写,那就永远写不好。欢迎大家交流纠错。

  UIMenuController,它不像Alert那么不友好,也不像ActionSheet,一定要点击一下;你可以无视它的出现,也可以通过它调用一些设定好的方法。它就长这样:

  

  这个控件是不是很熟悉,微信里面你长按就回出现的一个view。做IM的话,标杆就是wechat了,所以你们的产品怎么会放过它(你)呢。

  先设计一个我们常用的场景:你在聊天界面,长按textView,然后弹出这个菜单,接着你点击了某一个Item。

  聊天页面:tableView + inputBar(就是有输入框的一个view啦)。

  这里面你会用到,tableView的的代理,要实现几个delegate。

 1 #pragma mark -  UITableViewDataSource  &  UITableViewDelegate
 2 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 3     // 有多少条数据
 4     return [dataArray count];
 5 }
 6
 7 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 8     static NSString * CellIdentifier = @"MessageCell";
 9     MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
10     if (cell == nil) {
11         cell = [MessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
12         cell.selectionStyle = UITableViewCellSelectionStyleDefault;
13     }
14     MessageModel * model = [dataArray objectAtIndex:indexPath.row];
15     [cell setMyContent:model];
16     return cell;
17 }
18
19 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
20     // 这里就用之前写到的的高度计算
21     return #cellHeightFromModelData#;
22 }

  那我们再来看一下cell,cell要做几件事:1、自己的frame要算出来;2、要放好textView或imageView,我这里只说一下textView咯;

  .h 我们要声明一个public的方法,用model来设置cell,减少VC的代码量。 还有一个block,给VC回传textView交互事件。

 1 typedef NS_ENUM(NSInteger,CellOperations) {
 2     TextCopy,
 3     TextDelete,
 4     TextTransfor,
 5     TextCollection,
 6
 7     ImageCopy,
 8     ImageDelete,
 9     ImageTransfor,
10     ImageCollection,
11 };
12
13 @property(nonatomic,copy)void (^CellOperation)(MessageModel* message, CellOperations cop);
14
15 - (void)setMyContent:(MessageModel *)message;

  .m 我们要算自己的高度,textView的高度。还有传递textView的一些事件到VC上。

 1 - (void)setMyContent:(MessageModel *)message {
 2     // 传递参数
 3     // 算高度
 4     // 设置textView的大小 以及背景框的大小
 5 }
 6
 7 - (void)textViewCallBack:(CellOperations cop){
 8     // 把textView的操作 截获
 9     // 调用自己的 callBackVC 将操作传递出去
10 }
11
12 - (void)callBackVC:(CellOperations cop){
13     // 往VC传递操作事件
14 }

  实现上面的3个方法,我们就可以绘制出Cell,并且可以传递textView的操作了。

  接下来,textView。

  .h  这里我们要声明一个Block 给Cell传值

@property(nonatomic,copy)void (^TVOperation)(CellOperations cop);

  .m 这是就要实现UIMenuController

  1 //
  2 //  DisplayTextView.m
  3 //
  4 //
  5 //  Created by akforsure on 15/12/1.
  6 //  Copyright © 2015年 akforsure. All rights reserved.
  7 //
  8
  9 #import "DisplayTextView.h"
 10
 11 @implementation DisplayTextView {
 12     UIMenuController * menu;
 13 }
 14 - (instancetype)initWithFrame:(CGRect)frame {
 15     self = [super initWithFrame:frame];
 16     if(self) {
 17         // 展示用的textView  要不能编辑 最好也不能选取,不然很二的
 18         self.editable = NO;
 19         self.selectable = NO;
 20     }
 21     return self;
 22 }
 23 - (void)showMenu{
 24     // 如果已经出现了 我们就return
 25     if([menu isMenuVisible]) return;
 26     // textView 一定要是第一响应  也要设置为可以是第一响应
 27     [self becomeFirstResponder];
 28     // 设置UIMenuItems  并且添加到页面上
 29     UIMenuItem *menuItem0 = [[UIMenuItem alloc]initWithTitle:@"复制" action:@selector(kCopy:)];
 30     UIMenuItem *menuItem1 = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(kDelete:)];
 31     UIMenuItem *menuItem2 = [[UIMenuItem alloc]initWithTitle:@"转发" action:@selector(transfor:)];
 32     UIMenuItem *menuItem3 = [[UIMenuItem alloc]initWithTitle:@"收藏" action:@selector(collection:)];
 33     menu = [UIMenuController sharedMenuController];
 34     [menu setMenuItems:[NSArray arrayWithObjects:menuItem0,menuItem1,menuItem2,menuItem3,nil]];
 35     [menu setTargetRect:self.bounds inView:self];
 36     [menu setMenuVisible: YES animated: YES];
 37 }
 38 // 这个方法一定要实现的 不然你无法响应你的操作
 39 - (BOOL)canBecomeFirstResponder {
 40     return YES;
 41 }
 42 // 这个方法是对点击的响应  返回YES 就是可以被识别
 43 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
 44
 45     if(action == @selector(kCopy:)) {
 46         return YES;
 47     }else if (action == @selector(kDelete:)) {
 48         return YES;
 49     }else if (action == @selector(transfor:)) {
 50         return YES;
 51     }
 52     else if (action == @selector(collection:)) {
 53         return YES;
 54     }
 55     [super canPerformAction:action withSender:sender];
 56     return NO;
 57 }
 58 #pragram mark - private methods 每一个事件的实现
 59 - (void)kCopy:(id)sender {
 60     if(self.TVOperation){
 61         self.TVOperation(TextCopy);
 62     }
 63     NSLog(@"textkCopy");
 64 }
 65 - (void)kDelete:(id)sender {
 66     if(self.TVOperation){
 67         self.TVOperation(TextDelete);
 68     }
 69     NSLog(@"textkDelete");
 70 }
 71 - (void)transfor:(id)sender {
 72     if(self.TVOperation){
 73         self.TVOperation(TextTransfor);
 74     }
 75     NSLog(@"texttransfor");
 76 }
 77 - (void)collection:(id)sender {
 78      if(self.TVOperation){
 79         self.TVOperation(TextCollection);
 80     }
 81     NSLog(@"textcollection");
 82 }
 83
 84
 85 // Only override drawRect: if you perform custom drawing.
 86 // An empty implementation adversely affects performance during animation.
 87 // 在draw的时候加入long press 手势
 88 - (void)drawRect:(CGRect)rect {
 89     // Drawing code
 90     // 去除 长按手势
 91     for ( UIGestureRecognizer *recognizer in self.gestureRecognizers) {
 92         if ( [recognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
 93             recognizer.enabled = NO;
 94             //这里可能有问题,我不是很确定  不过用了一段时间也没啥
 95         }
 96     }
 97     // 重新加入长按手势
 98     UILongPressGestureRecognizer *kGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showMenu)];
 99     [self addGestureRecognizer:kGesture];
100 }
101
102 @end

  到这里为止,我们就完成了你看到的那个效果了,我没有给全所有代码,因为我希望大家都自己动手写一下。

时间: 2024-08-25 15:05:25

iOS IM开发建议(四)UIMenuController 怎么使用的相关文章

iOS IM开发建议(三)添加一个自定义键盘

各类的主流IM,都有自己定义的键盘:有表情键盘,选图片的键盘.其实都是一个inputView. 首先,我们要确定,我们的键盘是输入框调用的.也就是,我们可以设置的是某一个textView的inputView. // 让键盘进入编辑状态,替换输入源为自定义的fv // fv 是一个自定义的UIView - (void)callFaceKeyBoard:(UIButton *)button { [ktextView becomeFirstResponder]; ktextView.inputView

从零开始学ios开发(四):IOS控件(1),Image View、Text Field、Keyboard

长话短说,谢谢大家的关注,这篇写了好长时间,下面继续学习ios.我将用2到3篇的篇幅来学习iphone上的一些常用控件,包括Image View.Text Field.Keyboard.Slider等等,这篇的内容包括ImageView和Keyboard的使用.完成后的效果图如下: 1)创建一个新的project,选择“Single View Application”,命名为“Control Fun”,然后保存.一些和前几章相似的步骤在从这篇起就开始一笔待过了,也不再做截图了,例如这里的创建一个

IOS开发之——四种方法解析Jason数据(转)

本文将介绍TouchJson. SBJson .JSONKit 和 iOS5所支持的原生的json方法,解析国家气象局API,TouchJson和SBJson需要下载他们的库 TouchJson包下载: http://download.csdn.net/detail/enuola/4523169 SBJson 包下载: http://download.csdn.net/detail/enuola/4523177 JSONKit包下载:http://download.csdn.net/detail

(转发)IOS高级开发~Runtime(四)

用C代替OC: #import <objc/runtime.h> #import <objc/message.h> #import <stdio.h> extern int UIApplicationMain (int argc,char *argv[],void *principalClassName,void *delegateClassName); struct Rect { float x; float y; float width; float height;

移动开发在路上-- IOS移动开发系列 网络交互四(3)

接着上次的讲,这次我们讲 网络请求的封装  打开创建的项目,让我们一起来继续完成他, 上次我们说到GET请求地址的拼接: 我们接着昨天的继续完善: 下边我们要定义的是 block //定义block __block ASIFormDataRequest *request=[ASIFormDataRequest requestWithURL:url]; 请求超出时间 //设置请求超出时间 [request setTimeOutSeconds:60]; POST请求参数的处理 //处理POST请求方

移动开发在路上-- IOS移动开发系列 网络交互四(2)

接着上次的讲,这次我们讲 网络请求的封装  打开创建的项目,让我们一起来继续完成他, 首先我们来创建一个NSobject 的文件 圈住出来的轻一点要注意.千万不要搞错了 创建好之后,开始编写代码, 我们第一不要要先把工程文件引用进来 看图 让后我们定义一下接口  和 一个block //block定义 typedef void(^RequestFinishBlock)(id result); 1 @interface ZWJDataService : NSObject 2 3 //定义接口 4

给iOS开发者的Android开发建议

本人从事iOS应用开发已经5年有余,直到现在还总是刻意回避Andriod应用的开发.但是不管你信不信,安卓开发还是很有意思的,从iOS转向Android应用开发的跨度并没有你想象的那么大. 现在我把在开发7分钟训练这款Android应用中所学到的一些东西与大家分享,希望能对你们有所帮助.需要指出的是,我稍后所比较的每个项目并不是完全匹配的,并且这篇文章并不是一个完整的Android应用开发概述,但是它包涵了我从开发这个简单应用所学到的点点滴滴. 开发环境 开发环境我选择了Android Stud

iOS 11开发教程(十四)iOS11应用代码添加视图

iOS 11开发教程(十四)iOS11应用代码添加视图 如果开发者想要使用代码为主视图添加视图,该怎么办呢.以下将为开发者解决这一问题.要使用代码为主视图添加视图需要实现3个步骤. (1)实例化视图对象 每一个视图都是一个特定的类.在Swift中,经常会说,类是一个抽象的概念,而非具体的事物,所以要将类进行实例化.实例化一个视图对象的具体语法如下: let/var 对象名=视图类() 以我们接触的第一个视图View为例,它的实例化对象如下: let newView=UIView() 其中,UIV

iOS项目开发实战——学会使用TableView列表控件(四)plist读取与Section显示

文本将会实现把数据存储到plist文件里.然后在程序中进行读取.在TableView控件中依据不同的类别显示Section. 有关TableView 的其它实现,请參考<iOS项目开发实战--学会使用TableView列表控件(一)><iOS项目开发实战--学会使用TableView列表控件(二)><iOS项目开发实战--学会使用TableView列表控件(三)了解Section>. (1)新建一个Property List文件,这个也就是plist文件.我取名为dat