1. 程式人生 > >iOS UILabel的複製貼上和UIMenuController的基本使用

iOS UILabel的複製貼上和UIMenuController的基本使用

1.複製-貼上的功能

在iOS中下面三個控制元件,自身就有複製-貼上的功能:

  • UITextView
  • UITextField
  • UIWebView

UIKit framework提供了幾個類和協議方便我們在自己的應用程式中實現剪貼簿的功能。

  • UIPasteboard:貼上板是用於在一個應用程式內或不同應用程式間進行資料共享的受保護區域。
  • UIMenuController:顯示一個快捷選單,用來展示覆制、剪貼、貼上等選擇的項。
  • UIResponder中的 canPerformAction:withSender:用於控制哪些命令顯示在快捷選單中。

2.UIMenuController的使用

  • 1.使Menu所處的View成為First Responder (becomeFirstResponder)
    Menu所處的View或者viewController必須實現 – (BOOL)canBecomeFirstResponder, 且返回YES,使view或者viewController的self成為第一響應者,否則canPerformAction:withSender方法不會走
[self becomeFirstResponder];
  • 2.Menu所處的View必須實現 – (BOOL)canPerformAction:withSender, 並根據需求返回YES或NO

過載函式-(BOOL) canPerfomAction:(SEL)action withSender:(id)sender,設定要顯示的選單項,返回值為YES。若不進行任何限制,則將顯示系統自帶的所有選單項l

  • 3.定位Menu (- setTargetRect:inView:)
  • 4.展示Menu (- setMenuVisible:animated:)

這裡寫圖片描述

3.具體程式碼

//
//  ZQChatFootballViewCell.m
//  ZQMenuController
//
//  Created by zhouyu on 10/04/2018.
//  Copyright © 2018 zhouyu. All rights reserved.
// #import "ZQChatFootballViewCell.h" @interface ZQChatFootballViewCell () @property (nonatomic, strong) UILabel *contentLabel; @end @implementation ZQChatFootballViewCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) { self.selectionStyle = UITableViewCellSelectionStyleNone; _contentLabel = [[UILabel alloc] initWithFrame:CGRectMake(100, 200, 200, 100)]; _contentLabel.text = @"這是一個文字,在系統發現在其他View裡有Touch事件的時候,會自動將複製貼上選單隱藏。另外,有告警對話方塊彈出或者軟體退出的時候,複製按鈕也會被隱藏。當然,還是通過"; _contentLabel.textAlignment = NSTextAlignmentLeft; _contentLabel.numberOfLines = 0; _contentLabel.userInteractionEnabled = YES; [_contentLabel addGestureRecognizer:[[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]]; [self.contentView addSubview:_contentLabel]; //Menu所處的View必須實現--否則canPerformAction:(SEL)action withSender:(id)sender方法不走 [self becomeFirstResponder]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; _contentLabel.frame = self.contentView.bounds; } #pragma mark - longPress - (void)longPress:(UILongPressGestureRecognizer *)gesture { UIMenuController * menu = [UIMenuController sharedMenuController]; UIMenuItem * item1 = [[UIMenuItem alloc] initWithTitle:@"複製" action:@selector(myCopy:)]; UIMenuItem * item2 = [[UIMenuItem alloc] initWithTitle:@"舉報" action:@selector(myWhistleBlowing:)]; menu.menuItems = @[item1,item2]; if (menu.isMenuVisible) return;//避免重複顯示 [menu setTargetRect:CGRectMake(CGRectGetWidth(_contentLabel.frame) / 2, 15, 0, 0) inView:self.contentView];//定位 [menu setMenuVisible:YES animated:YES];//顯示 } #pragma mark - private //Menu所處的View必須實現 - (BOOL)canBecomeFirstResponder { return YES; } //Menu所處的View必須實現 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { if(action == @selector(myCopy:) || action == @selector(myWhistleBlowing:)) { return YES; } else { return NO; } } #pragma mark - event - (void)myCopy:(UIMenuController *)menu{ if (!_contentLabel.text) return; UIPasteboard * paste = [UIPasteboard generalPasteboard]; paste.string = _contentLabel.text; } - (void)myWhistleBlowing:(UIMenuController *)menu{ if (!_contentLabel.text) return; // UIPasteboard * paste = [UIPasteboard generalPasteboard]; // paste.string = _contentLabel.text; // _contentLabel.text = nil; if (self.delegate && [self.delegate respondsToSelector:@selector(whistleBlowingWithContent:)]) { [self.delegate whistleBlowingWithContent:_contentLabel.text]; } } @end

4.效果

這裡寫圖片描述

5.程式碼demo示例

複製貼上API的使用和注意事項

  • 首先要了解的是UIMenuController,也就是複製貼上Menu Controller;它用來控制使用複製貼上的時候彈出的按鈕。這個控制器在整個系統中只有一個例項,而且,應該顯示哪個按鈕就是由它來決定的。
  • 在系統發現在其他View裡有Touch事件的時候,會自動將複製貼上選單隱藏。另外,有告警對話方塊彈出或者軟體退出的時候,複製按鈕也會被隱藏。當然,還是通過-setMenuVisible:animated:方法,或者對UIMenuController.menuVisible進行賦值將其隱藏,也可以手動將其隱藏。

demo