iOS仿微信图片分享界面实现代码
程序员文章站
2023-12-20 15:47:22
分享功能目前几乎已成为很多app的标配了,其中微信,微博等app的图片分享界面设计的很棒,不仅能够展示缩略图,还可以预览删除。最近我在做一款社交分享app,其中就要实现图文...
分享功能目前几乎已成为很多app的标配了,其中微信,微博等app的图片分享界面设计的很棒,不仅能够展示缩略图,还可以预览删除。最近我在做一款社交分享app,其中就要实现图文分享功能,于是试着自行实现仿微信分享风格的功能。
核心思想:
主要是使用uicollectionview来动态加载分享图片内容,配合预览页面,实现动态添加和预览删除图片效果。
实现效果:
核心代码如下:
分享界面:
// // posttableviewcontroller.h // nineshare // // created by 张昌伟 on 15/1/26. // copyright (c) 2015年 9studio. all rights reserved. // #import <uikit/uikit.h> #import "umsocial.h" #import "ysypreviewviewcontroller.h" @interface posttableviewcontroller : uitableviewcontroller<uitextviewdelegate,uicollectionviewdatasource,uicollectionviewdelegate,uiactionsheetdelegate,uiimagepickercontrollerdelegate,umsocialuidelegate,uinavigationcontrollerdelegate> @property (weak, nonatomic) iboutlet uicollectionview *photoscollectionview; @property (weak, nonatomic) iboutlet uiswitch *weiboswitch; @property (weak, nonatomic) iboutlet uiswitch *renrenswitch; - (ibaction)doubanswitched:(id)sender; - (ibaction)renrenswitched:(id)sender; - (ibaction)weiboswitched:(id)sender; +(void) deleteselectedimage:(nsinteger) index; +(void) deleteselectedimagewithimage:(uiimage*)image; @end
实现文件
// // posttableviewcontroller.m // nineshare // // created by 张昌伟 on 15/1/26. // copyright (c) 2015年 9studio. all rights reserved. // #import "posttableviewcontroller.h" #import "nineshareservice.h" static nsmutablearray *currentimages; @interface posttableviewcontroller () @property (weak, nonatomic) iboutlet uitextview *sharecontent; - (ibaction)poststatus:(id)sender; - (ibaction)cancelpost:(id)sender; -(void) loadsnsstatus; @property (weak, nonatomic) iboutlet uiswitch *doubanswitch; @property (weak, nonatomic) iboutlet uitextview *backgroundtextview; @property nsmutablearray *snsarray; //@property nsmutablearray *photos; @property nineshareservice *datacontext; @property nsmutabledictionary *tempdict; -(void) opencamera; -(void) openlibary; @end @implementation posttableviewcontroller - (void)viewdidload { [super viewdidload]; if(currentimages ==nil) { currentimages=[[nsmutablearray alloc] init]; } // uncomment the following line to preserve selection between presentations. // self.clearsselectiononviewwillappear = no; // uncomment the following line to display an edit button in the navigation bar for this view controller. // self.navigationitem.rightbarbuttonitem = self.editbuttonitem; _datacontext=[nineshareservice getinstance]; [self loadsnsstatus]; } -(void)viewwillappear:(bool)animated{ [_photoscollectionview reloaddata]; } - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of any resources that can be recreated. } -(void) loadsnsstatus{ _snsarray=[nsmutablearray arraywithcontentsoffile:[[nsbundle mainbundle] pathforresource:@"sns" oftype:@"plist"]]; if(_snsarray.count>0) { [_weiboswitch seton:[_snsarray[0] boolvalue] animated:yes]; [_renrenswitch seton:[_snsarray[1] boolvalue] animated:yes]; [_doubanswitch seton:[_snsarray[2] boolvalue] animated:yes]; } } -(bool)textview:(uitextview *)textview shouldchangetextinrange:(nsrange)range replacementtext:(nsstring *)text{ if(![text isequaltostring:@""]) { [_backgroundtextview sethidden:yes]; } if([text isequaltostring:@""]&&range.length==1&&range.location==0){ [_backgroundtextview sethidden:no]; } if ([text isequaltostring:@"\n"]) { [textview resignfirstresponder]; return no; } return yes; } -(void)textviewdidbeginediting:(uitextview *)textview { cgrect frame = textview.frame; int offset = frame.origin.y + 32 - (self.view.frame.size.height - 216.0);//键盘高度216 nstimeinterval animationduration = 0.30f; [uiview beginanimations:@"resizeforkeyboard" context:nil]; [uiview setanimationduration:animationduration]; //将视图的y坐标向上移动offset个单位,以使下面腾出地方用于软键盘的显示 if(offset > 0) self.view.frame = cgrectmake(0.0f, -offset, self.view.frame.size.width, self.view.frame.size.height); [uiview commitanimations]; } -(void)textviewdidendediting:(uitextview *)textview{ self.view.frame =cgrectmake(0, 0, self.view.frame.size.width, self.view.frame.size.height); } -(void)collectionview:(uicollectionview *)collectionview didselectitematindexpath:(nsindexpath *)indexpath{ if(indexpath.row==currentimages.count) { uiactionsheet *action=[[uiactionsheet alloc] initwithtitle:@"选取照片" delegate:self cancelbuttontitle:@"取消" destructivebuttontitle:nil otherbuttontitles:@"从摄像头选取", @"从图片库选择",nil]; [action showinview:self.view]; } else { [ysypreviewviewcontroller setpreviewimage:currentimages[indexpath.row]]; [self.navigationcontroller pushviewcontroller:[[uistoryboard storyboardwithname:@"main" bundle:[nsbundle mainbundle]] instantiateviewcontrollerwithidentifier:@"previewvc"] animated:yes]; } } -(nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section{ return currentimages.count==0?1:currentimages.count+1; } -(uicollectionviewcell *)collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath{ uicollectionviewcell *cell=[collectionview dequeuereusablecellwithreuseidentifier:@"collectioncell" forindexpath:indexpath]; uiimageview *imageview=[[uiimageview alloc] initwithframe:cgrectmake(0, 0, 50, 50)]; if(currentimages.count==0||indexpath.row==currentimages.count) { imageview.image=[uiimage imagenamed:@"add"]; } else{ while ([cell.contentview.subviews lastobject] != nil) { [(uiview*)[cell.contentview.subviews lastobject] removefromsuperview]; } imageview.image=currentimages[indexpath.row]; } imageview.contentmode=uiviewcontentmodescaleaspectfill; [cell.contentview addsubview:imageview]; return cell; } -(void)savesnstofile{ nsstring *destpath=[nssearchpathfordirectoriesindomains(nsdocumentdirectory, nsuserdomainmask, yes) lastobject]; if (![[nsfilemanager defaultmanager] fileexistsatpath:destpath]) { nsstring *path=[[nsbundle mainbundle] pathforresource:@"sns" oftype:@"plist"]; [[nsfilemanager defaultmanager] copyitematpath:path topath:destpath error:nil]; } if(_snsarray==nil) _snsarray=[[nsmutablearray alloc] init]; [_snsarray removeallobjects]; [_snsarray addobject:_weiboswitch.ison?@"yes":@"no"]; [_snsarray addobject:_renrenswitch.ison?@"yes":@"no"]; [_snsarray addobject:_doubanswitch.ison?@"yes":@"no"]; if(_snsarray.count>0) { [_snsarray writetofile:destpath atomically:yes]; } } - (ibaction)poststatus:(id)sender { if(_weiboswitch.ison) [[umsocialdataservice defaultdataservice] postsnswithtypes:@[umsharetosina] content:_sharecontent.text.length>0?_sharecontent.text: @"9share for ios test message" image:currentimages.count==0?nil:currentimages[0] location:nil urlresource:nil presentedcontroller:self completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { nslog(@"分享成功!"); if(!(_renrenswitch.ison||_doubanswitch.ison)) { [self savesnstofile]; [self dismissviewcontrolleranimated:yes completion:nil]; } } }]; if(_renrenswitch.ison) [[umsocialdataservice defaultdataservice] postsnswithtypes:@[umsharetorenren] content:_sharecontent.text.length>0?_sharecontent.text: @"9share for ios test message" image:currentimages.count==0?nil:currentimages[0] location:nil urlresource:nil presentedcontroller:self completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { nslog(@"分享成功!"); if(!_doubanswitch.ison) { [self savesnstofile]; [self dismissviewcontrolleranimated:yes completion:nil]; } } }]; if(_doubanswitch.ison) [[umsocialdataservice defaultdataservice] postsnswithtypes:@[umsharetodouban] content:_sharecontent.text.length>0?_sharecontent.text: @"9share for ios test message" image:currentimages.count==0?nil:currentimages[0] location:nil urlresource:nil presentedcontroller:self completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { nslog(@"分享成功!"); [self savesnstofile]; [self dismissviewcontrolleranimated:yes completion:nil]; } }]; } -(void)imagepickercontroller:(uiimagepickercontroller *)picker didfinishpickingmediawithinfo:(nsdictionary *)info{ [picker dismissviewcontrolleranimated:yes completion:nil]; uiimage *image=[info objectforkey:uiimagepickercontrolleroriginalimage]; nsdata *tempdata=uiimagejpegrepresentation(image, 0.5f); image=[uiimage imagewithdata:tempdata]; if(currentimages ==nil) { currentimages=[[nsmutablearray alloc] init]; } [currentimages addobject:image]; [_photoscollectionview reloaddata]; // [self saveimage:image withname:@""] } -(void)imagepickercontrollerdidcancel:(uiimagepickercontroller *)picker{ [picker dismissviewcontrolleranimated:yes completion:nil]; } - (ibaction)cancelpost:(id)sender { [self dismissviewcontrolleranimated:yes completion:nil]; } -(void)actionsheet:(uiactionsheet *)actionsheet clickedbuttonatindex:(nsinteger)buttonindex{ switch (buttonindex) { case 0: [self opencamera]; break; case 1: [self openlibary]; break; default: break; } } -(void)opencamera{ //uiimagepickercontrollersourcetype *type=uiimagepickercontrollersourcetypecamera; if([uiimagepickercontroller issourcetypeavailable:uiimagepickercontrollersourcetypecamera]) { uiimagepickercontroller *picker=[[uiimagepickercontroller alloc] init]; picker.delegate=self; picker.sourcetype=uiimagepickercontrollersourcetypecamera; picker.allowsediting=yes; [self presentviewcontroller:picker animated:yes completion:nil]; } } -(void)openlibary{ if([uiimagepickercontroller issourcetypeavailable:uiimagepickercontrollersourcetypephotolibrary]) { uiimagepickercontroller *picker=[[uiimagepickercontroller alloc] init]; picker.delegate=self; picker.sourcetype=uiimagepickercontrollersourcetypephotolibrary; picker.allowsediting=yes; [self presentviewcontroller:picker animated:yes completion:nil]; } } -(void) saveimage:(uiimage *)image withname:(nsstring *)name { nsdata *imagedata=uiimagejpegrepresentation(image, 0.5); nsstring *path=[nstemporarydirectory() stringbyappendingpathcomponent:name]; [imagedata writetofile:path atomically:yes]; } - (ibaction)doubanswitched:(id)sender { if(_doubanswitch.ison){ if(![umsocialaccountmanager isoauthandtokennotexpired:umsharetodouban]) { //进入授权页面 [umsocialsnsplatformmanager getsocialplatformwithname:umsharetodouban].loginclickhandler(self,[umsocialcontrollerservice defaultcontrollerservice],yes,^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { //获取微博用户名、uid、token等 umsocialaccountentity *snsaccount = [[umsocialaccountmanager socialaccountdictionary] valueforkey:umsharetodouban]; nslog(@"username is %@, uid is %@, token is %@",snsaccount.username,snsaccount.usid,snsaccount.accesstoken); //进入你的分享内容编辑页面 umsocialaccountentity *doubanaccount = [[umsocialaccountentity alloc] initwithplatformname:umsharetodouban]; doubanaccount.usid = snsaccount.usid; doubanaccount.accesstoken = snsaccount.accesstoken; // weiboaccount.openid = @"tencent weibo openid"; //腾讯微博账户必需设置openid //同步用户信息 [umsocialaccountmanager postsnsaccount:doubanaccount completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { //在本地缓存设置得到的账户信息 [umsocialaccountmanager setsnsaccount:doubanaccount]; //进入你自定义的分享内容编辑页面或者使用我们的内容编辑页面 }}]; } else { [_doubanswitch seton:no animated:yes]; } }); } } } - (ibaction)renrenswitched:(id)sender { if(_doubanswitch.ison) { if(![umsocialaccountmanager isoauthandtokennotexpired:umsharetorenren]) { //进入授权页面 [umsocialsnsplatformmanager getsocialplatformwithname:umsharetorenren].loginclickhandler(self,[umsocialcontrollerservice defaultcontrollerservice],yes,^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { //获取微博用户名、uid、token等 umsocialaccountentity *snsaccount = [[umsocialaccountmanager socialaccountdictionary] valueforkey:umsharetorenren]; nslog(@"username is %@, uid is %@, token is %@",snsaccount.username,snsaccount.usid,snsaccount.accesstoken); //进入你的分享内容编辑页面 umsocialaccountentity *renrenaccount = [[umsocialaccountentity alloc] initwithplatformname:umsharetorenren]; renrenaccount.usid = snsaccount.usid; renrenaccount.accesstoken = snsaccount.accesstoken; // weiboaccount.openid = @"tencent weibo openid"; //腾讯微博账户必需设置openid //同步用户信息 [umsocialaccountmanager postsnsaccount:renrenaccount completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { //在本地缓存设置得到的账户信息 [umsocialaccountmanager setsnsaccount:renrenaccount]; //进入你自定义的分享内容编辑页面或者使用我们的内容编辑页面 }}]; } else{ [_renrenswitch seton:no animated:yes]; } }); } } } - (ibaction)weiboswitched:(id)sender { if(_weiboswitch.ison) { if(![umsocialaccountmanager isoauthandtokennotexpired:umsharetosina]) { [umsocialsnsplatformmanager getsocialplatformwithname:umsharetosina].loginclickhandler(self,[umsocialcontrollerservice defaultcontrollerservice],yes,^(umsocialresponseentity *response){ if(response.responsecode==umsresponsecodesuccess){ umsocialaccountentity *snsaccount=[[umsocialaccountmanager socialaccountdictionary] valueforkey:umsharetosina]; umsocialaccountentity *sinaaccount=[[umsocialaccountentity alloc] initwithplatformname:umsharetosina]; //缓存到本地 sinaaccount.usid = snsaccount.usid; sinaaccount.accesstoken = snsaccount.accesstoken; // weiboaccount.openid = @"tencent weibo openid"; //腾讯微博账户必需设置openid //同步用户信息 [umsocialaccountmanager postsnsaccount:sinaaccount completion:^(umsocialresponseentity *response){ if (response.responsecode == umsresponsecodesuccess) { //在本地缓存设置得到的账户信息 [umsocialaccountmanager setsnsaccount:sinaaccount]; //进入你自定义的分享内容编辑页面或者使用我们的内容编辑页面 }}]; } else { [_weiboswitch seton:no animated:yes]; } }); } } } +(void)deleteselectedimage:(nsinteger)index { if(currentimages!=nil) [currentimages removeobjectatindex:index]; } +(void)deleteselectedimagewithimage:(uiimage *)image{ if(currentimages!=nil) [currentimages removeobject:image]; } @end
预览界面:
// // ysypreviewviewcontroller.h // nineshare // // created by zhangchangwei on 15/2/1. // copyright (c) 2015年 9studio. all rights reserved. // #import <uikit/uikit.h> #import "posttableviewcontroller.h" @interface ysypreviewviewcontroller : uiviewcontroller<uiactionsheetdelegate> +(void) setpreviewimage:(uiimage *)image; @end
// // ysypreviewviewcontroller.m // nineshare // // created by zhangchangwei on 15/2/1. // copyright (c) 2015年 9studio. all rights reserved. // #import "ysypreviewviewcontroller.h" static uiimage *currentimage; @interface ysypreviewviewcontroller () - (ibaction)deleteselectedimage:(id)sender; @property (weak, nonatomic) iboutlet uiimageview *previewimageview; @end @implementation ysypreviewviewcontroller - (void)viewdidload { [super viewdidload]; // do any additional setup after loading the view. _previewimageview.image=currentimage; } - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of any resources that can be recreated. } /* #pragma mark - navigation // in a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareforsegue:(uistoryboardsegue *)segue sender:(id)sender { // get the new view controller using [segue destinationviewcontroller]. // pass the selected object to the new view controller. } */ - (ibaction)deleteselectedimage:(id)sender { uiactionsheet *action=[[uiactionsheet alloc] initwithtitle:@"要删除这张照片吗?" delegate:self cancelbuttontitle:@"取消" destructivebuttontitle:@"删除" otherbuttontitles: nil]; [action showinview:self.view]; } -(void)actionsheet:(uiactionsheet *)actionsheet clickedbuttonatindex:(nsinteger)buttonindex{ if(buttonindex==actionsheet.cancelbuttonindex) { return; } else { [posttableviewcontroller deleteselectedimagewithimage:currentimage]; [self.navigationcontroller poptorootviewcontrolleranimated:yes]; } } +(void)setpreviewimage:(uiimage *)image{ currentimage=image; } @end
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。