zoukankan      html  css  js  c++  java
  • 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

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

  • 相关阅读:
    问题建模---大纲---待补充
    塞库报表封装问题分析--一篇不太成功的问题分析报告
    哲学的根本问题--以人为本
    什么是本体论
    知行合一是做人的最高境界
    什么是问题?--人类才是最大的问题--所有的问题都是在人类认识世界和改造世界中产生的
    还原论与what、how、why
    selinux 开启和关闭
    Macbook上打开多个终端的方法
    PHPStorm 快捷键大全(Win/Linux/Mac)
  • 原文地址:https://www.cnblogs.com/akforsure/p/5547173.html
Copyright © 2011-2022 走看看