
在开发中,经常用到选择多张图片进行上传或作其他处理等等,以下DEMO满足了此功能中的大部分功能,可直接使用到项目中。
主要功能如下:
1,图片九宫格排列(可自动设置)
2,图片长按抖动(仿苹果软件删除时,图标抖动效果),可进入删除状态,再次单击进入普通状态
3,图片设置最大上限,加号按钮自动隐藏
4,已选图片可单击进行重新选择
5,无需代理,直接调用对应属性就可获取所有图片,并与显示顺序保持一致
效果图如下:



1 // 2 // SZAddImage.h 3 // addImage 4 // 5 // Created by mac on 14-5-21. 6 // Copyright (c) 2014年 shunzi. All rights reserved. 7 // 8 9 /** 10 * 使用说明:直接创建此view添加到你需要放置的位置即可. 11 * 属性images可以获取到当前选中的所有图片对象. 12 */ 13 14 #import <UIKit/UIKit.h> 15 16 @interface SZAddImage : UIView 17 18 /** 19 * 存储所有的照片(UIImage) 20 */ 21 @PRoperty (nonatomic, strong) NSMutableArray *images; 22 23 @end
1 //
2 // SZAddImage.m
3 // addImage
4 //
5 // Created by mac on 14-5-21.
6 // Copyright (c) 2014年 shunzi. All rights reserved.
7 //
8
9 #define imageH 100 // 图片高度
10 #define imageW 75 // 图片宽度
11 #define kMaxColumn 3 // 每行显示数量
12 #define MaxImageCount 9 // 最多显示图片个数
13 #define deleImageWH 25 // 删除按钮的宽高
14 #define kAdeleImage @"close.png" // 删除按钮图片
15 #define kAddImage @"add.png" // 添加按钮图片
16
17
18
19 #import "SZAddImage.h"
20 @interface SZAddImage()<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
21 {
22 // 标识被编辑的按钮 -1 为添加新的按钮
23 NSInteger editTag;
24 }
25 @end
26
27 @implementation SZAddImage
28
29 - (id)initWithFrame:(CGRect)frame
30 {
31 self = [super initWithFrame:frame];
32 if (self) {
33 UIButton *btn = [self createButtonWithImage:kAddImage andSeletor:@selector(addNew:)];
34 [self addSubview:btn];
35 }
36 return self;
37 }
38
39 -(NSMutableArray *)images
40 {
41 if (_images == nil) {
42 _images = [NSMutableArray array];
43 }
44 return _images;
45 }
46
47 // 添加新的控件
48 - (void)addNew:(UIButton *)btn
49 {
50 // 标识为添加一个新的图片
51
52 if (![self deleClose:btn]) {
53 editTag = -1;
54 [self callImagePicker];
55 }
56
57
58 }
59
60 // 修改旧的控件
61 - (void)changeOld:(UIButton *)btn
62 {
63 // 标识为修改(tag为修改标识)
64 if (![self deleClose:btn]) {
65 editTag = btn.tag;
66 [self callImagePicker];
67 }
68 }
69
70 // 删除"删除按钮"
71 - (BOOL)deleClose:(UIButton *)btn
72 {
73 if (btn.subviews.count == 2) {
74 [[btn.subviews lastObject] removeFromSuperview];
75 [self stop:btn];
76 return YES;
77 }
78
79 return NO;
80 }
81
82 // 调用图片选择器
83 - (void)callImagePicker
84 {
85 UIImagePickerController *pc = [[UIImagePickerController alloc] init];
86 pc.allowsEditing = YES;
87 pc.delegate = self;
88 [self.window.rootViewController presentViewController:pc animated:YES completion:nil];
89 }
90
91
92 // 根据图片名称或者图片创建一个新的显示控件
93 - (UIButton *)createButtonWithImage:(id)imageNameOrImage andSeletor : (SEL)selector
94 {
95 UIImage *addImage = nil;
96 if ([imageNameOrImage isKindOfClass:[NSString class]]) {
97 addImage = [UIImage imageNamed:imageNameOrImage];
98 }
99 else if([imageNameOrImage isKindOfClass:[UIImage class]])
100 {
101 addImage = imageNameOrImage;
102 }
103 UIButton *addBtn = [UIButton buttonWithType:UIButtonTypeCustom];
104 [addBtn setImage:addImage forState:UIControlStateNormal];
105 [addBtn addTarget:self action:selector forControlEvents:UIControlEventTouchUpInside];
106 addBtn.tag = self.subviews.count;
107
108 // 添加长按手势,用作删除.加号按钮不添加
109 if(addBtn.tag != 0)
110 {
111 UILongPressGestureRecognizer *gester = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)];
112 [addBtn addGestureRecognizer:gester];
113 }
114 return addBtn;
115
116 }
117
118
119 // 长按添加删除按钮
120 - (void)longPress : (UIGestureRecognizer *)gester
121 {
122 if (gester.state == UIGestureRecognizerStateBegan)
123 {
124 UIButton *btn = (UIButton *)gester.view;
125
126 UIButton *dele = [UIButton buttonWithType:UIButtonTypeCustom];
127 dele.bounds = CGRectMake(0, 0, deleImageWH, deleImageWH);
128 [dele setImage:[UIImage imageNamed:kAdeleImage] forState:UIControlStateNormal];
129 [dele addTarget:self action:@selector(deletePic:) forControlEvents:UIControlEventTouchUpInside];
130 dele.frame = CGRectMake(btn.frame.size.width - dele.frame.size.width, 0, dele.frame.size.width, dele.frame.size.height);
131
132 [btn addSubview:dele];
133 [self start : btn];
134
135
136 }
137
138 }
139
140 // 长按开始抖动
141 - (void)start : (UIButton *)btn {
142 double angle1 = -5.0 / 180.0 * M_PI;
143 double angle2 = 5.0 / 180.0 * M_PI;
144 CAKeyframeAnimation *anim = [CAKeyframeAnimation animation];
145 anim.keyPath = @"transform.rotation";
146
147 anim.values = @[@(angle1), @(angle2), @(angle1)];
148 anim.duration = 0.25;
149 // 动画的重复执行次数
150 anim.repeatCount = MAXFLOAT;
151
152 // 保持动画执行完毕后的状态
153 anim.removedOnCompletion = NO;
154 anim.fillMode = kCAFillModeForwards;
155
156 [btn.layer addAnimation:anim forKey:@"shake"];
157 }
158
159 // 停止抖动
160 - (void)stop : (UIButton *)btn{
161 [btn.layer removeAnimationForKey:@"shake"];
162 }
163
164 // 删除图片
165 - (void)deletePic : (UIButton *)btn
166 {
167 [self.images removeObject:[(UIButton *)btn.superview imageForState:UIControlStateNormal]];
168 [btn.superview removeFromSuperview];
169 if ([[self.subviews lastObject] isHidden]) {
170 [[self.subviews lastObject] setHidden:NO];
171 }
172
173
174 }
175
176 // 对所有子控件进行布局
177 - (void)layoutSubviews
178 {
179 [super layoutSubviews];
180 int count = self.subviews.count;
181 CGFloat btnW = imageW;
182 CGFloat btnH = imageH;
183 int maxColumn = kMaxColumn > self.frame.size.width / imageW ? self.frame.size.width / imageW : kMaxColumn;
184 CGFloat marginX = (self.frame.size.width - maxColumn * btnW) / (count + 1);
185 CGFloat marginY = marginX;
186 for (int i = 0; i < count; i++) {
187 UIButton *btn = self.subviews[i];
188 CGFloat btnX = (i % maxColumn) * (marginX + btnW) + marginX;
189 CGFloat btnY = (i / maxColumn) * (marginY + btnH) + marginY;
190 btn.frame = CGRectMake(btnX, btnY, btnW, btnH);
191 }
192
193 }
194
195 #pragma mark - UIImagePickerController 代理方法
196 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
197 {
198 UIImage *image = info[UIImagePickerControllerEditedImage];
199 if (editTag == -1) {
200 // 创建一个新的控件
201 UIButton *btn = [self createButtonWithImage:image andSeletor:@selector(changeOld:)];
202 [self insertSubview:btn atIndex:self.subviews.count - 1];
203 [self.images addObject:image];
204 if (self.subviews.count - 1 == MaxImageCount) {
205 [[self.subviews lastObject] setHidden:YES];
206
207 }
208 }
209 else
210 {
211 // 根据tag修改需要编辑的控件
212 UIButton *btn = (UIButton *)[self viewWithTag:editTag];
213 int index = [self.images indexOfObject:[btn imageForState:UIControlStateNormal]];
214 [self.images removeObjectAtIndex:index];
215 [btn setImage:image forState:UIControlStateNormal];
216 [self.images insertObject:image atIndex:index];
217 }
218 // 退出图片选择控制器
219 [picker dismissViewControllerAnimated:YES completion:nil];
220 }
221
222
223
224 @end