iOS开发 UILabel长按弹出复制选项-UIContextMenuInteraction

本文介绍了如何在iOS13及以上版本中为UILabel实现长按复制功能,使用了UIContextMenuInteraction和UIContextMenuConfiguration,通过设置代理方法来提供长按后的复制选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 目标效果

左侧的图片为长按操作前界面的显示效果,右侧的图片为长按“MAC”项右侧的1032E23A34D2(UILabel 后,弹出复制选项菜单的显示效果。
在这里插入图片描述

2. 实现代码

1. 给要实现长按复制功能的UILabel添加上下文菜单交互对象:UIContextMenuInteraction

提示:UIContextMenuInteraction 在iOS 13.0及更新版本中可用。

#import "DeviceInfoViewController.h"

@interface DeviceInfoViewController () <UIContextMenuInteractionDelegate>

@property (nonatomic, weak) IBOutlet UILabel *macLabel;

@property (nonatomic, weak) IBOutlet UILabel *modelLabel;

@end

@implementation DeviceInfoViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setupUI];
}

- (void)setupUI {
    self.title = NSLocalizedString(@"设备信息", nil);
    
    // MAC
    [self prepareLongPressCopyInView:self.macLabel];
    // 产品型号
    [self prepareLongPressCopyInView:self.modelLabel];
}


#pragma mark - 长按弹出复制按钮的相关实现方法

- (void)prepareLongPressCopyInView:(UIView *)view {
    view.userInteractionEnabled = YES;
    
    // 通过上下文菜单(UIContextMenuInteraction)实现 (需实现UIContextMenuInteractionDelegate代理方法)
    UIContextMenuInteraction *interaction = [[UIContextMenuInteraction alloc] initWithDelegate:self];
    [view addInteraction:interaction];
}


2. 实现UIContextMenuInteractionDelegate代理方法
// MARK: UIContextMenuInteractionDelegate

/// 交互开始时调用, 用来返回 预览控制器 和 操作菜单, 预览控制器 和 操作菜单都可为空
- (UIContextMenuConfiguration *)contextMenuInteraction:(UIContextMenuInteraction *)interaction configurationForMenuAtLocation:(CGPoint)location API_AVAILABLE(ios(13.0)) {
    // 通过interaction拿到对应的view
    UIView *view = interaction.view;
    
    // 创建菜单选项
    UIImage *action1Image = nil;
    if (@available(iOS 13.0, *)) {
        action1Image = [UIImage systemImageNamed:@"doc.on.doc"];
    }
    UIAction *action1 = nil;
    if (view == self.macLabel) {
        action1 = [UIAction actionWithTitle:NSLocalizedString(@"复制", nil) image:action1Image identifier:@"App.MenuActionID.Copy.Mac" handler:^(__kindof UIAction * _Nonnull action) {
            // 通过系统的粘贴板,记录下需要传递的数据
            [UIPasteboard generalPasteboard].string = self.macLabel.text;
        }];
    } else if (view == self.modelLabel) {
        action1 = [UIAction actionWithTitle:NSLocalizedString(@"复制", nil) image:action1Image identifier:@"App.MenuActionID.Copy.Model" handler:^(__kindof UIAction * _Nonnull action) {
            // 通过系统的粘贴板,记录下需要传递的数据
            [UIPasteboard generalPasteboard].string = self.modelLabel.text;
        }];
    }
    // 创建菜单
    UIMenu *menu = [UIMenu menuWithTitle:@"" children:@[action1]];
    
    UIContextMenuConfiguration *config = [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:^UIViewController * _Nullable {
        return nil;
    } actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
        return menu; // 返回菜单
    }];
    return config;
}

/// 交互开始时调用, 用来返回预览视图弹出时其所在位置的视图, 例如:如果返回视图A,则预览视图会在视图A位置弹出
/// 不实现该方法或返回nil时, 预览视图会默认在交互所在视图(即添加交互对象的视图)位置弹出
- (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForHighlightingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) {
    return nil;
}

/// 交互消失时调用, 用来返回预览视图消失时其所在位置的视图, 例如:如果返回视图B,则预览视图会在视图B位置消失
/// 不实现该方法或返回nil时, 预览视图会默认在交互所在视图(即添加交互对象的视图)位置消失
- (UITargetedPreview *)contextMenuInteraction:(UIContextMenuInteraction *)interaction previewForDismissingMenuWithConfiguration:(UIContextMenuConfiguration *)configuration API_AVAILABLE(ios(13.0)) {
    return nil;
}

@end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值