iOS-你真的会用UIMenuController吗?(详细)
UIMenuController的介绍
什么是UIMenuController?
UIMenuController是UIKit里面的控件
UIMenuController的作用在开发中弹出的菜单栏
后面介绍了菜单栏显示中文的设置
菜单栏
有哪些控件是自带UIMenuController菜单栏效果的呢?
UITextField
UITextView
UIWebView
有些读者问我这个动图是怎么添加的: 我用的是licecap 这个软件
下面送个几个好用的软件
主要介绍两种:
一种是控制器为第一响应者
另一种是当前UI控件为第一响应者 (把方法封装在控件里面)
具体看代码,注释里我会详细讲解,如果实在不懂不妨动手敲一遍
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//首先要允许label可以跟用户交互
self.label.userInteractionEnabled = YES;
//给label添加一个敲击手势
[self.label addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick)]];
}
/** 点击label触发的方法 */
- (void)labelClick
{
//控制器不需要调用这个方法, 但是其他乱七八糟的UI控件就需要调用这个方法 \
因为控制器默认是第一响应者
//[self becomeFirstResponder];
//显示menu 从来没有让menu跟控制器有关系 , 因为是第一响应者, 所以会调用第一响应者的方法
//不一定调用控制器的方法, 因为现在控制器是第一响应者
// 获得菜单
UIMenuController *menu = [UIMenuController sharedMenuController];
// 菜单最终显示的位置
CGRect rect = CGRectMake(100, 100, 100, 100);
[menu setTargetRect:rect inView:self.label];
//为什么要设置2个参数 为了通用 \
一个是矩形框, 一个是在哪个View上面
//传了矩形框, 要告诉坐标原点在哪, 坐标原点就在view上\
以tagreView的左上角为坐标原点
// 苹果设计2个参数 是因为矩形框一旦修改 出现的位置在哪里都是可以的
/*
targetRect:menuController指向的矩形框
targetView:targetRect以targetView的左上角为坐标原点
*/
// 显示菜单
[menu setMenuVisible:YES animated:YES];
/*
得通过第一响应者,来告诉MenuController它内部应该显示什么内容
*/
}
#pragma mark - 第一响应者 + UIMenuController
/**
* 说明控制器可以成为第一响应者
* 因为控制器是因为比较特殊的对象,它找控制器的方法,不找label的方法
*/
- (BOOL)canBecomeFirstResponder
{
return YES;
}
/**
* 通过这个方法告诉UIMenuController它内部应该显示什么内容
* 返回YES,就代表支持action这个操作
*/
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
//打印, 将一个方法转换成字符串 你就会看到许多方法
NSLog(@"%@",NSStringFromSelector(action));
if (action == @selector(cut:)
|| action == @selector(copy:)
|| action == @selector(paste:)) {
return YES;
}
return NO;
}
//监听事情需要对应的方法 冒号之后传入的是UIMenuController
- (void)cut:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
- (void)copy:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
- (void)paste:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
上面只是简单的介绍了UIMenuController的基本知识,下面正在带你运用到开发中的知识,封装一个自定义控件里面实现, 附上大概效果:
上代码,代码有具体的注释,还有具体的用法,所以认真阅读代码即可,就不附上demo了
#import "JHLabel.h"
@implementation JHLabel
/** 不管控件是通过xib stroyboard 还是纯代码 提供两种初始化的操作都调用同一个方法 */
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setupTap];
}
return self;
}
/** 不管控件是通过xib stroyboard 还是纯代码 提供两种初始化的操作都调用同一个方法 */
- (void)awakeFromNib
{
[self setupTap];
}
/** 设置敲击手势 */
- (void)setupTap
{
self.text = @"author:会跳舞的狮子";
//已经在stroyboard设置了与用户交互,也可以用纯代码设置
// self.userInteractionEnabled = YES;
//当前控件是label 所以是给label添加敲击手势
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(labelClick)]];
}
/** 点击label触发的方法 */
- (void)labelClick
{
// 让label成为第一响应者 \
一定要写这句话 因为这句话才是主动让label成为第一响应者
[self becomeFirstResponder];
// 获得菜单
UIMenuController *menu = [UIMenuController sharedMenuController];
// 设置菜单内容 \
因为menuItems是数组 官方没有给出需要传入什么对象,但是以经验可以判断出需要传入的是UIMenuItem对象 \
而且显示是按顺序的
menu.menuItems = @[
[[UIMenuItem alloc] initWithTitle:@"顶" action:@selector(ding:)],
[[UIMenuItem alloc] initWithTitle:@"回复" action:@selector(reply:)],
[[UIMenuItem alloc] initWithTitle:@"举报" action:@selector(warn:)]
];
// 菜单最终显示的位置 \
有两种方式: 一种是以自身的bounds 还有一种是以父控件的frame
[menu setTargetRect:self.bounds inView:self];
// [menu setTargetRect:self.frame inView:self.superview];
// 显示菜单
[menu setMenuVisible:YES animated:YES];
}
#pragma mark - UIMenuController相关
/**
* 让Label具备成为第一响应者的资格
*/
- (BOOL)canBecomeFirstResponder
{
return YES;
}
/**
* 通过第一响应者的这个方法告诉UIMenuController可以显示什么内容
*/
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if ( (action == @selector(copy:) && self.text) // 需要有文字才能支持复制
|| (action == @selector(cut:) && self.text) // 需要有文字才能支持剪切
|| action == @selector(paste:)
|| action == @selector(ding:)
|| action == @selector(reply:)
|| action == @selector(warn:)) return YES;
return NO;
}
#pragma mark - 监听MenuItem的点击事件
/** 剪切 */
- (void)cut:(UIMenuController *)menu
{
//UIPasteboard 是可以在应用程序与应用程序之间共享的 \
(应用程序:你的app就是一个应用程序 比如你的QQ消息可以剪切到百度查找一样)
// 将label的文字存储到粘贴板
[UIPasteboard generalPasteboard].string = self.text;
// 清空文字
self.text = nil;
}
/** 赋值 */
- (void)copy:(UIMenuController *)menu
{
// 将label的文字存储到粘贴板
[UIPasteboard generalPasteboard].string = self.text;
}
/** 粘贴 */
- (void)paste:(UIMenuController *)menu
{
// 将粘贴板的文字赋值给label
self.text = [UIPasteboard generalPasteboard].string;
}
//如果方法不实现,是不会显示出来的
- (void)ding:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
- (void)reply:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
- (void)warn:(UIMenuController *)menu
{
NSLog(@"%s %@", __func__, menu);
}
@end
上面的代码,menu只显示在label的上面 而一般菜单栏我们都是显示在cell的中间, 下面的这幅图详细讲解了显示在cell的中间
/** 点击cell的时候调用 */
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 取出cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIMenuController *menu = [UIMenuController sharedMenuController];
// 设置菜单内容
menu.menuItems = @[
[[UIMenuItem alloc] initWithTitle:@"顶" action:@selector(ding:)],
[[UIMenuItem alloc] initWithTitle:@"回复" action:@selector(reply:)],
[[UIMenuItem alloc] initWithTitle:@"举报" action:@selector(warn:)]
];
// 显示位置
CGRect rect = CGRectMake(0, cell.height * 0.5, cell.width, 1);
[menu setTargetRect:rect inView:cell];
// 显示出来
[menu setMenuVisible:YES animated:YES];
}
#pragma mark - 获得当前选中的评论
- (JHComment *)selectedComment
{
// 获得被选中的cell的行号
NSIndexPath *indexPath = self.tableView.indexPathForSelectedRow;
NSInteger row = indexPath.row;
// 获得评论数据
NSArray *comments = self.shortComments;
if (indexPath.section == 0 && self.longComments.count) {
comments = self.longComments;
}
return comments[row];
}
#pragma mark - UIMenuController处理
- (BOOL)canBecomeFirstResponder
{
return YES;
}
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
if (!self.isFirstResponder) { // 文本框弹出键盘, 文本框才是第一响应者
if (action == @selector(ding:)
|| action == @selector(reply:)
|| action == @selector(warn:)) return NO;
//如果是文本框,那么这些显示都不返回
}
return [super canPerformAction:action withSender:sender];
}
- (void)ding:(UIMenuController *)menu
{
NSLog(@"ding - %@ %@",
self.selectedComment.user.username,
self.selectedComment.content);
}
- (void)reply:(UIMenuController *)menu
{
NSLog(@"reply - %@ %@",
self.selectedComment.user.username,
self.selectedComment.content);
}
- (void)warn:(UIMenuController *)menu
{
NSLog(@"warn - %@ %@",
self.selectedComment.user.username,
self.selectedComment.content);
}
#注: 这里的self.selectedComent
# (点语法 要么调用set方法要么调用get方法, 这里直接用点语法是没有提示的,我已经进行了声明)
#/** 写方法声明的目的是为了使用点语法提示 */
#- (JHComment *)selectedComment;
iOS-你真的会用UIMenuController吗?(详细)的更多相关文章
- ios开发——实用技术篇&Pist转模型详细介绍
Pist转模型详细介绍 关于Plist转模型在iOS开发中是非常常见的,每开一一个项目或者实现一个功能都要用到它,所以今天就给大家讲讲Plist怎么转成模型数据, 前提:必须有一个Plist文件或者通 ...
- ios申请真机调试( xcode 5)详细解析
已经有开发证书的直接跳过第一步 第一步:申请"开发证书" 进入苹果开发者99美元账号: 选择:Certificates, Identifiers & Profiles 关于 ...
- iOS开发——实用OC篇&多种定时器详细介绍
多种定时器详细介绍 在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法.在这个时候,我们就需要用到定时器. 然而,在iOS中有很多方法完成以上的任务,到底有 ...
- ios 类似的效果淘宝商品详细页面
今天试着写ios 分类似影响淘宝的商品详细页面 我使用第三方库EGORefreshTableHeaderView有一个下拉效果刷新PWLoadMoreTableFooterView上拉电阻负载许多其他 ...
- iOS树状视图(折叠单元格)详细使用
RATreeView是一个第三方的iOS树视图(通俗的讲就是折叠单元格),它是对UITableView的封装,定义自己的委托和数据源的法,RATreeView是高度可定制的,并且有很多功能.很多朋友都 ...
- iOS开发融云即时通讯集成详细步骤
1.融云即时通讯iOS SDK下载地址 http://rongcloud.cn/downloads 选择iOS SDK下载 2.进行应用开发之前,需要先在融云开发者平台创建应用,如果您已经注 ...
- iOS的Ping++支付接入步骤(详细)
Ping++ SDK 代码下载地址: https://github.com/CoderLeezhen/PingppDemo 参考链接: https://www.pingxx.com/guidance/ ...
- 开发IOS应用真的一定要买苹果电脑设备吗?
不要忘记目的 如果你想开发ios或者苹果的app,网上很多网友都会建议你买一个苹果硬件--苹果电脑,一部分建议你安装黑苹果.这两种方案中前一种费用很高,后一种费时费力(甚至到最后都要转向购买apple ...
- 利用Qt开发跨平台APP(二)(iOS,使用Qt5.9,很详细,有截图)
本文将手把手教你如何使用Qt编译出iOS应用程序. Qt是一个优秀的跨平台开发工具.我们利用Qt可以很方便地将一次编写的应用,多次编译到不同平台上,如Windows.Linux.MAC.Android ...
随机推荐
- Linux脚本
放置在/usr/local/sbin下面: 收到一个问题:"-bash XXX 没有权限":需要在此目录下执行chmod +x filename 收到一个问题:"-bas ...
- 原生js实现tab选项卡里内嵌图片滚动特效代码
<!DOCTYPE HTML><html lang="en-US"><head><meta charset="UTF-8&quo ...
- 邮件协议POP3/IMAP/SMTP服务的区别
2016年09月09日 09時51分 wanglinqiang整理 通过网上查找的资料和自己的总结完成了下面的文章,看完之后相信大家对这三种协议会有更深入的理解.如有错误的地方望指正. POP3 PO ...
- UFLDL教程之(三)PCA and Whitening exercise
Exercise:PCA and Whitening 第0步:数据准备 UFLDL下载的文件中,包含数据集IMAGES_RAW,它是一个512*512*10的矩阵,也就是10幅512*512的图像 ( ...
- Hadoop 2.6.0编译on mac
花了一个晚上的时间弄了下hadoop的编译环境,碰到些错误,这里保存下. 需要编译Hadoop,不但需要安装Maven,还需要安装protobuf 安装Maven 下载:apache-maven-3. ...
- bzoj 1223: [HNOI2002]Kathy函数 数位DP 高精度
1223: [HNOI2002]Kathy函数 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 207 Solved: 90[Submit][Stat ...
- bzoj 1005: [HNOI2008]明明的烦恼 prufer编号&&生成树计数
1005: [HNOI2008]明明的烦恼 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2248 Solved: 898[Submit][Statu ...
- BZOJ 3992 序列统计
Description 小C有一个集合\(S\),里面的元素都是小于\(M\)的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为\(N\)的数列,数列中的每个数都属于集合\(S\). 小C用 ...
- [BZOJ 3680] 吊打XXX 【模拟退火】
题目链接:BZOJ - 3680 题目分析 这道题是SLYZ的神犇把JSOI的平衡点那道题改了一下题面变成了吊打GTY神犇..Orz 第一次写模拟退火,只能照着别人的代码写,我看的是PoPoQQQ神犇 ...
- 大数据计算新贵Spark在腾讯雅虎优酷成功应用解析
http://www.csdn.net/article/2014-06-05/2820089 摘要:MapReduce在实时查询和迭代计算上仍有较大的不足,目前,Spark由于其可伸缩.基于内存计算等 ...