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

发布于 2024-08-18 20:47:48 字数 2674 浏览 5 评论 0原文

我承认,这里已经有一个与此完全一致的问题,但它缺乏实现细节、工作答案,而且我想更具体,所以我认为应该提出一个新问题。显然,如果我错了,请告诉我,我们可以尝试重新启动那边的线程

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

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

因此,我按照指南所述使用以下实现对 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

I will admit that there is already a question exactly along these lines here on S.O., but it lacks implementation details, a working answer, and I would like to be more specific, so I think a new question is in order. Obviously, let me know if I'm wrong and we can try to restart the thread over there.

Basically, I want to copy the text in a UILabel to the pasteboard when a user holds down on the label. Not hard to do, honestly. However, I think the best way to provide visual feedback is to prompt the user with the Copy menu option from UIMenuController.

According to the Event Handling section of the iPhone Application Programming Guide, specifically the section on Copy, Cut, and Paste Operations, it should be possible to provide copy, cut, and/or paste operations from a custom view.

So, I've sub-classed UILabel with the following implementation as described by the guide, but the UIMenuController won't show up. There's no indication in the guide that there's anything else required to do this, and the NSLog statement does print out to the console, indicating that the selector is being performed when I hold down on the label:

//
//  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

So, what else does one have to do to make this happen?

For those following along and trying to do this, too, you'll also need to set 'User Interaction Enabled' for the label

Edit:

For clarity, let me add that this should be similar to the little [Copy] menu item that appears over an image in certain iphone views when you hold down on it. -B

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

維他命╮ 2024-08-25 20:47:48

我会先说我没有答案,但我做了一些探索并发现了更多信息。我确信您已经看过这个: 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 获得)

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

I'll say upfront I don't have an aswer, but I did some poking around and found more out. I'm sure you've looked at this already: CopyPasteTile

That code does work on my simulator and goes like this:

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];

There are a few differences here:

  • drawRect is calculated from a giant view tile and tap point calculations
  • setNeedsDisplayInRect is being called
  • self is a large screen sized view, you may need screen coords instead of local coords (you can probably get that from self.superview)

I'd try making these adjustments to match the example first and see what kind of progress it gets me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文