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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

1回答

2377閲覧

swift2.xでWKWebViewにプログレスバーを付けたい

aoshima.natsuki

総合スコア33

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/05/02 03:29

編集2016/05/02 03:33

質問させてください。swift2.xでのストーリーボードを使わないWKWebViewの実装についてです。

現在、1ページだけの起動後に表示される画面に特定のwebページが表示させるだけのサンプルアプリをつくっています。WKWebViewのtitle、loading、estimatedProgressを監視対象に入れプログレスバーを設置する設定をしているのですが、どうやってもプログレスバーが表示されずに困っており3日ほど詰まってしまって前に進めない状況なのでなんとか解決できないかと思い、質問させていただきました。titleの設定やスワイプで前の画面に戻る動作、プログレスの値(0.0-1.0)を取得してコンソールに出力させるまではだいたい理解して実装ができています。

viewDidLoadの // プログレスバーを設定する あたりが間違っているのかなと思いいろいろ試しているのですがどうやってもプログレスバーが出てきません。

また、監視対象の解除について、 viewWillDisappear で解除すべきか deinit で解除すべきかで迷っております。こちらについてもお詳しい方がおられましたら教えていただけますととても嬉しいです。どうかよろしくお願いいたします。

swift

1import UIKit 2import WebKit 3 4class ViewController: UIViewController, WKNavigationDelegate { 5 6 var webkitview: WKWebView? 7 var progressView: UIProgressView! 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 // Do any additional setup after loading the view, typically from a nib. 12 13 // ヘッダーにタイトルを設定する 14 self.navigationItem.title = "Home" 15 16 // WebKitのインスタンスをつくる 17 self.webkitview = WKWebView() 18 19 // WebKitをviewに紐付ける 20 self.view = self.webkitview! 21 22 // 表示する内容を設定する 23 let url = NSURL(string: "https://www.nintendo.co.jp") 24 let req = NSURLRequest(URL: url!) 25 self.webkitview!.loadRequest(req) 26 27 // スワイプで戻る動作を設定する 28 self.webkitview!.allowsBackForwardNavigationGestures = true 29 30 // プログレスバーを設定する 31 self.webkitview!.navigationDelegate = self 32 progressView = UIProgressView(frame: CGRectMake(0, self.navigationController!.navigationBar.frame.size.height, self.view.frame.size.width, 10)) 33 progressView.progressTintColor = UIColor.greenColor() 34 progressView.trackTintColor = UIColor.whiteColor() 35 progressView.layer.position = CGPoint(x:0, y:(self.navigationController?.navigationBar.frame.size.height)!) 36 progressView.transform = CGAffineTransformMakeScale(1.0, 2.0) 37 self.navigationItem.titleView?.addSubview(progressView) 38 } 39 40 deinit { 41 // 監視対象を解除する 42 webkitview!.removeObserver(self, forKeyPath: "estimatedProgress") 43 webkitview!.removeObserver(self, forKeyPath: "loading") 44 webkitview!.removeObserver(self, forKeyPath: "title") 45 } 46 47 override func didReceiveMemoryWarning() { 48 super.didReceiveMemoryWarning() 49 // Dispose of any resources that can be recreated. 50 } 51 52 override func viewWillAppear(animated: Bool) { 53 // 監視対象を登録する 54 self.webkitview!.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil) 55 self.webkitview!.addObserver(self, forKeyPath: "loading", options: .New, context: nil) 56 self.webkitview!.addObserver(self, forKeyPath: "title", options: .New, context: nil) 57 } 58 59 override func viewWillDisappear(animated: Bool) { 60 // 監視対象を解除する 61 self.webkitview!.removeObserver(self, forKeyPath: "estimatedProgress") 62 self.webkitview!.removeObserver(self, forKeyPath: "loading") 63 self.webkitview!.removeObserver(self, forKeyPath: "title") 64 } 65 66 override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 67 if(keyPath == "estimatedProgress") { 68 let progress : Float = Float(webkitview!.estimatedProgress) 69 if(progressView != nil) { 70 if(progress < 1.0) { 71 // プログレスバーを更新する 72 print("loaded:\(progress)") 73 progressView.setProgress(progress, animated: true) 74 UIApplication.sharedApplication().networkActivityIndicatorVisible = true 75 } else { 76 // 読み込みが完了したらプログレスバーを消す 77 print("loaded:done") 78 progressView.setProgress(0.0, animated: false) 79 UIApplication.sharedApplication().networkActivityIndicatorVisible = false 80 } 81 } 82 } else if(keyPath == "title") { 83 // タイトルにページのタイトルを設定する 84 let title = self.webkitview!.title 85 self.navigationItem.title = title 86 } 87 } 88}

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

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

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

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

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

guest

回答1

0

ベストアンサー

swift

1self.navigationItem.titleView?.addSubview(progressView)

ではなく、

swift

1self.navigationItem.titleView = progressView

で。(printすればわかりますが、self.navigationItem.titleViewはnilです)

解除についてはよくわからないのでパス。

【追記】

aoshima.natsukiさんのやりたいことを想像すると、viewDidLoadでprogressViewをセットするのではなく、読み込み開始時に、

swift

1self.navigationItem.titleView = progressView

読み込み終了時に、

swift

1self.navigationItem.titleView = nil

とすればいいと思います。

投稿2016/05/02 05:07

編集2016/05/02 05:24
fuzzball

総合スコア16731

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

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

aoshima.natsuki

2016/05/02 07:25 編集

さっそくのご回答ありがとうございます。おっしゃる通りご呈示いただいたコードでほとんど思い通りのことが実現できました。また、追記でご指摘いただいた点についても納得しました。確かにこちらで指定すべきでした。ご丁寧にありがとうございます。 ただこちらですと、self.navigationItem.title に指定していたページのタイトルが打ち消されてしまうのですが回避策はありますか? また、また、progressViewのサイズと位置の指定で、もしご存知であれば教えていただきたいのですが progressView = UIProgressView(frame: CGRectMake(0, self.navigationController!.navigationBar.frame.size.height, self.view.frame.size.width, 10)) と progressView.layer.position = CGPoint(x:0, y:(self.navigationController?.navigationBar.frame.size.height)!) がどうやら適応されないようです。記述の仕方は間違っていないと思っていたのですが、どこか悪い点は見受けられますでしょうか。試しにすべて0に指定しても何も変化がなく、幅が95%くらいから変わらず、位置も0にしても中途半端なところから動かず困っております。もしご存知であればこちらについても教えていただけますととても嬉しいです。
fuzzball

2016/05/02 07:45 編集

読み込み中はタイトルの代わりにプログレスを表示するのかと思ったのですが、そういうわけではないんですね。何を実現したいのか(どうなったら正解なのか)を書いてもらわないとアドバイスのしようがありません。
aoshima.natsuki

2016/05/02 08:39

言葉不足ですみません。読み込み中からnavigationbarにタイトルが表示させ、それとは別に読み込み率をnavigationbarの下に表示させたいです。このような見せ方をするのはあまり一般的ではないのでしょうか?よろしくお願いいたします。
fuzzball

2016/05/02 09:41 編集

時間切れなので分かったことだけ書いておきます。 ・WkWebViewの初期化 現在、frame指定をしていないのでサイズが0になっています。ということは、progressViewの横幅も0になっているということです。 → self.webkitview = WKWebView(frame: self.view.frame) ・addSubView progressViewはtitleViewにセットするのではなく、self.viewにセットして下さい。 → self.view.addSubview(progressView) ・progressViewのY座標 直値で100を指定してみて下さい。上記の横幅の件と合わせて、とりあえず画面に表示されると思います。 navigationBarの高さでダメな理由は突き止められませんでした。 あと、普通layer.positionは使わないと思うのですが何か意図があるのでしょうか?特に理由がなければframeで指定した方が良いと思います。 では良いGWを!w
aoshima.natsuki

2016/05/02 10:50 編集

ご回答ありがとうございます。 frame指定をしていないとサイズが0になってしまうのですね。知りませんでした。。frame指定をすることで self.view!.bounds.size.width が取得できるようになり幅100%でプログレスバーを設置することができるようになりました。 pregressViewのY座標については self.navigationController?.navigationBar.frame.size.height がなぜか取得でき直接値で指定したとこをひとまず思い通りの位置に設置することができました。 (追記:追記いただいた記事がとても参考になりそうです!ひとまず直接指定してしまいましたが後ほどこちらの方法で実現できないか試してみます!) その他もろもろの良くなかった書き方を修正し、思い描いていたものが実現できました。ご丁寧にありがとうございました。良いGWをお過ごし下さい!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問