您的位置:首页 > 产品设计 > UI/UE

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

2016-05-31 19:41 591 查看
  这应该是这个系列最后一篇了。我写了很多都不是很好,不过如果不写,那就永远写不好。欢迎大家交流纠错。

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

  


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

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

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

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

#pragma mark -  UITableViewDataSource  &  UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// 有多少条数据
return [dataArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * CellIdentifier = @"MessageCell";
MessageCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [MessageCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleDefault;
}
MessageModel * model = [dataArray objectAtIndex:indexPath.row];
[cell setMyContent:model];
return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// 这里就用之前写到的的高度计算
return #cellHeightFromModelData#;
}


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

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

typedef NS_ENUM(NSInteger,CellOperations) {
TextCopy,
TextDelete,
TextTransfor,
TextCollection,

ImageCopy,
ImageDelete,
ImageTransfor,
ImageCollection,
};

@property(nonatomic,copy)void (^CellOperation)(MessageModel* message, CellOperations cop);

- (void)setMyContent:(MessageModel *)message;


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

- (void)setMyContent:(MessageModel *)message {
// 传递参数
// 算高度
// 设置textView的大小 以及背景框的大小
}

- (void)textViewCallBack:(CellOperations cop){
// 把textView的操作 截获
// 调用自己的 callBackVC 将操作传递出去
}

- (void)callBackVC:(CellOperations cop){
// 往VC传递操作事件
}


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

  接下来,textView。

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

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


  .m 这是就要实现UIMenuController

//
//  DisplayTextView.m
//
//
//  Created by akforsure on 15/12/1.
//  Copyright © 2015年 akforsure. All rights reserved.
//

#import "DisplayTextView.h"

@implementation DisplayTextView {
UIMenuController * menu;
}
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if(self) {
// 展示用的textView  要不能编辑 最好也不能选取,不然很二的
self.editable = NO;
self.selectable = NO;
}
return self;
}
- (void)showMenu{
// 如果已经出现了 我们就return
if([menu isMenuVisible]) return;
// textView 一定要是第一响应  也要设置为可以是第一响应
[self becomeFirstResponder];
// 设置UIMenuItems  并且添加到页面上
UIMenuItem *menuItem0 = [[UIMenuItem alloc]initWithTitle:@"复制" action:@selector(kCopy:)];
UIMenuItem *menuItem1 = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(kDelete:)];
UIMenuItem *menuItem2 = [[UIMenuItem alloc]initWithTitle:@"转发" action:@selector(transfor:)];
UIMenuItem *menuItem3 = [[UIMenuItem alloc]initWithTitle:@"收藏" action:@selector(collection:)];
menu = [UIMenuController sharedMenuController];
[menu setMenuItems:[NSArray arrayWithObjects:menuItem0,menuItem1,menuItem2,menuItem3,nil]];
[menu setTargetRect:self.bounds inView:self];
[menu setMenuVisible: YES animated: YES];
}
// 这个方法一定要实现的 不然你无法响应你的操作
- (BOOL)canBecomeFirstResponder {
return YES;
}
// 这个方法是对点击的响应  返回YES 就是可以被识别
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {

if(action == @selector(kCopy:)) {
return YES;
}else if (action == @selector(kDelete:)) {
return YES;
}else if (action == @selector(transfor:)) {
return YES;
}
else if (action == @selector(collection:)) {
return YES;
}
[super canPerformAction:action withSender:sender];
return NO;
}
#pragram mark - private methods 每一个事件的实现
- (void)kCopy:(id)sender {
if(self.TVOperation){
self.TVOperation(TextCopy);
}
NSLog(@"textkCopy");
}
- (void)kDelete:(id)sender {
if(self.TVOperation){
self.TVOperation(TextDelete);
}
NSLog(@"textkDelete");
}
- (void)transfor:(id)sender {
if(self.TVOperation){
self.TVOperation(TextTransfor);
}
NSLog(@"texttransfor");
}
- (void)collection:(id)sender {
if(self.TVOperation){
self.TVOperation(TextCollection);
}
NSLog(@"textcollection");
}

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
// 在draw的时候加入long press 手势
- (void)drawRect:(CGRect)rect {
// Drawing code
// 去除 长按手势
for ( UIGestureRecognizer *recognizer in self.gestureRecognizers) {
if ( [recognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
recognizer.enabled = NO;
//这里可能有问题,我不是很确定  不过用了一段时间也没啥
}
}
// 重新加入长按手势
UILongPressGestureRecognizer *kGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(showMenu)];
[self addGestureRecognizer:kGesture];
}

@end


  到这里为止,我们就完成了你看到的那个效果了,我没有给全所有代码,因为我希望大家都自己动手写一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: