热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

华山论剑之浅谈iOS剪切黏贴(UIPasteboard和UIMenuController)

每个程序猿都是一名强大的战士,名曰CV战士.
每个程序猿都是一名强大的战士,名曰CV战士.
华山论剑之浅谈iOS剪切黏贴(UIPasteboard和UIMenuController)
菜单功能

序言


如上图,我们在应用程序中时常需要有黏贴复制的功能,像UIWebView,UITextField,UITextView这些类都是自带黏贴复制功能的,但是我们先让某个控件具有黏贴复制功能,我们该怎么办呢?那就需要用到两个类,一个是UIPasteboard,另外一个就是UIMenuController,一个是剪切板,另外一个是菜单弹窗.

从UIMenuController到菜单弹窗的完美变身


UIMenuController的用法和UIAlertView的使用方法是类似的,如下图,我在storyboard的ViewController的控制器中,添加两个个UILabel对象,然后在ViewController其中添加手势.

华山论剑之浅谈iOS剪切黏贴(UIPasteboard和UIMenuController)

把UILabel拖成属性,然后代码如下

#import "ViewController.h" @interface ViewController () @property (strong, nonatomic) IBOutlet UILabel *testlLabel;//测试Label @property (strong, nonatomic) IBOutlet UILabel *pasteLabel;//黏贴Label @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; [self loadingTapGR]; } //添加点击手势 -(void)loadingTapGR{ UILongPressGestureRecognizer *lOngPress= [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(showMenuVC:)]; longPress.minimumPressDuration = 1; self.testlLabel.userInteractiOnEnabled= YES; [self.testlLabel addGestureRecognizer:longPress]; UILongPressGestureRecognizer *longPress2 = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(showMenuVC:)]; longPress2.minimumPressDuration = 1; self.pasteLabel.userInteractiOnEnabled= YES; [self.pasteLabel addGestureRecognizer:longPress2]; } //显示菜单 -(void)showMenuVC:(UILongPressGestureRecognizer *)longPress{ UIMenuController *menuCOntroller= [UIMenuController sharedMenuController]; UIMenuItem * menuItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyTitle)]; UIMenuItem * pasteItem = [[UIMenuItem alloc] initWithTitle:@"黏贴" action:@selector(paste:)]; NSLog(@"%@",menuController.menuItems); [menuController setMenuItems:@[menuItem,pasteItem]]; CGPoint location = [longPress locationInView:[longPress view]]; CGRect menuLocation = CGRectMake(location.x, location.y, 0, 0); [menuController setTargetRect:menuLocation inView:[longPress view]]; [menuController setMenuVisible:YES animated:YES]; } //复制文本 -(void)copyTitle{ } //黏贴 -(void)paste:(id)sender { } @end

代码是如上实现了,但是我们点击Label仍是没有菜单出现,这是为什么呢?因为我们还重新定义下面的这个方法.

//允许成为第一响应者 -(BOOL)canBecomeFirstResponder{ return YES; }

看一下效果图,好了菜单完成了,我们接下来要做复制黏贴的功能了.

华山论剑之浅谈iOS剪切黏贴(UIPasteboard和UIMenuController)
效果图片

从UIPasteboard到复制黏贴功能的终极进化


在使用UIPasteboard之前,我们需要先了解一下剪贴板UIPasteboard的一些基本的知识.

剪贴板类型:

  • 系统级别:使用UIPasteboardNameGeneral和UIPasteboardNameFind,系统级应用程序关闭,或者卸载的数据不会丢失。
  • 应用程序级:通过设置,可以让数据在应用程序关闭之后仍然保存在剪贴板中,但是应用程序卸载之后数据就会失去。我们可用通过pasteboardWithName:create:来创建。

剪贴板可直接存放的类型

  • 1、UIPasteboardTypeListString — 字符串数组 包含kUTTypeUTF8PlainText
  • 2、UIPasteboardTypeListURL — URL数组,包含kUTTypeURL
  • 3、UIPasteboardTypeListImage — 图形数组, 包含kUTTypePNG 和kUTTypeJPEG
  • 4、UIPasteboardTypeListColor — 颜色数组

下面我们对上面代码中的 -(void)copyTitle 方法进行进一步的完善.使其能有简单的复制功能.

//复制文本 -(void)copyTitle{ NSLog(@"复制功能的实现~"); UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];//普通的黏贴板 pasteboard.string = self.testlLabel.text; }

复制功能实现之后,我们需要实现黏贴功能.

-(void)paste:(id)sender { UIPasteboard *pboard = [UIPasteboard generalPasteboard]; //判断是否数据 if (nil != pboard.string) { self.pasteLabel.text = pboard.string; } }

到此,复制黏贴的功能就实现了,当然了,这是对一些简单对象(比如:string,URL,image,color)进行的复制黏贴,如果是复杂对象,改如何进行黏贴复制呢?这时候就需要使用到归档和反归档把数据变成NSData类型的对象,然后使用 setData:forPasteboardType:dataForPasteboardType: 两个方法进行数据的存储和获取,代码如下

//存储数据 UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:YES]; NSDictionary *dic = [NSDictionary dictionaryWithObject:self.testlLabel.text forKey:@"saoDong"]; NSData *dictData = [NSKeyedArchiver archivedDataWithRootObject:dic]; [pb setData:dictData forPasteboardType:@"myType"]; //获取就类似于这样: UIPasteboard *pb = [UIPasteboard pasteboardWithName:@"testBoard" create:YES]; NSDictionary *dic = [NSKeyedUnarchiver unarchiveObjectWithData:[pb dataForPasteboardType:@"myType"]]; self.pasteLabel.text = [dict objectForKey:@"saoDong"];

总结: UIPasteboard和UIMenuController两个类整体使用起来比较简单,难度一般,如果有什么疑问,请在下面评论,我会及时回复.谢谢您的查看,最后附上测试的Demo.

——-> UIPasteboard和UIMenuController使用Demo传送门


推荐阅读
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 解决Bootstrap DataTable Ajax请求重复问题
    在最近的一个项目中,我们使用了JQuery DataTable进行数据展示,虽然使用起来非常方便,但在测试过程中发现了一个问题:当查询条件改变时,有时查询结果的数据不正确。通过FireBug调试发现,点击搜索按钮时,会发送两次Ajax请求,一次是原条件的请求,一次是新条件的请求。 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文节选自《NLTK基础教程——用NLTK和Python库构建机器学习应用》一书的第1章第1.2节,作者Nitin Hardeniya。本文将带领读者快速了解Python的基础知识,为后续的机器学习应用打下坚实的基础。 ... [详细]
  • Android 自定义 RecycleView 左滑上下分层示例代码
    为了满足项目需求,需要在多个场景中实现左滑删除功能,并且后续可能在列表项中增加其他功能。虽然网络上有很多左滑删除的示例,但大多数封装不够完善。因此,我们尝试自己封装一个更加灵活和通用的解决方案。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • ECharts 官方提供了丰富的图表示例,但实际项目中往往需要从后端动态获取数据。本文将详细介绍如何从后端获取数据并将其转换为 ECharts 所需的 JSON 格式,以实现动态饼图的展示。 ... [详细]
  • 本文将带你快速了解 SpringMVC 框架的基本使用方法,通过实现一个简单的 Controller 并在浏览器中访问,展示 SpringMVC 的强大与简便。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • Ihavetwomethodsofgeneratingmdistinctrandomnumbersintherange[0..n-1]我有两种方法在范围[0.n-1]中生 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • 在 iOS 开发中,经常会遇到 `@(YES)`、`@[firstViewController]` 以及 `@{@a:@b}` 这样的语法糖。这些简化的写法分别用于初始化布尔值、数组和字典对象,能够显著提高代码的可读性和编写效率。例如,`@(YES)` 可以快速创建一个布尔值对象,`@[firstViewController]` 则用于创建包含单个元素的数组,而 `@{@a:@b}` 则用于创建键值对字典。理解这些语法糖的使用方法,有助于开发者更加高效地进行编码。 ... [详细]
author-avatar
愚木小三_563
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有