• iOS开发之UIMenuController


    1、简介

      用于剪切、复制、粘贴、选择、选择ALL和DELETE命令的菜单界面。

      UITextField、UIWebView、UITextView自带有这种UIMenuController效果; 

    2、相关API

    #import <Foundation/Foundation.h>
    #import <CoreGraphics/CoreGraphics.h>
    #import <UIKit/UIKitDefines.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    typedef NS_ENUM(NSInteger, UIMenuControllerArrowDirection) {
        UIMenuControllerArrowDefault, // up or down based on screen location
        UIMenuControllerArrowUp NS_ENUM_AVAILABLE_IOS(3_2),
        UIMenuControllerArrowDown NS_ENUM_AVAILABLE_IOS(3_2),
        UIMenuControllerArrowLeft NS_ENUM_AVAILABLE_IOS(3_2),
        UIMenuControllerArrowRight NS_ENUM_AVAILABLE_IOS(3_2),
    } __TVOS_PROHIBITED;
    
    @class UIView, UIMenuItem;
    
    NS_CLASS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED @interface UIMenuController : NSObject
    
    //初始化懒加载
    #if UIKIT_DEFINE_AS_PROPERTIES
    @property(class, nonatomic, readonly) UIMenuController *sharedMenuController;
    #else
    + (UIMenuController *)sharedMenuController;
    #endif
    
    //菜单的显示和隐藏
    @property(nonatomic,getter=isMenuVisible) BOOL menuVisible;        // default is NO
    - (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated;  //可动画
    
    //设置显示区域
    - (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView;
    //编辑菜单箭头指向的方向。
    @property(nonatomic) UIMenuControllerArrowDirection arrowDirection NS_AVAILABLE_IOS(3_2); // default is UIMenuControllerArrowDefault
    
    @property(nullable, nonatomic,copy) NSArray<UIMenuItem *> *menuItems NS_AVAILABLE_IOS(3_2); // default is nil. 编辑菜单中的自定义菜单项。
    //刷新Menu
    - (void)update;
    //返回编辑菜单的框架
    @property(nonatomic,readonly) CGRect menuFrame;
    
    @end
    
    UIKIT_EXTERN NSNotificationName const UIMenuControllerWillShowMenuNotification __TVOS_PROHIBITED; //将要显示
    UIKIT_EXTERN NSNotificationName const UIMenuControllerDidShowMenuNotification __TVOS_PROHIBITED;  //已经显示
    UIKIT_EXTERN NSNotificationName const UIMenuControllerWillHideMenuNotification __TVOS_PROHIBITED; //将要隐藏
    UIKIT_EXTERN NSNotificationName const UIMenuControllerDidHideMenuNotification __TVOS_PROHIBITED;  //已经隐藏
    UIKIT_EXTERN NSNotificationName const UIMenuControllerMenuFrameDidChangeNotification __TVOS_PROHIBITED; //视图更新
    
    //自定义菜单项
    NS_CLASS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED @interface UIMenuItem : NSObject
    //标题  和 响应方法
    - (instancetype)initWithTitle:(NSString *)title action:(SEL)action NS_DESIGNATED_INITIALIZER;
    @property(nonatomic,copy) NSString *title;
    @property(nonatomic)      SEL       action;
    
    @end

    3、自定义MenuLabel

    #import "MenuLabel.h"
    
    @implementation MenuLabel
    
    - (instancetype)initWithFrame:(CGRect)frame{
        if (self = [super initWithFrame:frame]) {
            [self setUI];
        }
        return self;
    }
    - (void)awakeFromNib{
        [super awakeFromNib];
        [self setUI];
    }
    - (void)setUI{
        self.userInteractionEnabled = YES;
    //    self.text = @"";
        [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGes:)]];
    }
    - (void)tapGes:(UITapGestureRecognizer *)ges{
        [self becomeFirstResponder];
        UIMenuController *menu = [UIMenuController sharedMenuController];
        menu.menuItems = @[[[UIMenuItem alloc] initWithTitle:@"点赞" action:@selector(tap:)],
                           [[UIMenuItem alloc] initWithTitle:@"留言" action:@selector(reply:)],
                           [[UIMenuItem alloc] initWithTitle:@"踩一踩" action:@selector(down:)],
                           [[UIMenuItem alloc] initWithTitle:@"踩一踩" action:@selector(down:)]];
        [menu setTargetRect:self.bounds inView:self];
        [menu setMenuVisible:YES animated:YES];
    }
    - (BOOL)canBecomeFirstResponder{
        return YES;
    }
    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender{
        if ( (action == @selector(copy:) && self.text) // 需要有文字才能支持复制
            || (action == @selector(cut:) && self.text) // 需要有文字才能支持剪切
            || action == @selector(paste:)
            || action == @selector(tap:)
            || action == @selector(reply:)
            || action == @selector(down:)) return YES;
        return NO;
    }
    - (void)cut:(UIMenuController *)menu
    {
        //UIPasteboard 粘贴板
        // 将label的文字存储到粘贴板
        [UIPasteboard generalPasteboard].string = self.text;
        // 清空文字
        self.text = nil;
        NSLog(@"cut");
    }
    
    - (void)copy:(UIMenuController *)menu
    {
        // 将label的文字存储到粘贴板
        [UIPasteboard generalPasteboard].string = self.text;
        NSLog(@"copy");
    }
    
    - (void)paste:(UIMenuController *)menu
    {
        // 将粘贴板的文字赋值给label
        self.text = [UIPasteboard generalPasteboard].string;
        NSLog(@"paste");
    }
    
    - (void)tap:(UIMenuController *)menu{
        NSLog(@"tap");
    }
    - (void)reply:(UIMenuController *)menu{
        NSLog(@"reply");
    }
    - (void)down:(UIMenuController *)menu{
        NSLog(@"down");
    }
    
    @end
    MenuLabel.m文件

      ps:自定义UIMenuItem过多是自动分页;

        部分选择文本可以继承TextView自定义类;

        注意事项:自身可交互、成为第一响应者、显示前设置好位置等属性;

        self.userInteractionEnabled = YES;
        [self becomeFirstResponder];

        实现UIResponder类中的一个方法:

    - (BOOL)canPerformAction:(SEL)action withSender:(id)sender;
  • 相关阅读:
    【LeetCode】1248. 统计「优美子数组」
    【LeetCode】200. 岛屿数量
    【LeetCode】53. 最大子序和
    【剑指Offer】面试题42. 连续子数组的最大和
    【剑指Offer】面试题57. 和为s的两个数字
    【LeetCode】55. 跳跃游戏
    【LeetCode】56. 合并区间
    简历HTML网页版
    关于新建Eclipse新建一个WEB项目后创建一个jsp文件头部报错问题?
    jquery选择器 看这个链接吧!2017.6.2
  • 原文地址:https://www.cnblogs.com/xianfeng-zhang/p/9511194.html
Copyright © 2020-2023  润新知