質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Swift

    8942questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    4774questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

WKWebViewの中で画像を長押すとカスタマイズのActionSheetを表示したい

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,017

Abest

score 2

 前提・実現したいこと

swift 4
Xcode 9.2
iOS 10.3

WKWebViewの中で画像を長押すとカスタマイズのActionSheetを表示、他のリンクとかはそのままのデフォルトのActionSheetを表示する機能を実現したいです。

実装中に以下の問題が発生しました。

 発生している問題

document.body.style.webkitTouchCallout='none'を使うとすべてのリンクに対する長押しは無効になります。しかし、それを使わないと画像を長押すときにデフォルトのActionSheetと自分が作ったものが同時に重なって表示します。

 該当のソースコード

関係のあると思うコードをアップロードしました。

@objc func longPressed(_ gesture: UILongPressGestureRecognizer) {

        if gesture.state == UIGestureRecognizerState.began {

            let touchPoint: CGPoint = gesture.location(in: self.view)
            let ptX = touchPoint.x
            var ptY = touchPoint.y

            if (ptY <= (self.webview.frame.origin.y + self.webview.frame.size.height))
            {

                if #available(iOS 7.0, *) {

                    ptY -= 20.0
                }

                self.webview.evaluateJavaScript("document.elementFromPoint(\(ptX), \(ptY)).tagName", completionHandler: {(_ object: Any, _ error: Error?) -> Void in
                    let tagname = object as! String
                    if tagname == "IMG" {
                        self.webview.evaluateJavaScript("document.elementFromPoint(\(ptX), \(ptY)).src", completionHandler: {(_ object: Any, _ error: Error?) -> Void in
                            self._imgURL = object as! String
                            let imageData = try? Data(contentsOf: URL(string: self._imgURL)!)
                            if imageData != nil {

                                self.handleLongTouch()  //ここでカスタマイズのActionSheetを呼び出す
                            }
                        })
                    }
                })
            }
        }
    }

fileprivate var longPressGesture: UILongPressGestureRecognizer! {

        let longPressGesture: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressed))
        longPressGesture.minimumPressDuration = 0.5
        longPressGesture.delegate = self
        return longPressGesture
    }

private func loadWebview() {

        let webConfiguration = WKWebViewConfiguration()
        let noneSelectScript = WKUserScript(source: "document.body.style.webkitTouchCallout='none'", injectionTime: .atDocumentEnd, forMainFrameOnly: false)
        webConfiguration.userContentController.addUserScript(noneSelectScript)
        self.webview = WKWebView(frame: .zero, configuration: webConfiguration)

        self.webview.translatesAutoresizingMaskIntoConstraints = false
        self.webview.allowsBackForwardNavigationGestures = true
        self.view.addSubview(self.webview)
        self.webview.topAnchor.constraint(equalTo: self.webviewContainer.topAnchor).isActive = true
        self.webview.rightAnchor.constraint(equalTo: self.webviewContainer.rightAnchor).isActive = true
        self.webview.leftAnchor.constraint(equalTo: self.webviewContainer.leftAnchor).isActive = true
        self.webview.bottomAnchor.constraint(equalTo: self.webviewContainer.bottomAnchor).isActive = true
        self.webview.navigationDelegate = self as WKNavigationDelegate
        self.webview.uiDelegate = self as? WKUIDelegate
    }

初めての質問で、お手数をお掛け致しますが、宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

下記の回答など参考になりますでしょうか?
https://stackoverflow.com/questions/34275334/how-to-override-wkwebview-hyperlink-action-sheet

流れとしては、
longPressedの中でフラグを立てて、
func webView(webView: WKWebView, decidePolicyForNavigationAction navigationAction: WKNavigationAction, decisionHandler: (WKNavigationActionPolicy) -> Void)
の中で対象だった場合はdecisionHandler(decisionHandler(WKNavigationActionPolicy.cancel)で既存処理をキャンセルし、ActionSheetを設定して呼び出しているようです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Swift

    8942questions

    Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

  • iOS

    4774questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。