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

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

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

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

Q&A

解決済

2回答

1939閲覧

SwiftでWKWebViewのDelegateメソッドと他のextensionとの組み合わせ

MycoChild

総合スコア36

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Swift

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

0グッド

0クリップ

投稿2021/11/07 07:31

編集2021/11/07 07:57

Swiftで、現在のスクロール量がaタグより前のときに所望の処理をしたいです。
scrollViewDidScrollとfunc webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)を組み合わせて使いたいです。

Swift

1var y_array : String = "" 2let get_yarray=""" 3 function get_atag_y(){ 4 var y_array2=""; 5 var doms = document.querySelectorAll('a'); 6 for (var i = 0; i < doms.length; i++) { 7 y_array2+=String(doms[i].getBoundingClientRect().top + window.pageYOffset) 8 if (i!=doms.length-1){ 9 y_array2+="," 10 } 11 } 12 return String(y_array2) 13 } 14 get_atag_y() 15 """ 16func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 17webView.evaluateJavaScript(get_yarray, completionHandler: { (result, error) in 18 19 if let y_array = result as? String { 20 self.y_array = y_array//Int(y_array) 21 } 22 }) 23}

これでaタグの位置を読み込み後にy_array変数に格納して、

Swift

1// MARK: UICollectionViewDelegate 2extension ViewController: UICollectionViewDelegate { 3 let y_array_ = self.y_array.components(separatedBy: ",") 4         func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { 5 scrollBeginingPoint = scrollView.contentOffset; 6 y_array_ = self.y_array.components(separatedBy: ",") 7 } 8 9 func scrollViewDidScroll(_ scrollView: UIScrollView) { 10 let currentPoint = scrollView.contentOffset 11 if (currentPoint.y > Int(y_array_[0])){ 12 現在のスクロール量がaタグより前のときの処理〜 13 } 14 } 15} 16

このとき、func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!)の処理の方がfunc scrollViewDidScroll(_ scrollView: UIScrollView) よりも遅いので、aタグが位置の格納されずNullになってしまいます。
また、extension ViewController: UICollectionViewDelegate内でグローバル
変数のようにy_array_func scrollViewDidScroll(_ scrollView: UIScrollView)に値渡ししたいのですが、
Extensions must not contain stored propertiesとエラーが出てしまいます。
どうすればいいでしょうか

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

すでに回答ありますが、回答依頼いただいたので回答します。

aタグが位置の格納されずNullになってしまいます。

処理の順番の都合で値が格納されないのはあるあるなので、値を利用する部分で期待通りの値が格納されているかチェックするといいと思います。

Extensions must not contain stored properties とエラーが出てしまいます。

Extensionに変数は書けないので、拡張元のクラス(今回はextension ViewControllerなのでclass ViewController部分で変数を定義します。

swift

1import UIKit 2import WebKit 3 4class ViewController: UIViewController { 5 @IBOutlet weak var webView: WKWebView! 6 7 private let get_yarray = """ 8 function get_atag_y(){ 9 var y_array2=""; 10 var doms = document.querySelectorAll('a'); 11 for (var i = 0; i < doms.length; i++) { 12 y_array2+=String(doms[i].getBoundingClientRect().top + window.pageYOffset) 13 if (i!=doms.length-1){ 14 y_array2+="," 15 } 16 } 17 return String(y_array2) 18 } 19 get_atag_y() 20 """ 21 22 private var y_array: String = "" 23 private var y_array_: [String] = [] 24 25 override func viewDidLoad() { 26 super.viewDidLoad() 27 28 webView.navigationDelegate = self 29 webView.scrollView.delegate = self 30 31 webView.load(URLRequest(url: URL(string: "https://...")!)) 32 } 33} 34 35extension ViewController: WKNavigationDelegate { 36 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 37 webView.evaluateJavaScript(get_yarray, completionHandler: { (result, error) in 38 if let y_array = result as? String { 39 self.y_array = y_array 40 } 41 42 debugPrint("[ViewController:webView] y_array: (self.y_array)") 43 }) 44 } 45} 46 47extension ViewController: UIScrollViewDelegate { 48 func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { 49 y_array_ = self.y_array.components(separatedBy: ",") 50 51 debugPrint("[ViewController:scrollViewWillBeginDragging] y_array_: (y_array_)") 52 } 53 54 func scrollViewDidScroll(_ scrollView: UIScrollView) { 55 let currentPoint = scrollView.contentOffset 56 57 debugPrint("[ViewController:scrollViewDidScroll] currentPoint: (currentPoint)") 58 debugPrint("[ViewController:scrollViewDidScroll] y_array_: (y_array_)") 59 60 if y_array_.indices.contains(0) { 61 if let y = Float(y_array_[0]), currentPoint.y > CGFloat(y) { 62 debugPrint("[ViewController:scrollViewDidScroll] 現在のスクロール量がaタグより前のときの処理") 63 } 64 } 65 } 66} 67

投稿2021/11/08 01:59

KAOsaka

総合スコア531

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

WebViewのスクロール位置とaタグの位置を比較する処理を、以下のようにして分離するとよいと思います。

swift

1import UIKit 2import WebKit 3 4class ViewController: UIViewController, WKNavigationDelegate, UIScrollViewDelegate { 5 6 @IBOutlet private weak var webView: WKWebView! 7 8 override func viewDidLoad() { 9 super.viewDidLoad() 10 11 webView.navigationDelegate = self 12 webView.scrollView.delegate = self 13 14 let url = URL(string: "https://www.google.com")! 15 let request = URLRequest(url: url) 16 webView.load(request) 17 } 18 19 let get_yarray = """ 20 function get_atag_y(){ 21 var y_array2=""; 22 var doms = document.querySelectorAll('a'); 23 for (var i = 0; i < doms.length; i++) { 24 y_array2+=String(doms[i].getBoundingClientRect().top + window.pageYOffset) 25 if (i!=doms.length-1){ 26 y_array2+="," 27 } 28 } 29 return String(y_array2) 30 } 31 get_atag_y() 32 """ 33 34 var positions: [Int] = [] 35 36 func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { 37 webView.evaluateJavaScript(get_yarray) { result, error in 38 guard let result = result as? String else { 39 return 40 } 41 self.positions = result.components(separatedBy: ",").compactMap({ Int($0) }) 42 print("positionsの値を更新しました") 43 self.checkScrollPosition() 44 } 45 } 46 47 func scrollViewDidScroll(_ scrollView: UIScrollView) { 48 print("scrollViewDidScroll") 49 checkScrollPosition() 50 } 51 52 private func checkScrollPosition() { 53 print("checkScrollPosition") 54 guard let firstY = positions.first else { 55 print("取得済のaタグの位置はありません") 56 return 57 } 58 if webView.scrollView.contentOffset.y > CGFloat(firstY) { 59 print("現在のスクロール量がaタグより前のときの処理〜") 60 } 61 } 62}

投稿2021/11/07 09:11

__k_san__

総合スコア177

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MycoChild

2021/11/08 15:29

ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問