在自定义视图/uiview 子类上实现 iphone 的复制/粘贴控件

Posted

技术标签:

【中文标题】在自定义视图/uiview 子类上实现 iphone 的复制/粘贴控件【英文标题】:Implementing iphone's copy/paste controls on a custom view / uiview subclass 【发布时间】:2010-01-21 16:10:07 【问题描述】:

我承认在 S.O. 上已经有一个完全符合这些思路的问题,但它缺乏实现细节,一个有效的答案,我想更具体一些,所以我认为一个新问题是有序的。显然,如果我错了,请告诉我,我们可以尝试restart the thread over there。

基本上,当用户按住标签时,我想将 UILabel 中的文本复制到粘贴板。老实说,不难做到。但是,我认为提供视觉反馈的最佳方式是使用来自UIMenuController 的“复制”菜单选项提示用户。

根据 iPhone 应用程序编程指南的事件处理部分,特别是 Copy, Cut, and Paste Operations 部分,应该可以从自定义视图提供复制、剪切和/或粘贴操作。

因此,我已按照指南中的描述使用以下实现对 UILabel 进行了子类化,但 UIMenuController 不会出现。指南中没有任何迹象表明还需要执行此操作,并且 NSLog 语句确实会打印到控制台,表明当我按住标签时正在执行选择器:

//
//  CopyLabel.m
//  HoldEm
//
//  Created by Billy Gray on 1/20/10.
//  Copyright 2010 Zetetic LLC. All rights reserved.
//

#import "CopyLabel.h"

@implementation CopyLabel

- (void)showCopyMenu 
    NSLog(@"I'm tryin' Ringo, I'm tryin' reeeeal hard.");
    // bring up editing menu.
    UIMenuController *theMenu = [UIMenuController sharedMenuController];
    // do i even need to show a selection? There's really no point for my implementation...
    // doing it any way to see if it helps the "not showing up" problem...
    CGRect selectionRect = [self frame];
    [theMenu setTargetRect:selectionRect inView:self];
    [theMenu setMenuVisible:YES animated:YES]; // <-- doesn't show up...


// obviously, important to provide this, but whether it's here or not doesn't seem
// to change the fact that the UIMenuController view is not showing up
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender 
    BOOL answer = NO;

    if (action == @selector(copy:))
        answer = YES;

    return answer;


- (BOOL)canBecomeFirstResponder 
    return YES;


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    [self performSelector:@selector(showCopyMenu) withObject:nil afterDelay:0.8f];


- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(showCopyMenu) object:nil];


@end

那么,要做到这一点,还需要做些什么呢?

对于那些跟随并尝试这样做的人,您还需要为标签设置“启用用户交互”

编辑:

为清楚起见,让我补充一点,这应该类似于在某些 iphone 视图中按住图像时出现在图像上的小 [复制] 菜单项。 -B

【问题讨论】:

完成这项工作后,我在 Mobile Orchard 上整理了一个教程和示例项目:mobileorchard.com/hold-and-copy-in-uikit 教程正是我所需要的,但您忘记添加“重置”方法代码。谢谢! 【参考方案1】:

我会先说我没有答案,但我做了一些探索并发现了更多信息。我相信你已经看过这个了:CopyPasteTile

该代码确实可以在我的模拟器上运行,如下所示:

CGRect drawRect = [self rectFromOrigin:currentSelection inset:TILE_INSET];
[self setNeedsDisplayInRect:drawRect];

UIMenuController *theMenu = [UIMenuController sharedMenuController];
[theMenu setTargetRect:drawRect inView:self];
[theMenu setMenuVisible:YES animated:YES];

这里有一些区别:

drawRect 是根据巨大的视图图块和点击点计算得出的 正在调用setNeedsDisplayInRect self 是一个大屏幕尺寸的视图,您可能需要屏幕坐标而不是本地坐标(您可能可以从 self.superview 获得)

我会先尝试进行这些调整以匹配示例,然后看看它给我带来了什么样的进步。

【讨论】:

BINGO,尝试了你的每一个建议,获胜者设置了selectionRect = [[super view] frame]。将编写一个完整的工作示例并很快将其链接到此处。谢谢! 很高兴听到你把它修好了:) 那么比利 - 完整的例子在哪里? :-)

以上是关于在自定义视图/uiview 子类上实现 iphone 的复制/粘贴控件的主要内容,如果未能解决你的问题,请参考以下文章

在自包含的自定义 UIView 子类中使用 .xib 文件进行原型设计

如何在自定义适配器上实现 onClickListener?

在自定义 UIView 类 Iphone 上应用自动布局约束。

在自定义视图上显示弹出菜单时不要关闭键盘

在 Storyboard 中设计的自定义 UITableViewCell 中的自定义 UIView

在自定义 UIview 中设置 UItableview 的委托和数据源