在開發中,經常用到選擇多張圖片進行上傳或作其他處理等等,以下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