CYWebViewProgressView.m 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. //
  2. // CYWebViewProgressView.m
  3. // CYWebViewProgressView
  4. //
  5. // Created by Chen Yiliang on 2020/3/6.
  6. // Copyright © 2020 cyl. All rights reserved.
  7. //
  8. #import "CYWebViewProgressView.h"
  9. @interface CYWebViewProgressView ()
  10. @property (nonatomic, weak) WKWebView *webView;
  11. @end
  12. @implementation CYWebViewProgressView
  13. - (instancetype)initWithFrame:(CGRect)frame {
  14. self = [super initWithFrame:frame];
  15. if (self) {
  16. [self configureViews];
  17. }
  18. return self;
  19. }
  20. - (void)awakeFromNib {
  21. [super awakeFromNib];
  22. [self configureViews];
  23. }
  24. - (void)configureViews {
  25. self.userInteractionEnabled = NO;
  26. self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  27. _progressBarView = [[UIView alloc] initWithFrame:self.bounds];
  28. _progressBarView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
  29. UIColor *tintColor = [UIColor colorWithRed:22.f / 255.f green:126.f / 255.f blue:251.f / 255.f alpha:1.0]; // iOS7 Safari bar color
  30. _progressBarView.backgroundColor = tintColor;
  31. [self addSubview:_progressBarView];
  32. _barAnimationDuration = 0.27f;
  33. _fadeAnimationDuration = 0.27f;
  34. _fadeOutDelay = 0.1f;
  35. }
  36. - (void)setWebView:(WKWebView *)webView {
  37. if (_webView == webView) return;
  38. [_webView removeObserver:self forKeyPath:@"estimatedProgress"];
  39. _webView = webView;
  40. [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL];
  41. }
  42. - (void)setProgress:(double)progress {
  43. [self setProgress:progress animated:NO];
  44. }
  45. - (void)setProgress:(double)progress animated:(BOOL)animated {
  46. BOOL isGrowing = progress > 0.0;
  47. [UIView animateWithDuration:(isGrowing && animated) ? _barAnimationDuration : 0.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  48. CGRect frame = self.progressBarView.frame;
  49. frame.size.width = progress * self.bounds.size.width;
  50. self.progressBarView.frame = frame;
  51. } completion:nil];
  52. if (progress >= 1.0) {
  53. [UIView animateWithDuration:animated ? _fadeAnimationDuration : 0.0 delay:_fadeOutDelay options:UIViewAnimationOptionCurveEaseInOut animations:^{
  54. self.progressBarView.alpha = 0.0;
  55. } completion:^(BOOL completed){
  56. CGRect frame = self.progressBarView.frame;
  57. frame.size.width = 0;
  58. self.progressBarView.frame = frame;
  59. }];
  60. } else {
  61. [UIView animateWithDuration:animated ? _fadeAnimationDuration : 0.0 delay:0.0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
  62. self.progressBarView.alpha = 1.0;
  63. } completion:nil];
  64. }
  65. }
  66. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
  67. if ([keyPath isEqualToString:@"estimatedProgress"] && object == self.webView) {
  68. double progress = [[change valueForKey:NSKeyValueChangeNewKey] doubleValue];
  69. [self setProgress:progress animated:YES];
  70. } else {
  71. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  72. }
  73. }
  74. - (void)dealloc {
  75. [_webView removeObserver:self forKeyPath:@"estimatedProgress"];
  76. }
  77. @end
  78. @implementation WKWebView (CYWebViewProgressView)
  79. - (CYWebViewProgressView *)progressView {
  80. CYWebViewProgressView *progressView = nil;
  81. for (UIView *view in self.subviews) {
  82. if ([view isKindOfClass:[CYWebViewProgressView class]]) {
  83. progressView = (CYWebViewProgressView *)view;
  84. break;
  85. }
  86. }
  87. return progressView;
  88. }
  89. - (void)setProgressView:(CYWebViewProgressView *)progressView {
  90. [self addSubview:progressView];
  91. [progressView setWebView:self];
  92. }
  93. @end