好久沒(méi)更新了障涯,今天準(zhǔn)備寫(xiě)一個(gè)在實(shí)戰(zhàn)項(xiàng)目中大家經(jīng)常遇到的罐旗,就是圖片上傳頭像。 下面介紹從本地上傳唯蝶。首先九秀,一般我們頭像是需要保存在本地的,所以我們要建個(gè)本地類粘我,用來(lái)存圖片字節(jié)鼓蜒。
UserDefaults.m文件
#import "UserDefaults.h"
@implementation UserDefaults
+ (void)setImage:(NSData *)img
{
[[NSUserDefaults standardUserDefaults] setObject:img forKey:@"img"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
+ (NSData *)getImage
{
return [[NSUserDefaults standardUserDefaults] objectForKey:@"img"];
}
@end
然后在你的控制器頁(yè)面將UserDefaults.h導(dǎo)進(jìn)來(lái)痹换。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width / 2)];
[_topView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:_topView];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, _topView.frame.size.width, _topView.frame.size.height)];
[imageView setBackgroundColor:[UIColor clearColor]];
[imageView setImage:[UIImage imageNamed:@"chen.png"]];
[_topView addSubview:imageView];
_avatarBtn = [[UIButton alloc] initWithFrame:CGRectMake((imageView.frame.size.width - 70) / 2, (imageView.frame.size.height - 70) / 2, 70, 70)];
_avatarBtn.layer.masksToBounds = YES;
_avatarBtn.layer.cornerRadius = _avatarBtn.frame.size.height / 2;
_avatarBtn.layer.borderWidth = 1.0f;
_avatarBtn.layer.borderColor = [UIColor lightGrayColor].CGColor;
[_avatarBtn setBackgroundImage:[UIImage imageNamed:@"loin_icon_noSelect"] forState:UIControlStateNormal];
[_avatarBtn addTarget:self action:@selector(onImageTouch:) forControlEvents:UIControlEventTouchUpInside];
[_topView addSubview:_avatarBtn];
}
初始化創(chuàng)建所需要的控件。接下來(lái)都弹,在點(diǎn)擊按鈕的事件中娇豫,我們就來(lái)個(gè)提示框提示是否選擇圖片或拍照,都是在一個(gè)點(diǎn)擊事件的方法里面
- (void)onImageTouch:(UIButton *)btn
{
UIAlertController *alertSheet = [UIAlertController alertControllerWithTitle:@"請(qǐng)選擇頭像來(lái)源" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
imagePickerController.delegate = self;
imagePickerController.allowsEditing = YES;
// 判斷是否支持相機(jī)
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIAlertAction *cameraAction = [UIAlertAction actionWithTitle:@"拍照" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
// 設(shè)置數(shù)據(jù)源
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:imagePickerController animated:YES completion:nil];
}];
[alertSheet addAction:cameraAction];
}
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIAlertAction *photoAction = [UIAlertAction actionWithTitle:@"從手機(jī)相冊(cè)選擇" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePickerController animated:YES completion:nil];
}];
[alertSheet addAction:photoAction];
}
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
[alertSheet addAction:cancelAction];
[self presentViewController:alertSheet animated:YES completion:nil];
}
之后畅厢,我們就去寫(xiě)UIImagePickerController的代理方法冯痢,當(dāng)取消或選中之后的操作:
#pragma mark -
#pragma mark UIImagePickerControllerDelegate
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info
{
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
// 被選中的圖片
if ([mediaType isEqualToString:@"public.image"]) {
// 獲取照片
UIImage *image = [info objectForKey:UIImagePickerControllerEditedImage];
NSString *path = [self saveImg:image WithName:@"avatar.png"];
if (path != nil) {
// 圖片存在,做你想要的操作
NSData *data = [NSData dataWithContentsOfFile:path];
[UserDefaults setImage:data];
}
[picker dismissViewControllerAnimated:YES completion:nil]; // 隱藏視圖
}
}
我們需要寫(xiě)一個(gè)圖片保存到本地的方法
// 圖片保存本地
- (NSString *)saveImg:(UIImage *)curImage WithName:(NSString *)imageName;
{
NSData *imageData = UIImageJPEGRepresentation(curImage, 1); // 1為不縮放保存框杜,取值(0~1)
// 獲取沙盒路徑
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:imageName];
// 將照片寫(xiě)入文件
//atomically:這個(gè)參數(shù)意思是: 如果為YES則保證文件的寫(xiě)入原子性,就是說(shuō)會(huì)先創(chuàng)建一個(gè)臨時(shí)文件,直到文件內(nèi)容寫(xiě)入成功再導(dǎo)入到目標(biāo)文件里.如果為NO,則直接寫(xiě)入目標(biāo)文件里
if ([imageData writeToFile:path atomically:NO]) {
return path;
} else {
return nil;
}
}
到了這里已經(jīng)把圖片從手機(jī)相冊(cè)還是手機(jī)拍照之后傳到了頭像控件里面了浦楣。但是要注意,我們是本地保存霸琴,所以再每次進(jìn)入到視圖View的時(shí)候都要記得取加載保存過(guò)的那張圖片
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
if ([UserDefaults getImage].length > 0) {
[_avatarBtn setImage:[UIImage imageWithData:[UserDefaults getImage]] forState:UIControlStateNormal];
} else {
// 否則椒振,獲取你從服務(wù)器上加載的圖片(讀者的建議,很nice)梧乘,獲取后記得把圖片保存本地澎迎,這樣長(zhǎng)度就有啦
[_avatarBtn setImage@“服務(wù)器上加載的圖片” forState:UIControlStateNormal];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}
最后,提醒一點(diǎn)选调,記得把訪問(wèn)跟拍照權(quán)限添加進(jìn)來(lái)夹供,這不列舉一下
NSMicrophoneUsageDescription 是否允許此App使用您的麥克風(fēng)?
NSPhotoLibraryUsageDescription 是否允許此App使用您的相冊(cè)仁堪?
NSContactsUsageDescription 是否允許此App訪問(wèn)您的通訊錄哮洽?
NSCameraUsageDescription 是否允許此App使用您的 相機(jī)?
NSCalendarsUsageDescription 是否允許此App使用日歷?
NSAppleMusicUsageDescription 媒體資料庫(kù)
效果圖:
好了弦聂,大概圖片上傳也就這些啦鸟辅,簡(jiǎn)單易懂。全部代碼都貼出來(lái)了莺葫,背景框是我女神匪凉,大家猜一猜嘍。我會(huì)再繼續(xù)分享自己的菜鳥(niǎo)經(jīng)歷中的心得捺檬,感謝了再层!