使用自定义 UIMenuController 项从 UIPasteboard 中复制和检索值

Posted

技术标签:

【中文标题】使用自定义 UIMenuController 项从 UIPasteboard 中复制和检索值【英文标题】:Use standard Copy and retrieve value from the UIPasteboard with a custom UIMenuController item 【发布时间】:2012-05-30 15:07:12 【问题描述】:

我有一个显示 pdf 文件的 web 视图。作为网络视图的标准,用户可以选择文本并执行标准操作,如复制、剪切。我需要添加一个自定义 UIMenuController 用于显示自定义操作。我不明白如何在标准 UIPasteboard 中复制所选文本并传递给我的自定义选择器。 我试过用

[[UIApplication sharedApplication] sendAction:@selector(copy:) to:nil from:self forEvent:nil];

在方法中,我可以复制选定的文本,但我不明白如何将此值返回到我的方法中。

这是我的代码(简化) 在视图中确实加载了我为 UIPasteboardChangedNotification 添加了一个观察者来执行我的选择器 myCopy:

- (void)viewDidLoad

[super viewDidLoad];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myCopy:) name:UIPasteboardChangedNotification object:nil];

UIMenuItem *schedaMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"POPSCHEDA",nil) action:@selector(copyScheda:)];
UIMenuItem *istruzionetMenuItem = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"POPISTR",nil) action:@selector(copyIstruzione:)];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:MenuItem1,MenuItem2,nil]];



-(void)myCopy:(id)sender 
  UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
  NSString* copyCode = pasteboard.string;
  //perform the necessary action
 

 -(void)copyScheda:(id)sender 
   UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
   NSString* copyCode = pasteboard.string;
   //perform the necessary action
 

 -(void)copyIstruzione:(id)sender 
   UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
   NSString* copyCode = pasteboard.string;
   //perform the necessary action
 

感谢您的帮助和时间!

【问题讨论】:

【参考方案1】:

如果我正确理解了您的问题,那么您是在尝试获取当前选择的文本,当用户点击您的自定义项目时将其复制到粘贴板,然后对所选/复制的文本执行操作?

如果是这样,我认为这应该对你有用,至少它在 Swift 4 中对我有用。

首先,在viewDidLoad 中,设置您的自定义菜单项

let customMenuItem = UIMenuItem(title: "Foo Bar", action: #selector(ViewController.customMenuTapped))
UIMenuController.shared.menuItems = [customMenuItem]
UIMenuController.shared.update()

然后,仍然在viewDidLoad 中将自己设置为UIPasteboardChanged 的观察者

NotificationCenter.default.addObserver(self, selector: #selector(displaySelectecText), name: NSNotification.Name.UIPasteboardChanged, object: nil)

然后创建响应customMenuItem 的函数,在我的示例中它是customMenuTapped(),并且您基本上将复制操作发送到响应者链来处理它。

@objc func customMenuTapped() 
    UIApplication.shared.sendAction(#selector(copy(_:)), to: nil, from: self, for: nil)

由于您已将自己注册为侦听器,因此当复制操作完成后,您的另一个函数将被调用,我的是 displaySelectecText()

@objc func displaySelectedText() 
    let copiedText = UIPasteboard.general.string ?? ""
    let alertView = UIAlertController(title: "Selected Text", message: copiedText, preferredStyle: .alert)
    alertView.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
    present(alertView, animated: true, completion: nil)

在本例中,为了简单起见,我只是在警报视图中显示文本。

完整代码如下:

import UIKit
import WebKit

class ViewController: UIViewController 

    @IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() 
        super.viewDidLoad()

        loadWebView()
        setupCustomMenu()
        setupListener()
    

    func loadWebView() 
        let url = URL(string: "http://www.google.com")
        let request = URLRequest(url: url!)
        webView.load(request)
    

    func setupCustomMenu() 
        let customMenuItem = UIMenuItem(title: "Foo Bar", action:
            #selector(ViewController.customMenuTapped))
        UIMenuController.shared.menuItems = [customMenuItem]
        UIMenuController.shared.update()
    

    func setupListener() 
        NotificationCenter.default.addObserver(self, selector: #selector(displaySelectedText), name: NSNotification.Name.UIPasteboardChanged, object: nil)
    

    @objc func customMenuTapped() 
        UIApplication.shared.sendAction(#selector(copy(_:)), to: nil, from: self, for: nil)
    

    @objc func displaySelectedText() 
        let copiedText = UIPasteboard.general.string ?? ""
        let alertView = UIAlertController(title: "Selected Text", message: copiedText, preferredStyle: .alert)
        alertView.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        present(alertView, animated: true, completion: nil)
    


这是一个演示

【讨论】:

以上是关于使用自定义 UIMenuController 项从 UIPasteboard 中复制和检索值的主要内容,如果未能解决你的问题,请参考以下文章

自定义 UIMenuController

UIMenuController 未在 UICollectionViewController 子类上显示自定义操作

从 UIMenuController 中删除自定义菜单项

如何在 UIMenuController 的自定义操作中获取点击的表格视图单元格

自定义 UIMenuController

如何显示自定义弹出窗口而不是 UIMenuController