2014-01-21 4 views
21

Привет, я новичок в программировании, и я пытаюсь сделать свое первое приложение для iPhone на Xcode. Мое приложение содержит кнопку, которая открывает UIWebView при нажатии и загружает домашнюю страницу. Теперь я также хочу добавить представление Progress View в WebView, как и Safari, что указывает на прогресс загрузки страницы. Как я могу это сделать?
Мой код до сих пор для загрузки URL в UIWebView:UIWebView with Progress Bar

.h

IBOutlet UIWebView *webView; 

.m

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

Спасибо за вашу помощь!

+0

Проверьте ответы здесь, чтобы получить лучшее решение относительно места, где вы поместите код для индикатора выполнения. Http://stackoverflow.com/questions/23966697/show-progress-bar-until-it-load-the-data -in-uiwebview-ios7 – Suhaib

ответ

67

Чтобы иметь точную UIProgressView, вам нужно иметь какую-то задачу, что:

  • Вы можете получить информацию, пока она не завершена
  • Количественно его «полнота» как процент на основе этой информации ,

Теперь, когда вы загружаете UIWebView, это невозможно. И Apple тоже этого не делает. Apple часто использует подделку UIProgressView s, чтобы дать вам возможность посмотреть, пока загружается страница. Почта также использует поддельные представления прогресса. Попробуйте сами. Это как подделка мнения о ходе работы компании Apple:

  • мнение прогресс начинает двигаться в медленном, с постоянной скоростью
  • Если задача завершается до завершения бара, он вдруг молниеносно по всей остальной до 100%, прежде чем исчезнуть
  • Если задача занимает много времени, представление прогресса остановится на уровне 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, чтобы контролировать скорость анимации.

+2

_ + 1_ Я не читал ваш ответ должным образом, прежде чем отправлять свою информацию, которая также предлагает фальшивый индикатор прогресса :) – Tricertops

+0

Благодарим за помощь. Но это не сработает для меня. Что я делаю не так? Я поместил Progress View в свой веб-просмотр и связал его с «IBOutlet». Теперь я вижу представление прогресса во время работы симулятора, но он не будет оживлять. – user3220034

+0

Когда я помещаю, например, 0,5 в поле «Прогресс» внутри Инспектора атрибутов «Прогресс», «Прогресс» будет начинаться с 0,5 и затем внезапно перейти в 0 без анимации. – user3220034

0

Я бы добавил комментарий, а не добавлял ответ, но у меня пока нет достаточной репутации, чтобы комментировать!

Только пару дней назад я задал почти тот же вопрос. В этом вопросе я включил решение, которое я придумал. Мое решение сложнее, чем WolfLink, но оно отслеживает реальный ход загрузки страницы, хотя это не на 100% точно. Как сказал WolfLink, это невозможно.Мой вопрос можно найти здесь: Progress bar for UIWebView

Обратите внимание, что, как бы вы это ни делали, вам нужно проверить свойство загрузки UIWebView, чтобы определить, когда будет завершена загрузка страницы.

+0

Спасибо. Я определенно не ожидал, что это будет так сложно: p – user3220034

2

Это трудно (если вообще возможно), так как вы должны отслеживать все ресурсы, загруженные на сайт, но ...

У меня есть одна идея. Это больше трюк, чем реальное решение, но я думаю, что даже Apple, использует это в Messages приложение :)

  1. При запуске процесса загрузки страницы начать анимацию до 90% прогресса (давайте скажем, с продолжительностью 1,5 секунды, может быть, отличается для Wi-Fi, LTE, 3G, ...).
  2. Когда страница загружается, то быстро оживляет ход до 100%. Готово!
  3. Если на страницу требуется больше времени для загрузки, индикатор выполнения остановится на 90% и будет ждать там. Разочарование момента, когда пользователь наблюдает за индикатором медленного вращения в строке состояния! И затем, наконец, загрузка страницы заканчивается и (как в марке 2.) вы играете быстрой анимации до 100%. Готово!

Я думаю, что мы все знаем, что это, как работает приложение Сообщения, так как я не верю, что отправка SMS можно отслеживать с помощью такого точного прогресса :)

3

я последовал за ответ Wolflink и нашел такую ​​же проблему не имея progressView анимированный.

После прочтения NSTimer класса Reference:

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:

В Обсуждение вы можете прочитать: "Вы должны добавить новый таймер цикла выполнения, используя ADDTimer: forMode :."

поэтому я добавил

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

после

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

Он работал для меня (как WolfLink рекомендовал я сделал подкласс UIProgressView)

+0

Спасибо, что заметили! Я хотел использовать '[NSTimer scheduletimerWithTimeInterval: 0.01667 target: self selector: @selector (timerCallback) userInfo: nil repeatts: YES];' который автоматически добавляет таймер в цикл запуска. – WolfLink

+0

Даже чище, я буду использовать этот путь. Я видел, что вы уже отредактировали свой ответ, поэтому @ user3220034 может пометить его как правильный. По крайней мере, это то, что я искал. – danihvilla

4

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 
    } 
} 
2

Если кто-то хочет сделать это в быстром 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. 
} 
0

Apple, в настоящее время обеспечивает основу WebKit, который включает в себя класс WKWebView, который позволяет запросить оценочный прогресс, используя свойство «estimatedProgress», так что вы больше не должны " fake ", как вы делаете, чтобы показать индикатор выполнения в UIWebView.