线上所有马甲包模板,与《猎豆》同UI。域名zhuadd

SDPhotoBrowser.m 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. //
  2. // SDPhotoBrowser.m
  3. // photobrowser
  4. //
  5. // Created by aier on 15-2-3.
  6. // Copyright (c) 2015年 aier. All rights reserved.
  7. //
  8. #import "SDPhotoBrowser.h"
  9. #import "UIImageView+WebCache.h"
  10. #import "SDBrowserImageView.h"
  11. // ============在这里方便配置样式相关设置===========
  12. // ||
  13. // ||
  14. // ||
  15. // \\//
  16. // \/
  17. #import "SDPhotoBrowserConfig.h"
  18. // =============================================
  19. @implementation SDPhotoBrowser
  20. {
  21. UIScrollView *_scrollView;
  22. BOOL _hasShowedFistView;
  23. UILabel *_indexLabel;
  24. UIButton *_saveButton;
  25. UIActivityIndicatorView *_indicatorView;
  26. BOOL _willDisappear;
  27. }
  28. - (id)initWithFrame:(CGRect)frame
  29. {
  30. self = [super initWithFrame:frame];
  31. if (self) {
  32. self.backgroundColor = SDPhotoBrowserBackgrounColor;
  33. }
  34. return self;
  35. }
  36. - (void)didMoveToSuperview
  37. {
  38. [self setupScrollView];
  39. [self setupToolbars];
  40. }
  41. - (void)dealloc
  42. {
  43. [[UIApplication sharedApplication].keyWindow removeObserver:self forKeyPath:@"frame"];
  44. }
  45. - (void)setupToolbars
  46. {
  47. // 1. 序标
  48. UILabel *indexLabel = [[UILabel alloc] init];
  49. indexLabel.bounds = CGRectMake(0, 0, 80, 30);
  50. indexLabel.textAlignment = NSTextAlignmentCenter;
  51. indexLabel.textColor = [UIColor whiteColor];
  52. indexLabel.font = [UIFont boldSystemFontOfSize:20];
  53. indexLabel.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
  54. indexLabel.layer.cornerRadius = indexLabel.bounds.size.height * 0.5;
  55. indexLabel.clipsToBounds = YES;
  56. if (self.imageCount > 1) {
  57. indexLabel.text = [NSString stringWithFormat:@"1/%ld", (long)self.imageCount];
  58. }else {
  59. indexLabel.hidden = YES;
  60. }
  61. _indexLabel = indexLabel;
  62. [self addSubview:indexLabel];
  63. // 2.保存按钮
  64. UIButton *saveButton = [[UIButton alloc] init];
  65. [saveButton setTitle:@"保存" forState:UIControlStateNormal];
  66. [saveButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
  67. saveButton.backgroundColor = [UIColor colorWithRed:0.1f green:0.1f blue:0.1f alpha:0.90f];
  68. saveButton.layer.cornerRadius = 5;
  69. saveButton.clipsToBounds = YES;
  70. [saveButton addTarget:self action:@selector(saveImage) forControlEvents:UIControlEventTouchUpInside];
  71. _saveButton = saveButton;
  72. [self addSubview:saveButton];
  73. }
  74. - (void)saveImage
  75. {
  76. int index = _scrollView.contentOffset.x / _scrollView.bounds.size.width;
  77. UIImageView *currentImageView = _scrollView.subviews[index];
  78. UIImageWriteToSavedPhotosAlbum(currentImageView.image, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL);
  79. UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] init];
  80. indicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge;
  81. indicator.center = self.center;
  82. _indicatorView = indicator;
  83. [[UIApplication sharedApplication].keyWindow addSubview:indicator];
  84. [indicator startAnimating];
  85. }
  86. - (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo;
  87. {
  88. [_indicatorView removeFromSuperview];
  89. UILabel *label = [[UILabel alloc] init];
  90. label.textColor = [UIColor whiteColor];
  91. label.backgroundColor = [UIColor colorWithRed:0.1f green:0.1f blue:0.1f alpha:0.90f];
  92. label.layer.cornerRadius = 5;
  93. label.clipsToBounds = YES;
  94. label.bounds = CGRectMake(0, 0, 150, 30);
  95. label.center = self.center;
  96. label.textAlignment = NSTextAlignmentCenter;
  97. label.font = [UIFont boldSystemFontOfSize:17];
  98. [[UIApplication sharedApplication].keyWindow addSubview:label];
  99. [[UIApplication sharedApplication].keyWindow bringSubviewToFront:label];
  100. if (error) {
  101. label.text = SDPhotoBrowserSaveImageFailText;
  102. } else {
  103. label.text = SDPhotoBrowserSaveImageSuccessText;
  104. }
  105. [label performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.0];
  106. }
  107. - (void)setupScrollView
  108. {
  109. _scrollView = [[UIScrollView alloc] init];
  110. _scrollView.delegate = self;
  111. _scrollView.showsHorizontalScrollIndicator = NO;
  112. _scrollView.showsVerticalScrollIndicator = NO;
  113. _scrollView.pagingEnabled = YES;
  114. [self addSubview:_scrollView];
  115. for (int i = 0; i < self.imageCount; i++) {
  116. SDBrowserImageView *imageView = [[SDBrowserImageView alloc] init];
  117. imageView.tag = i;
  118. // 单击图片
  119. UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(photoClick:)];
  120. // 双击放大图片
  121. UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageViewDoubleTaped:)];
  122. doubleTap.numberOfTapsRequired = 2;
  123. [self addGestureRecognizer:doubleTap];
  124. [singleTap requireGestureRecognizerToFail:doubleTap];
  125. [imageView addGestureRecognizer:singleTap];
  126. [imageView addGestureRecognizer:doubleTap];
  127. [_scrollView addSubview:imageView];
  128. }
  129. [self setupImageOfImageViewForIndex:self.currentImageIndex];
  130. }
  131. // 加载图片
  132. - (void)setupImageOfImageViewForIndex:(NSInteger)index
  133. {
  134. SDBrowserImageView *imageView = _scrollView.subviews[index];
  135. self.currentImageIndex = index;
  136. if (imageView.hasLoadedImage) return;
  137. if ([self highQualityImageURLForIndex:index]) {
  138. [imageView setImageWithURL:[self highQualityImageURLForIndex:index] placeholderImage:[self placeholderImageForIndex:index]];
  139. } else {
  140. imageView.image = [self placeholderImageForIndex:index];
  141. }
  142. imageView.hasLoadedImage = YES;
  143. }
  144. - (void)photoClick:(UITapGestureRecognizer *)recognizer
  145. {
  146. _scrollView.hidden = YES;
  147. _willDisappear = YES;
  148. SDBrowserImageView *currentImageView = (SDBrowserImageView *)recognizer.view;
  149. NSInteger currentIndex = currentImageView.tag;
  150. UIView *sourceView = self.sourceImagesContainerView.subviews[currentIndex];
  151. CGRect targetTemp = [self.sourceImagesContainerView convertRect:sourceView.frame toView:self];
  152. UIImageView *tempView = [[UIImageView alloc] init];
  153. tempView.contentMode = sourceView.contentMode;
  154. tempView.clipsToBounds = YES;
  155. tempView.image = currentImageView.image;
  156. CGFloat h = (self.bounds.size.width / currentImageView.image.size.width) * currentImageView.image.size.height;
  157. if (!currentImageView.image) { // 防止 因imageview的image加载失败 导致 崩溃
  158. h = self.bounds.size.height;
  159. }
  160. tempView.bounds = CGRectMake(0, 0, self.bounds.size.width, h);
  161. tempView.center = self.center;
  162. [self addSubview:tempView];
  163. _saveButton.hidden = YES;
  164. [UIView animateWithDuration:SDPhotoBrowserHideImageAnimationDuration animations:^{
  165. tempView.frame = targetTemp;
  166. self.backgroundColor = [UIColor clearColor];
  167. _indexLabel.alpha = 0.1;
  168. } completion:^(BOOL finished) {
  169. [self removeFromSuperview];
  170. }];
  171. }
  172. - (void)imageViewDoubleTaped:(UITapGestureRecognizer *)recognizer
  173. {
  174. SDBrowserImageView *imageView = (SDBrowserImageView *)recognizer.view;
  175. CGFloat scale;
  176. if (imageView.isScaled) {
  177. scale = 1.0;
  178. } else {
  179. scale = 2.0;
  180. }
  181. SDBrowserImageView *view = (SDBrowserImageView *)recognizer.view;
  182. [view doubleTapToZommWithScale:scale];
  183. }
  184. - (void)layoutSubviews
  185. {
  186. [super layoutSubviews];
  187. CGRect rect = self.bounds;
  188. rect.size.width += SDPhotoBrowserImageViewMargin * 2;
  189. _scrollView.bounds = rect;
  190. _scrollView.center = self.center;
  191. CGFloat y = 0;
  192. CGFloat w = _scrollView.frame.size.width - SDPhotoBrowserImageViewMargin * 2;
  193. CGFloat h = _scrollView.frame.size.height;
  194. [_scrollView.subviews enumerateObjectsUsingBlock:^(SDBrowserImageView *obj, NSUInteger idx, BOOL *stop) {
  195. CGFloat x = SDPhotoBrowserImageViewMargin + idx * (SDPhotoBrowserImageViewMargin * 2 + w);
  196. obj.frame = CGRectMake(x, y, w, h);
  197. }];
  198. _scrollView.contentSize = CGSizeMake(_scrollView.subviews.count * _scrollView.frame.size.width, 0);
  199. _scrollView.contentOffset = CGPointMake(self.currentImageIndex * _scrollView.frame.size.width, 0);
  200. if (!_hasShowedFistView) {
  201. [self showFirstImage];
  202. }
  203. _indexLabel.center = CGPointMake(self.bounds.size.width * 0.5, 45);
  204. _saveButton.frame = CGRectMake(30, self.bounds.size.height - 70, 50, 25);
  205. }
  206. - (void)show
  207. {
  208. UIWindow *window = [UIApplication sharedApplication].keyWindow;
  209. self.frame = window.bounds;
  210. [window addObserver:self forKeyPath:@"frame" options:0 context:nil];
  211. [window addSubview:self];
  212. }
  213. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(UIView *)object change:(NSDictionary *)change context:(void *)context
  214. {
  215. if ([keyPath isEqualToString:@"frame"]) {
  216. self.frame = object.bounds;
  217. SDBrowserImageView *currentImageView = _scrollView.subviews[_currentImageIndex];
  218. if ([currentImageView isKindOfClass:[SDBrowserImageView class]]) {
  219. [currentImageView clear];
  220. }
  221. }
  222. }
  223. - (void)showFirstImage
  224. {
  225. UIView *sourceView = self.sourceImagesContainerView.subviews[self.currentImageIndex];
  226. CGRect rect = [self.sourceImagesContainerView convertRect:sourceView.frame toView:self];
  227. UIImageView *tempView = [[UIImageView alloc] init];
  228. tempView.image = [self placeholderImageForIndex:self.currentImageIndex];
  229. [self addSubview:tempView];
  230. CGRect targetTemp = [_scrollView.subviews[self.currentImageIndex] bounds];
  231. tempView.frame = rect;
  232. tempView.contentMode = [_scrollView.subviews[self.currentImageIndex] contentMode];
  233. _scrollView.hidden = YES;
  234. [UIView animateWithDuration:SDPhotoBrowserShowImageAnimationDuration animations:^{
  235. tempView.center = self.center;
  236. tempView.bounds = (CGRect){CGPointZero, targetTemp.size};
  237. } completion:^(BOOL finished) {
  238. _hasShowedFistView = YES;
  239. [tempView removeFromSuperview];
  240. _scrollView.hidden = NO;
  241. }];
  242. }
  243. - (UIImage *)placeholderImageForIndex:(NSInteger)index
  244. {
  245. if ([self.delegate respondsToSelector:@selector(photoBrowser:placeholderImageForIndex:)]) {
  246. return [self.delegate photoBrowser:self placeholderImageForIndex:index];
  247. }
  248. return nil;
  249. }
  250. - (NSURL *)highQualityImageURLForIndex:(NSInteger)index
  251. {
  252. if ([self.delegate respondsToSelector:@selector(photoBrowser:highQualityImageURLForIndex:)]) {
  253. return [self.delegate photoBrowser:self highQualityImageURLForIndex:index];
  254. }
  255. return nil;
  256. }
  257. #pragma mark - scrollview代理方法
  258. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  259. {
  260. int index = (scrollView.contentOffset.x + _scrollView.bounds.size.width * 0.5) / _scrollView.bounds.size.width;
  261. // 有过缩放的图片在拖动一定距离后清除缩放
  262. CGFloat margin = 150;
  263. CGFloat x = scrollView.contentOffset.x;
  264. if ((x - index * self.bounds.size.width) > margin || (x - index * self.bounds.size.width) < - margin) {
  265. SDBrowserImageView *imageView = _scrollView.subviews[index];
  266. if (imageView.isScaled) {
  267. [UIView animateWithDuration:0.5 animations:^{
  268. imageView.transform = CGAffineTransformIdentity;
  269. } completion:^(BOOL finished) {
  270. [imageView eliminateScale];
  271. }];
  272. }
  273. }
  274. if (!_willDisappear) {
  275. _indexLabel.text = [NSString stringWithFormat:@"%d/%ld", index + 1, (long)self.imageCount];
  276. }
  277. [self setupImageOfImageViewForIndex:index];
  278. }
  279. @end
  280. // 版权属于原作者
  281. // http://code4app.com (cn) http://code4app.net (en)
  282. // 发布代码于最专业的源码分享网站: Code4App.com