HBImageScroller.m 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. //
  2. // HBImageScroller.m
  3. // MyTest
  4. //
  5. // Created by weqia on 13-7-31.
  6. // Copyright (c) 2013年 weqia. All rights reserved.
  7. //
  8. #import "HBImageScroller.h"
  9. #import "HBHttpRequestCache.h"
  10. #import "DialogUtil.h"
  11. #import "HBHttpImageDownloader.h"
  12. #import "JXActionSheetVC.h"
  13. @interface HBImageScroller () <JXActionSheetVCDelegate, UIScrollViewDelegate>
  14. @property (nonatomic, strong) JXActionSheetVC *actionVC;
  15. @end
  16. @implementation HBImageScroller
  17. @synthesize imageView=_imageView,controller;
  18. #pragma -mark 覆盖父类的方法
  19. #pragma -mark 事件响应方法
  20. -(void)longPressAction:(UIGestureRecognizer*)sender
  21. {
  22. if(sender.state==UIGestureRecognizerStateBegan){
  23. if(self.controller){
  24. self.actionVC = [[JXActionSheetVC alloc] initWithImages:@[] names:@[Localized(@"HBImageScroller_SavePhone"),Localized(@"HBImageScroller_ShareTo")]];
  25. self.actionVC.delegate = self;
  26. [g_App.window addSubview:self.actionVC.view];
  27. }else{
  28. self.actionVC = [[JXActionSheetVC alloc] initWithImages:@[] names:@[Localized(@"HBImageScroller_SavePhone")]];
  29. self.actionVC.delegate = self;
  30. [g_App.window addSubview:self.actionVC.view];
  31. }
  32. }
  33. }
  34. /**scroll view处理缩放和平移手势,必须需要实现委托下面两个方法,另外 maximumZoomScale和minimumZoomScale两个属性要不一样*/
  35. //1.返回要缩放的图片
  36. -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
  37. return self.imageView;
  38. }
  39. //让图片保持在屏幕中央,防止图片放大时,位置出现跑偏
  40. - (void)scrollViewDidZoom:(UIScrollView *)scrollView{
  41. CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width)?(scrollView.bounds.size.width - scrollView.contentSize.width) * 0.5 : 0.0;
  42. CGFloat offsetY = (scrollView.bounds.size.height > scrollView.contentSize.height)?
  43. (scrollView.bounds.size.height - scrollView.contentSize.height) * 0.5 : 0.0;
  44. self.imageView.center = CGPointMake(scrollView.contentSize.width * 0.5 + offsetX,scrollView.contentSize.height * 0.5 + offsetY);
  45. }
  46. //2.重新确定缩放完后的缩放倍数
  47. -(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
  48. [scrollView setZoomScale:scale+0.01 animated:NO];
  49. [scrollView setZoomScale:scale animated:NO];
  50. }
  51. //-(void)imagePinchAction:(UIPinchGestureRecognizer*)recognizer
  52. //{
  53. // if(recognizer.state==UIGestureRecognizerStateBegan)
  54. // {
  55. // _beginSize=_imageView.frame.size;
  56. // }
  57. // else if(recognizer.state==UIGestureRecognizerStateChanged)
  58. // {
  59. // int width= _beginSize.width*recognizer.scale;
  60. // int height=_imgScale*width;
  61. // if(width<_scale*1.5*_beginImageSize.width&&width>0.5*_beginImageSize.width)
  62. // {
  63. // CGSize size=CGSizeMake(width, height);
  64. // if (size.height<self.frame.size.height) {
  65. // size.height=self.frame.size.height;
  66. // }
  67. // if (size.width<self.frame.size.width) {
  68. // size.width=self.frame.size.width;
  69. // }
  70. // self.contentSize=size;
  71. // float x=0,y=0;
  72. //// if (width<self.frame.size.width) {
  73. // x=(self.frame.size.width-width)/2;
  74. //// }
  75. //// if (height<self.frame.size.height) {
  76. // y=(self.frame.size.height-height)/2;
  77. //// }
  78. // _imageView.frame=CGRectMake(x,y , width, height);
  79. //
  80. // }
  81. // }
  82. // else if(recognizer.state==UIGestureRecognizerStateEnded)
  83. // {
  84. // if(_imageView.frame.size.width<_beginImageSize.width)
  85. // {
  86. // [UIView beginAnimations:nil context:NULL];
  87. // [UIView setAnimationDuration:0.2];
  88. // [self setImageFrameAndContentSize];
  89. // self.contentSize=self.frame.size;
  90. // [UIView commitAnimations];
  91. // max=NO;
  92. // }
  93. // else if(_imageView.frame.size.width>_scale*_beginImageSize.width)
  94. // {
  95. // [UIView beginAnimations:nil context:NULL];
  96. // [UIView setAnimationDuration:0.2];
  97. // CGSize size=self.contentSize;
  98. // size.width=_beginImageSize.width*_scale;
  99. // size.height=_imgScale*size.width;
  100. // if (size.height<self.frame.size.height) {
  101. // size.height=self.frame.size.height;
  102. // }
  103. // if (size.width<self.frame.size.width) {
  104. // size.width=self.frame.size.width;
  105. // }
  106. // float x=(self.frame.size.width-size.width)/2,y=(self.frame.size.height-size.height)/2;
  107. // self.contentOffset = CGPointMake(-x, -y);
  108. // self.contentSize=size;
  109. // _imageView.frame= CGRectMake(0, 0, size.width, size.height);
  110. // [UIView commitAnimations];
  111. // max=YES;
  112. // }
  113. //
  114. // }
  115. //}
  116. -(void)imageTapTwoAction:(UIGestureRecognizer*)recognizer
  117. {
  118. if(max)
  119. {
  120. [UIView beginAnimations:nil context:NULL];
  121. [UIView setAnimationDuration:0.2];
  122. [self setImageFrameAndContentSize];
  123. self.contentSize=self.frame.size;
  124. [UIView commitAnimations];
  125. max=NO;
  126. }else{
  127. [UIView beginAnimations:nil context:NULL];
  128. [UIView setAnimationDuration:0.2];
  129. CGSize size=self.contentSize;
  130. size.width=_beginImageSize.width*_scale;
  131. size.height=_imgScale*size.width;
  132. float x=0,y=0;
  133. if (size.height<self.frame.size.height) {
  134. y=(self.frame.size.height-size.height)/2;
  135. size.height=self.frame.size.height;
  136. }
  137. if (size.width<self.frame.size.width) {
  138. x=(self.frame.size.width-size.width)/2;
  139. size.width=self.frame.size.width;
  140. }
  141. self.contentSize=size;
  142. _imageView.frame= CGRectMake(x, y, size.width, size.height);
  143. LocationRegion region=[self getLocationRegion:[recognizer locationInView:self]];
  144. switch (region) {
  145. case RegionTopLeft:
  146. break;
  147. case RegionBottomLeft:
  148. [self scrollRectToVisible:CGRectMake(0, self.contentSize.height-self.frame.size.height, self.frame.size.width, self.frame.size.height) animated:NO];
  149. break;
  150. case RegionTopRight:
  151. [self scrollRectToVisible:CGRectMake(self.contentSize.width-self.frame.size.width, 0, self.frame.size.width, self.frame.size.height) animated:NO];
  152. break;
  153. case RegionBottomRight:
  154. [self scrollRectToVisible:CGRectMake(self.contentSize.width-self.frame.size.width, self.contentSize.height-self.frame.size.height, self.frame.size.width, self.frame.size.height) animated:NO];
  155. break;
  156. default:
  157. break;
  158. }
  159. [UIView commitAnimations];
  160. max=YES;
  161. }
  162. }
  163. -(void)imageTapOnceAction:(UIGestureRecognizer*)recognizer
  164. {
  165. if(_tapOnceAction&&_target&&[_target respondsToSelector:_tapOnceAction])
  166. #pragma clang diagnostic push
  167. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  168. [_target performSelector:_tapOnceAction withObject:_imageView];
  169. #pragma clang diagnostic pop
  170. }
  171. #pragma -mark 回调方法
  172. - (void)actionSheet:(JXActionSheetVC *)actionSheet didButtonWithIndex:(NSInteger)index {
  173. if(index==0){
  174. UIImageWriteToSavedPhotosAlbum(_imageView.image, self,@selector(image:didFinishSavingWithError:contextInfo:), NULL);
  175. }else if(index==1){
  176. }
  177. }
  178. -(void)image: (UIImage *) image didFinishSavingWithError: (NSError *) error contextInfo: (void *) contextInfo
  179. {
  180. if(error){
  181. [[DialogUtil sharedInstance] showDlg:self textOnly:Localized(@"JX_SaveFiled")];
  182. }else{
  183. [[DialogUtil sharedInstance] showDlg:self textOnly:Localized(@"JX_SaveSuessed")];
  184. }
  185. }
  186. #pragma -mark 私有方法
  187. -(CGRect)getFrameForImageView
  188. {
  189. CGSize size=_imageView.image.size;
  190. CGRect rect=self.frame;
  191. CGRect frame;
  192. float imgScale=size.height/size.width;
  193. float viewScale=rect.size.height/rect.size.width;
  194. float width=size.width,height=size.height;
  195. if(imgScale<viewScale&&size.width>rect.size.width){
  196. width=rect.size.width;
  197. height=width*imgScale;
  198. _scale=rect.size.height/height;
  199. }else if(imgScale>=viewScale&&size.height>rect.size.height){
  200. height=rect.size.height;
  201. width=height/imgScale;
  202. _scale=rect.size.width/width;
  203. }else{
  204. _scale=rect.size.width/width;
  205. }
  206. float x=0,y=0;
  207. if (width<rect.size.width) {
  208. x=(rect.size.width-width)/2;
  209. }if(height<rect.size.height){
  210. y=(rect.size.height-height)/2;
  211. }
  212. frame=CGRectMake(x, y, width, height);
  213. return frame;
  214. }
  215. -(void)setImageFrameAndContentSize
  216. {
  217. CGRect frame=[self getFrameForImageView];
  218. _imageView.frame=frame;
  219. _beginImageSize=_imageView.frame.size;
  220. _imgScale=_imageView.image.size.height/_imageView.image.size.width;
  221. self.contentSize=self.frame.size;
  222. }
  223. -(LocationRegion)getLocationRegion:(CGPoint)point
  224. {
  225. float width=self.frame.size.width;
  226. float height=self.frame.size.height;
  227. if(point.x<width/2)
  228. {
  229. if(point.y<height/2)
  230. return RegionTopLeft;
  231. else
  232. return RegionBottomLeft;
  233. }
  234. else
  235. {
  236. if(point.y<height/2)
  237. return RegionTopRight;
  238. else
  239. return RegionBottomRight;
  240. }
  241. }
  242. #pragma -mark 接口方法
  243. -(id)initWithFrame:(CGRect)frame
  244. {
  245. self= [super initWithFrame:frame];
  246. if(self)
  247. {
  248. _imageView=[[UIImageView alloc]initWithFrame:self.bounds];
  249. [self addSubview:_imageView];
  250. UITapGestureRecognizer * tapOnce=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageTapOnceAction:)];
  251. tapOnce.numberOfTapsRequired=1;
  252. tapOnce.numberOfTouchesRequired=1;
  253. [self addGestureRecognizer:tapOnce];
  254. _imageView.userInteractionEnabled=YES;
  255. UITapGestureRecognizer* tapTwo=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageTapTwoAction:)];
  256. tapTwo.numberOfTapsRequired=2;
  257. tapTwo.numberOfTouchesRequired=1;
  258. [tapOnce requireGestureRecognizerToFail:tapTwo];
  259. [_imageView addGestureRecognizer:tapTwo];
  260. // UIPinchGestureRecognizer * pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(imagePinchAction:)];
  261. // [_imageView addGestureRecognizer:pinch];
  262. self.delegate = self;
  263. self.minimumZoomScale = 1;
  264. self.maximumZoomScale = 3;
  265. _imageView.contentMode=UIViewContentModeScaleAspectFill;
  266. _imageView.clipsToBounds=YES;
  267. max=NO;
  268. _tapOnceAction=nil;
  269. _target=nil;
  270. self.contentSize=self.frame.size;
  271. }
  272. return self;
  273. }
  274. -(id)initWithImage:(UIImage*)image andFrame:(CGRect)frame
  275. {
  276. self = [self initWithFrame:frame];
  277. if (self) {
  278. // Initialization code
  279. [self setImage:image];
  280. }
  281. return self;
  282. }
  283. -(void)setImage:(UIImage*)image
  284. {
  285. // Initialization code
  286. _imageView.image=image;
  287. [self setImageFrameAndContentSize];
  288. UILongPressGestureRecognizer * longPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
  289. [self addGestureRecognizer:longPress];
  290. }
  291. -(void)setImageWithURL:(NSString *)url
  292. {
  293. [self setImageWithURL:url andSmallImage:nil];
  294. }
  295. -(void)setImageWithURL:(NSString*)url andSmallImage:(UIImage*)image
  296. {
  297. UIImage* image1;
  298. if (image.images.count > 0) {
  299. UIImage *image2 = [[HBHttpRequestCache shareCache] getBitmapFromMemory:url];
  300. if (image2.images.count > 0) {
  301. image1 = image2;
  302. }else{
  303. [[HBHttpRequestCache shareCache] clearOneCache:url];
  304. [[HBHttpRequestCache shareCache] storeBitmapToMemory:image withKey:url];
  305. image1 = image;
  306. }
  307. }else{
  308. image1 = [[HBHttpRequestCache shareCache] getBitmapFromMemory:url];
  309. }
  310. if(image1){
  311. _imageView.image=image1;
  312. [self setImageFrameAndContentSize];
  313. _imageView.userInteractionEnabled=YES;
  314. UILongPressGestureRecognizer * longPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
  315. [self addGestureRecognizer:longPress];
  316. }else{
  317. UIImage *image1=[[HBHttpRequestCache shareCache] getBitmapFromDisk:url];
  318. if(image1){
  319. _imageView.image=image1;
  320. [self setImageFrameAndContentSize];
  321. _imageView.userInteractionEnabled=YES;
  322. UILongPressGestureRecognizer * longPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
  323. [self addGestureRecognizer:longPress];
  324. }else{
  325. _imageView.image=image;
  326. [self setImageFrameAndContentSize];
  327. _imageView.userInteractionEnabled=NO;
  328. UIActivityIndicatorView *indicator=[[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
  329. indicator.frame=CGRectMake((self.frame.size.width-20)/2, (self.frame.size.height-20)/2, 20, 20);
  330. [self addSubview:indicator];
  331. [indicator startAnimating];
  332. [[HBHttpImageDownloader shareDownlader] downBitmapWithURL:url process:nil complete:^(UIImage *image, NSData *data, NSError *error, BOOL finish) {
  333. dispatch_async(dispatch_get_main_queue(), ^{
  334. [indicator stopAnimating];
  335. [indicator removeFromSuperview];
  336. _imageView.image=image;
  337. [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
  338. [self setImageFrameAndContentSize];
  339. } completion:^(BOOL finished) {
  340. _imageView.userInteractionEnabled=YES;
  341. UILongPressGestureRecognizer * longPress=[[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];
  342. [self addGestureRecognizer:longPress];
  343. }];
  344. });
  345. } option:HBHttpImageDownloaderOptionUseCache valueReturn:nil];
  346. }
  347. }
  348. }
  349. -(void)addTarget:(id)target tapOnceAction:(SEL)action
  350. {
  351. _target=target;
  352. _tapOnceAction=action;
  353. }
  354. -(void)reset
  355. {
  356. [self setImageFrameAndContentSize];
  357. }
  358. @end