こんにちは私はプログラミングが初めてで、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/"]]];
ご協力いただきありがとうございます!
正確なUIProgressView
を使用するには、次のタスクが必要です。
UIWebView
を読み込んでいるとき、それは不可能です。そして、Appleもそれをしません。 Appleは、偽のUIProgressView
sをよく使用して、ページの読み込み中に見たいものを提供します。メールも偽の進行状況ビューを使用します。自分で試してみてください。これが、Appleの偽の進行状況ビューの仕組みです。
これを実現するには、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ステートメントの値を変更して、アニメーションの速度を制御します。
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
}
}
誰かが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.
}
Wolflinkの答えに従いましたが、progressViewがアニメーション化されていないのと同じ問題が見つかりました。
NSTimerクラスリファレンスを読んだ後:
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をした)
サイトによってロードされたすべてのリソースを追跡する必要があるため、困難です(可能な場合でも)が…
アイデアが1つあります。実際のソリューションよりもトリックの方が多いですが、Appleはメッセージアプリでこれを使用しています:)
SMSはこのような正確な進捗状況で追跡できるとは思わないからです)
答えを追加するのではなく、コメントを追加したはずですが、コメントするほどの評判はまだありません!
ほんの数日前、私はほぼ同じ質問をしました。その質問に、私が思いついた解決策を含めました。私のソリューションはWolfLinkよりも複雑ですが、100%正確ではありませんが、ページの読み込みの実際の進行状況を追跡します。 WolfLinkが言ったように、それは不可能です。私の質問はここにあります: IWebViewの進行状況バー
どちらの方法でも、UIWebViewの読み込みプロパティを確認して、ページの読み込みがいつ完了するかを確認する必要があります。
次のパターンを試しました。少し良い結果が得られました。 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
}
}
Appleは現在、WebKitフレームワークを提供しています。これには、プロパティ「estimatedProgress」を使用して推定進行状況を照会できるWKWebViewクラスが含まれているため、UIWebViewに進行状況バーを表示するように進行状況を「偽造」する必要がなくなりました。