21

ユーザーがUIWebViewで選択を完了したときに、「こんにちは」と「さようなら」の2つのオプションを表示したいと思います。

次のように、ViewControllerにオブザーバーを追加しました。しかし、私はそれ以上の実装を知りません。

[[UIMenuController sharedMenuController] addObserver:self 
                                          forKeyPath:UIMenuControllerWillShowMenuNotification
                                             options:nil
                                             context:nil
 ];
4

2 に答える 2

44

サーガル、

あなたの質問は数か月前のものですが、私は最終的にこれを理解したので、他の誰かを助ける場合に備えて答えようと思いました.

次のコードを、webview を含むビュー コントローラーの viewDidAppear: メソッドに追加しました。

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    UIMenuItem *customMenuItem1 = [[[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(customAction1:)] autorelease];
    UIMenuItem *customMenuItem2 = [[[UIMenuItem alloc] initWithTitle:@"Custom 2" action:@selector(customAction2:)] autorelease];
    [[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:customMenuItem1, customMenuItem2, nil]];
}

私の viewDidDisappear: では、これらのアイテムを削除します。

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];

    [[UIMenuController sharedMenuController] setMenuItems:nil];
}

次に、ビュー コントローラーに canPerformAction:withSender: メソッドを実装しました。ここで何が起こっているのかを理解するには、レスポンダーとレスポンダー チェーンの概念を理解することが役立ちます。基本的に、uiviewcontroller はレスポンダー チェーンの一部であるため、レスポンダー チェーンの上位にあるオブジェクト (UIWebView など) が処理方法を知らないアクション (上記で追加したカスタム アクションなど) を処理できるかどうかを尋ねられます (詳細については、UIResponder のドキュメントiOS のイベント処理ガイドを参照してください)。

これで、webview に対して canPerformAction:withSender: が呼び出されると、sender パラメーターが nil に設定されます。そのため、この関数の書き方について少し賢くしようとしています。基本的に、送信者がゼロであること、ユーザーに webview を表示していること、およびページ上の他のコントロールがファーストレスポンダーでないことを確認します。その場合は、これが上で定義したアクションの 1 つであるかどうかを確認し、そうであれば YES を返します。それ以外の場合はすべて、スーパーで同じメソッドを呼び出して UIViewController からデフォルト値を返します。

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    if (webView.superview != nil && ![urlTextField isFirstResponder]) {
        if (action == @selector(customAction1:) || action == @selector(customAction2:)) {
            return YES;
        }
    }

    return [super canPerformAction:action withSender:sender];
}

もちろん、次のステップは、選択内容を実際に処理する方法を見つけることです (おそらく、Web ビューで JavaScript を実行することによって)。

于 2010-08-29T20:14:13.477 に答える
5

迅速に:

class ViewController: UIViewController {
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)

        // add two custom menu items to the context menu of UIWebView (assuming in contenteditable mode)
        let menuItem1 = UIMenuItem(title: "Foo", action: #selector(ViewController.foo))
        let menuItem2 = UIMenuItem(title: "Bar", action: #selector(ViewController.bar))
        UIMenuController.sharedMenuController().menuItems = [menuItem1, menuItem2]
    }

    override func viewDidDisappear(animated: Bool) {
        super.viewDidAppear(animated)
        UIMenuController.sharedMenuController().menuItems = nil
    }

    override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
        if webView?.superview != nil {
            if action == #selector(ViewController.foo) || action == #selector(ViewController.bar) {
                return true
            }
        }

        return super.canPerformAction(action, withSender: sender)
    }

    func foo() {
        print("foo")
    }

    func bar() {
        print("bar")
    }
}

注: #selector は Swift 2.2 で使用できます。

スクリーンショット

于 2016-03-16T05:50:10.987 に答える