web-dev-qa-db-ja.com

進行状況バー付きのUIWebView

こんにちは私はプログラミングが初めてで、XcodeでiPhone用の最初のアプリを作成しようとしています。私のアプリには、押されたときにUIWebViewを開き、ホームページをロードするボタンが含まれています。ここで、Safariも使用しているように、ページのロードの進行状況を示すProgress ViewをWebViewに追加します。どうやってやるの?
UIWebViewにURLをロードするためのこれまでの私のコード:

。h

IBOutlet UIWebView *webView;

。m

- (void)viewDidLoad
{
[webView loadRequest:[NSURLRequest requestWithURL: [NSURL URLWithString:@"http:/www.google.com/"]]];

ご協力いただきありがとうございます!

22
user3220034

正確なUIProgressViewを使用するには、次のタスクが必要です。

  • 完全ではない間に情報を取得できます
  • その情報に基づいてパーセンテージで「完全性」を定量化します。

UIWebViewを読み込んでいるとき、それは不可能です。そして、Appleもそれをしません。 Appleは、偽のUIProgressViewsをよく使用して、ページの読み込み中に見たいものを提供します。メールも偽の進行状況ビューを使用します。自分で試してみてください。これが、Appleの偽の進行状況ビューの仕組みです。

  • 進行状況ビューはゆっくりと一定の速度で動き始めます
  • バーが完了する前にタスクが終了すると、残りの部分が突然消えてから消えます
  • タスクに時間がかかる場合、進行状況ビューは95%で停止し、タスクが完了するまでそこにとどまります。

これを実現するには、progressViewを手動でアニメーション化する必要があります。あなたはそれをサブクラス化することができますが、それはおそらくあなたのために少し高度になるでしょう。最も簡単な方法は次のとおりです。

MyViewController.hで

@interface myViewController : UIViewController {
     BOOL theBool;
     //IBOutlet means you can place the progressView in Interface Builder and connect it to your code
     IBOutlet UIProgressView* myProgressView;
     NSTimer *myTimer;
}
@end

MyViewController.mで

#import "myViewController.h"
@implementation myViewController
- (void)webViewDidStartLoad:(UIWebView *)webView{
     myProgressView.progress = 0;
     theBool = false;
     //0.01667 is roughly 1/60, so it will update at 60 FPS
     myTimer = [NSTimer scheduledTimerWithTimeInterval:0.01667 target:self selector:@selector(timerCallback) userInfo:nil repeats:YES];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView{
     theBool = true;
}
-(void)timerCallback {
    if (theBool) {
         if (myProgressView.progress >= 1) {
              myProgressView.hidden = true;
              [myTimer invalidate];
         }
         else {
              myProgressView.progress += 0.1;
         }
    }
    else {
         myProgressView.progress += 0.05;
         if (myProgressView.progress >= 0.95) {
              myProgressView.progress = 0.95;
         }
    }
}
@end

次に、タスクが完了する場所でtheBool = true;を設定すると、進行状況ビューが自動的に処理します。 ifステートメントの値を変更して、アニメーションの速度を制御します。

70
WolfLink

Swift 2.2

class ViewController: UIViewController,UIWebViewDelegate {

    @IBOutlet weak var webView: UIWebView!
    @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
    @IBOutlet weak var myProgressView: UIProgressView!

    var myTimer = NSTimer()
    var theBool = Bool()

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = NSURL(string: "https://www.youtube.com")
        let request = NSURLRequest(URL: url!)
        activityIndicator.hidesWhenStopped = true
        activityIndicator.startAnimating()
        webView.loadRequest(request)

    }
    func timerCallback(){
        if theBool {
            if myProgressView.progress >= 1 {
                myProgressView.hidden = true
                myTimer.invalidate()
            }else{
                myProgressView.progress += 0.1
            }
        }else{
            myProgressView.progress += 0.05
            if myProgressView.progress >= 0.95 {
                myProgressView.progress = 0.95
            }
        }
    }

    func webViewDidStartLoad(webView: UIWebView) {
        activityIndicator.startAnimating()
        myProgressView.progress = 0
        theBool = false
        myTimer =  NSTimer.scheduledTimerWithTimeInterval(0.01667,target: self,selector: #selector(ViewController.timerCallback),userInfo: nil,repeats: true)
    }
    func webViewDidFinishLoad(webView: UIWebView) {
        activityIndicator.stopAnimating()
        theBool = true
    }
}
5
ZAFAR007

誰かがSwift 3でそれをやりたいなら、私はそれを理解しようとして数日を費やし、最終的にやりました。

ここにコードがあります:)

override func viewDidLoad() {
    super.viewDidLoad()

    let url = NSURL(string: "http://google.com")
    let request = NSURLRequest(url: url as! URL)
    webView.loadRequest(request as URLRequest)
    webView.delegate=self

}

func webViewDidStartLoad(_ webView: UIWebView) {

    self.progressView.setProgress(0.1, animated: false)
}


func webViewDidFinishLoad(_ webView: UIWebView) {

    self.progressView.setProgress(1.0, animated: true)
}

func webView(_ webView: UIWebView, didFailLoadWithError error: Error) {

    self.progressView.setProgress(1.0, animated: true)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
3
Matej Marić

Wolflinkの答えに従いましたが、progressViewがアニメーション化されていないのと同じ問題が見つかりました。

NSTimerクラスリファレンスを読んだ後:

https://developer.Apple.com/library/Mac/documentation/Cocoa/Reference/Foundation/Classes/NSTimer_Class/Reference/NSTimer.html#//Apple_ref/occ/clm/NSTimer/timerWithTimeInterval:target: selector:userInfo:repeats

Discussionでは、「addTimer:forMode:を使用して、実行ループに新しいタイマーを追加する必要があります。」

だから私は追加しました

_[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];_

myTimer = [NSTimer timerWithTimeInterval:0.01667 target:self selector:@selector(timerCallback) userInfo:nil repeats:YES];

それは私のために働いた(WolfLinkが推奨したように、サブクラスUIProgressViewをした)

3
danihvilla

サイトによってロードされたすべてのリソースを追跡する必要があるため、困難です(可能な場合でも)が…

アイデアが1つあります。実際のソリューションよりもトリックの方が多いですが、Appleはメッセージアプリでこれを使用しています:)

  1. ページの読み込みを開始すると、アニメーションを90%に開始進行状況(1.5秒の長さで、Wi-Fi、LTE、3Gなどで異なる場合があります)。
  2. その間にページが読み込まれると、進行状況を100%にすばやくアニメーション化します。できた!
  3. ページの読み込みに時間がかかる場合、進行状況バー90%で停止し、そこで待機します。ユーザーがステータスバーでゆっくり回転するインジケーターを見るときのイライラする瞬間!そして最後に、ページの読み込みが完了し、(箇条書き2のように)アニメーションを100%に高速化を再生します。できた!

SMSはこのような正確な進捗状況で追跡できるとは思わないからです)

2
Tricertops

答えを追加するのではなく、コメントを追加したはずですが、コメントするほどの評判はまだありません!

ほんの数日前、私はほぼ同じ質問をしました。その質問に、私が思いついた解決策を含めました。私のソリューションはWolfLinkよりも複雑ですが、100%正確ではありませんが、ページの読み込みの実際の進行状況を追跡します。 WolfLinkが言ったように、それは不可能です。私の質問はここにあります: IWebViewの進行状況バー

どちらの方法でも、UIWebViewの読み込みプロパティを確認して、ページの読み込みがいつ完了するかを確認する必要があります。

0
Stuart Fisher

次のパターンを試しました。少し良い結果が得られました。 WKWebviewを使用しています。

@IBOutlet weak var progressView: UIProgressView! // added in storyboard
@IBOutlet weak var webView: WKWebView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        setupEstimatedProgressObserver()
    }

    // Observe the WebViewClient for estimatedProgress value
    private func setupEstimatedProgressObserver() {
        estimatedProgressObserver = webView.observe(\.estimatedProgress, options: [.new]) { [weak self] webView, _ in
            self?.progressView.progress = Float(webView.estimatedProgress)
        }
    }

    //When WebView load finished in WKNavigationDelegate in didFinish method we will use the following approach
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.progressView.progress =  1.0
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            // your code here
             self.progressView.isHidden = true
        }
    }
0
Bidhan Roy

Appleは現在、WebKitフレームワークを提供しています。これには、プロパティ「estimatedProgress」を使用して推定進行状況を照会できるWKWebViewクラスが含まれているため、UIWebViewに進行状況バーを表示するように進行状況を「偽造」する必要がなくなりました。

0