PKDownloadButton.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. //
  2. // PKDownloadButton.m
  3. // PKDownloadButton
  4. //
  5. // Created by Pavel on 28/05/15.
  6. // Copyright (c) 2015 Katunin. All rights reserved.
  7. //
  8. #import "PKDownloadButton.h"
  9. #import "PKMacros.h"
  10. #import "NSLayoutConstraint+PKDownloadButton.h"
  11. #import "UIImage+PKDownloadButton.h"
  12. #import "PKPendingView.h"
  13. @interface PKDownloadButton ()
  14. @property (nonatomic, weak) PKBorderedButton *startDownloadButton;
  15. @property (nonatomic, weak) PKStopDownloadButton *stopDownloadButton;
  16. @property (nonatomic, weak) PKBorderedButton *downloadedButton;
  17. @property (nonatomic, weak) PKPendingView *pendingView;
  18. @property (nonatomic, strong) NSMutableArray *stateViews;
  19. - (PKBorderedButton *)createStartDownloadButton;
  20. - (PKStopDownloadButton *)createStopDownloadButton;
  21. - (PKBorderedButton *)createDownloadedButton;
  22. - (PKPendingView *)createPendingView;
  23. - (void)currentButtonTapped:(id)sender;
  24. - (void)createSubviews;
  25. - (NSArray *)createConstraints;
  26. @end
  27. static PKDownloadButton *CommonInit(PKDownloadButton *self) {
  28. if (self != nil) {
  29. [self createSubviews];
  30. [self addConstraints:[self createConstraints]];
  31. self.state = kPKDownloadButtonState_StartDownload;
  32. self.backgroundColor = [UIColor clearColor];
  33. }
  34. return self;
  35. }
  36. @implementation PKDownloadButton
  37. #pragma mark - Properties
  38. - (void)setState:(PKDownloadButtonState)state {
  39. _state = state;
  40. [self.stateViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  41. SafeObjClassCast(UIView, view, obj);
  42. view.hidden = YES;
  43. }];
  44. switch (state) {
  45. case kPKDownloadButtonState_StartDownload:
  46. self.startDownloadButton.hidden = NO;
  47. break;
  48. case kPKDownloadButtonState_Pending:
  49. self.pendingView.hidden = NO;
  50. [self.pendingView startSpin];
  51. break;
  52. case kPKDownloadButtonState_Downloading:
  53. self.stopDownloadButton.hidden = NO;
  54. self.stopDownloadButton.progress = 0.f;
  55. break;
  56. case kPKDownloadButtonState_Downloaded:
  57. self.downloadedButton.hidden = NO;
  58. break;
  59. default:
  60. NSAssert(NO, @"unsupported state");
  61. break;
  62. }
  63. }
  64. #pragma mark - Initialization
  65. - (id)initWithCoder:(NSCoder *)decoder {
  66. return CommonInit([super initWithCoder:decoder]);
  67. }
  68. - (instancetype)initWithFrame:(CGRect)frame {
  69. return CommonInit([super initWithFrame:frame]);
  70. }
  71. - (void)tintColorDidChange {
  72. [super tintColorDidChange];
  73. [self updateButton:self.startDownloadButton title:[self.startDownloadButton titleForState:UIControlStateNormal] font:self.startDownloadButton.titleLabel.font];
  74. [self updateButton:self.downloadedButton title:[self.downloadedButton titleForState:UIControlStateNormal] font:self.downloadedButton.titleLabel.font];
  75. }
  76. #pragma mark - appearance
  77. -(void)updateStartDownloadButtonText:(NSString *)title {
  78. [self updateButton:self.startDownloadButton title:title];
  79. }
  80. -(void)updateDownloadedButtonText:(NSString *)title {
  81. [self updateButton:self.downloadedButton title:title];
  82. }
  83. -(void)updateStartDownloadButtonText:(NSString *)title font:(UIFont *)font {
  84. [self updateButton:self.startDownloadButton title:title font: font];
  85. }
  86. -(void)updateDownloadedButtonText:(NSString *)title font:(UIFont *)font {
  87. [self updateButton:self.downloadedButton title:title font: font];
  88. }
  89. - (void)updateButton:(UIButton *)button title:(NSString *)title {
  90. [self updateButton:button title:title font:[UIFont systemFontOfSize:14.f]];
  91. }
  92. - (void)updateButton:(UIButton *)button title:(NSString *)title font:(UIFont *)font {
  93. if (title == nil) {
  94. title = @"";
  95. }
  96. [button setTitle:title forState:UIControlStateNormal];
  97. [button setTitleColor:self.tintColor forState:UIControlStateNormal];
  98. [button setTitleColor:UIColor.whiteColor forState:UIControlStateHighlighted];
  99. button.titleLabel.font = font;
  100. }
  101. #pragma mark - private methods
  102. - (PKBorderedButton *)createStartDownloadButton {
  103. PKBorderedButton *startDownloadButton = [PKBorderedButton buttonWithType:UIButtonTypeCustom];
  104. [startDownloadButton configureDefaultAppearance];
  105. [self updateButton:startDownloadButton title:@"DOWNLOAD"];
  106. [startDownloadButton addTarget:self
  107. action:@selector(currentButtonTapped:)
  108. forControlEvents:UIControlEventTouchUpInside];
  109. return startDownloadButton;
  110. }
  111. - (PKStopDownloadButton *)createStopDownloadButton {
  112. PKStopDownloadButton *stopDownloadButton = [[PKStopDownloadButton alloc] init];
  113. [stopDownloadButton.stopButton addTarget:self action:@selector(currentButtonTapped:)
  114. forControlEvents:UIControlEventTouchUpInside];
  115. return stopDownloadButton;
  116. }
  117. - (PKBorderedButton *)createDownloadedButton {
  118. PKBorderedButton *downloadedButton = [PKBorderedButton buttonWithType:UIButtonTypeCustom];
  119. [downloadedButton configureDefaultAppearance];
  120. [self updateButton:downloadedButton title:@"REMOVE"];
  121. [downloadedButton addTarget:self
  122. action:@selector(currentButtonTapped:)
  123. forControlEvents:UIControlEventTouchUpInside];
  124. return downloadedButton;
  125. }
  126. - (PKPendingView *)createPendingView {
  127. PKPendingView *pendingView = [[PKPendingView alloc] init];
  128. [pendingView addTarget:self action:@selector(currentButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
  129. return pendingView;
  130. }
  131. - (void)currentButtonTapped:(id)sender {
  132. [self.delegate downloadButtonTapped:self currentState:self.state];
  133. BlockSafeRun(self.callback, self, self.state);
  134. }
  135. - (void)createSubviews {
  136. self.stateViews = (__bridge_transfer NSMutableArray *)CFArrayCreateMutable(nil, 0, nil);
  137. PKBorderedButton *startDownloadButton = [self createStartDownloadButton];
  138. startDownloadButton.translatesAutoresizingMaskIntoConstraints = NO;
  139. [self addSubview:startDownloadButton];
  140. self.startDownloadButton = startDownloadButton;
  141. [self.stateViews addObject:startDownloadButton];
  142. PKStopDownloadButton *stopDownloadButton = [self createStopDownloadButton];
  143. stopDownloadButton.translatesAutoresizingMaskIntoConstraints = NO;
  144. [self addSubview:stopDownloadButton];
  145. self.stopDownloadButton = stopDownloadButton;
  146. [self.stateViews addObject:stopDownloadButton];
  147. PKBorderedButton *downloadedButton = [self createDownloadedButton];
  148. downloadedButton.translatesAutoresizingMaskIntoConstraints = NO;
  149. [self addSubview:downloadedButton];
  150. self.downloadedButton = downloadedButton;
  151. [self.stateViews addObject:downloadedButton];
  152. PKPendingView *pendingView = [self createPendingView];
  153. pendingView.translatesAutoresizingMaskIntoConstraints = NO;
  154. [self addSubview:pendingView];
  155. self.pendingView = pendingView;
  156. [self.stateViews addObject:pendingView];
  157. }
  158. - (NSArray *)createConstraints {
  159. NSMutableArray *constraints = [NSMutableArray array];
  160. [self.stateViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  161. SafeObjClassCast(UIView, view, obj);
  162. [constraints addObjectsFromArray:[NSLayoutConstraint constraintsForWrappedSubview:view
  163. withInsets:UIEdgeInsetsZero]];
  164. }];
  165. return constraints;
  166. }
  167. @end