iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果
程序员文章站
2023-12-10 21:37:46
废话不多说了,直奔主题。
//需要的效果
1.设置window的根视图控制器为一个uitableviewcontroller
#import...
废话不多说了,直奔主题。
//需要的效果
1.设置window的根视图控制器为一个uitableviewcontroller
#import "appdelegate.h" #import "yctableviewcontroller.h" @interface appdelegate () @end @implementation appdelegate - (bool)application:(uiapplication *)application didfinishlaunchingwithoptions:(nsdictionary *)launchoptions { self.window = [[uiwindow alloc] initwithframe:[uiscreen mainscreen].bounds]; self.window.backgroundcolor = [uicolor whitecolor]; self.window.rootviewcontroller = [[uinavigationcontroller alloc] initwithrootviewcontroller:[[yctableviewcontroller alloc] init]]; [self.window makekeyandvisible]; return yes; }
2.uitableviewcontroller
// copyright © 2016年 chason. all rights reserved. // #import <uikit/uikit.h> #import "depositfeeheader.h" #import "depositfeewithapplytableviewcell.h" #import "appmodel.h" #import "mycollectionviewcell.h" #import "sectionheaderviewcollectionreusableview.h" @interface yctableviewcontroller : uitableviewcontroller<uicollectionviewdatasource, uicollectionviewdelegate, uicollectionviewdelegateflowlayout, uiimagepickercontrollerdelegate, uiactionsheetdelegate, uinavigationcontrollerdelegate> @property (nonatomic, strong) nsmutablearray *dataarray; @property (nonatomic, strong) nsmutablearray *ownhobby;//上传图片数组1 @property (nonatomic, strong) nsmutablearray *imagearray;//上传图片数组2 @property (nonatomic, strong) uicollectionview *collection; @property (nonatomic, strong) uiactionsheet *actionsheet; @property (nonatomic, strong) appmodel *model; @property (nonatomic, assign) nsinteger reupdate; @property (nonatomic, strong) nsstring *imagestring; @property (nonatomic, assign) nsinteger number; @end // copyright © 2016年 chason. all rights reserved. // #import "yctableviewcontroller.h" //手机屏幕的宽和高 #define kscreenwidth [uiscreen mainscreen].bounds.size.width #define kscreenheight [uiscreen mainscreen].bounds.size.height @interface yctableviewcontroller () @end @implementation yctableviewcontroller - (void)viewdidload { [super viewdidload]; _dataarray = [[nsmutablearray alloc] initwithcapacity:1]; for (int i = 0; i < 3; i++) { appmodel *model = [[appmodel alloc] init]; [_dataarray addobject:model]; } _ownhobby = [nsmutablearray array]; _reupdate = 10000;//赋初值 } - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section { appmodel *model = _dataarray[section]; if ([model is_open]) { return 1; }else { return 0; } } - (nsinteger)numberofsectionsintableview:(uitableview *)tableview { [_ownhobby removeallobjects]; for (int i = 0; i < _dataarray.count; i++) { _imagearray= [nsmutablearray array]; [_ownhobby addobject:_imagearray]; } return _dataarray.count; } - (cgfloat)tableview:(uitableview *)tableview heightforfooterinsection:(nsinteger)section { appmodel *model = _dataarray[section]; if (model.is_open == yes || section == _dataarray.count - 1) { return 0.01; }else { return 10; } } -(uiview *)tableview:(uitableview *)tableview viewforfooterinsection:(nsinteger)section { uiview *backview = [[uiview alloc] init]; backview.backgroundcolor = [uicolor whitecolor]; return backview; } - (cgfloat)tableview:(uitableview *)tableview heightforheaderinsection:(nsinteger)section { return 40; } - (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath { return 200; } - (uiview *)tableview:(uitableview *)tableview viewforheaderinsection:(nsinteger)section { depositfeeheader *depositheader = [tableview dequeuereusableheaderfooterviewwithidentifier:@"deposit"]; if (depositheader == nil) { depositheader = [[depositfeeheader alloc] initwithreuseidentifier:@"deposit"]; } depositheader.tag = 1000 + section; [depositheader.tap addtarget:self action:@selector(showdetail:)]; cgfloat rota; appmodel *model = _dataarray[section]; if ([model is_open] == no) { rota=0; } else{ rota=m_pi_2; } [uiview animatewithduration:0.1 animations:^{ depositheader.listimage.transform = cgaffinetransformmakerotation(rota); }]; return depositheader; } - (uitableviewcell *)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath { if (indexpath.section != _reupdate) { appmodel *model = _dataarray[indexpath.section]; depositfeewithapplytableviewcell *cell = [[depositfeewithapplytableviewcell alloc] initwithstyle:uitableviewcellstyledefault reuseidentifier:@"applycell"]; uicollectionviewflowlayout *flowlayout = [[uicollectionviewflowlayout alloc]init]; flowlayout.minimuminteritemspacing = 5; flowlayout.minimumlinespacing = 5; flowlayout.sectioninset = uiedgeinsetsmake(0 , 5 , 0 , 10 ); flowlayout.itemsize = cgsizemake(40 , 40); _collection = [[uicollectionview alloc]initwithframe:cgrectmake(10, 10, cell.backview.frame.size.width - 20, 90) collectionviewlayout:flowlayout]; [_collection registerclass:[sectionheaderviewcollectionreusableview class] forsupplementaryviewofkind:uicollectionelementkindsectionheader withreuseidentifier:@"head"]; _collection.tag = indexpath.section; _collection.bounces = no; _collection.delegate = self; _collection.datasource = self; _collection.backgroundcolor = [uicolor whitecolor]; [_collection registerclass:[mycollectionviewcell class] forcellwithreuseidentifier:@"identifier"]; [cell.backview addsubview:_collection]; [cell.shouldbtn addtarget:self action:@selector(upimage:) forcontrolevents:uicontroleventtouchupinside]; cell.shouldbtn.tag = indexpath.row + 2000; cell.selectionstyle = uitableviewcellselectionstylenone; return cell; }else { return nil; } } //对照片进行处理 - (void)upimage:(uibutton *)btn { } -(void)textfiledshow { if ([_ownhobby[_number] count] == 9) { uialertcontroller *alert1 = [uialertcontroller alertcontrollerwithtitle:@"上传照片不能超过9张, 点击图片可以删除" message:@"" preferredstyle:uialertcontrollerstylealert]; uialertaction *action = [uialertaction actionwithtitle:@"确定" style:uialertactionstyledefault handler:^(uialertaction * _nonnull action) { }]; [alert1 addaction:action]; [self.navigationcontroller presentviewcontroller:alert1 animated:yes completion:nil]; } else { [self callactionsheet]; } } //弹框提示相片来源 - (void)callactionsheet { if ([uiimagepickercontroller issourcetypeavailable:uiimagepickercontrollersourcetypecamera]) { self.actionsheet = [[uiactionsheet alloc] initwithtitle:@"选择照片" delegate:self cancelbuttontitle:@"取消" destructivebuttontitle:nil otherbuttontitles:@"拍照", @"从相册选择", nil]; }else { self.actionsheet = [[uiactionsheet alloc] initwithtitle:@"选择照片" delegate:self cancelbuttontitle:@"取消" destructivebuttontitle:nil otherbuttontitles:@"从相册选择", nil]; } [self.actionsheet showinview:self.tableview]; } - (void)actionsheet:(uiactionsheet *)actionsheet clickedbuttonatindex:(nsinteger)buttonindex { nsuinteger sourcetype = uiimagepickercontrollersourcetypephotolibrary; //pand是否支持相机 if ([uiimagepickercontroller issourcetypeavailable:uiimagepickercontrollersourcetypecamera]) { switch (buttonindex) { case 0: sourcetype = uiimagepickercontrollersourcetypecamera; break; case 1: sourcetype = uiimagepickercontrollersourcetypephotolibrary; break; default: return; } }else { if (buttonindex == 1) { return; }else { sourcetype = uiimagepickercontrollersourcetypesavedphotosalbum; } } uiimagepickercontroller *imagepicker = [[uiimagepickercontroller alloc] init]; imagepicker.delegate = self; imagepicker.allowsediting = yes; imagepicker.sourcetype = sourcetype; [self.navigationcontroller presentviewcontroller:imagepicker animated:yes completion:^{ }]; } -(void)imagepickercontroller:(uiimagepickercontroller *)picker didfinishpickingmediawithinfo:(nsdictionary<nsstring *,id> *)info { [picker dismissviewcontrolleranimated:yes completion:^{ }]; [_ownhobby[_number] addobject:[info objectforkey:uiimagepickercontrolleroriginalimage]]; [_collection reloaddata]; }
-(uicollectionviewcell *)collectionview:(uicollectionview *)collectionview cellforitematindexpath:(nsindexpath *)indexpath { _number = collectionview.tag; if ([_ownhobby[_number] count] == indexpath.row) { mycollectionviewcell *cell = [collectionview dequeuereusablecellwithreuseidentifier:@"identifier" forindexpath:indexpath]; uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc]initwithtarget:self action:@selector(textfiledshow)]; [cell.imageview addgesturerecognizer:tap]; cell.imageview.userinteractionenabled = yes; cell.cellstyle = cellstyleadd; cell.layer.maskstobounds = no; cell.layer.borderwidth = 0; cell.layer.cornerradius = 0; [cell layoutsubviews]; return cell; } else { mycollectionviewcell *cell = [collectionview dequeuereusablecellwithreuseidentifier:@"identifier" forindexpath:indexpath]; cell.photo.image = _ownhobby[_number][indexpath.row]; cell.cellstyle = 1; [cell layoutsubviews]; [cell.imageview removefromsuperview]; return cell; } } -(nsinteger)numberofsectionsincollectionview:(uicollectionview *)collectionview { return 1; } -(nsinteger)collectionview:(uicollectionview *)collectionview numberofitemsinsection:(nsinteger)section { return [_ownhobby[_number] count] + 1; } #pragma mark 头视图size -(cgsize)collectionview:(uicollectionview *)collectionview layout:(uicollectionviewlayout *)collectionviewlayout referencesizeforheaderinsection:(nsinteger)section { cgsize size = {0.01, 0.01}; return size; } #pragma mark 每个item大小 -(cgsize)collectionview:(uicollectionview *)collectionview layout:(uicollectionviewlayout *)collectionviewlayout sizeforitematindexpath:(nsindexpath *)indexpath { return cgsizemake(40, 40); } -(cgfloat)lengthwithstring:(nsstring *)string { return [string length]; } -(void)collectionview:(uicollectionview *)collectionview didselectitematindexpath:(nsindexpath *)indexpath { if ([_ownhobby[_number] count]) { [_ownhobby[_number] removeobjectatindex:indexpath.row]; [_collection reloaddata]; } } - (void)showdetail:(uitapgesturerecognizer *)tap { appmodel *model = _dataarray[tap.view.tag - 1000]; if ([model is_open]) { model.is_open = no; }else { model.is_open = yes; } [self.tableview reloadsections:[nsindexset indexsetwithindex:tap.view.tag - 1000] withrowanimation:uitableviewrowanimationnone]; } @end
3.自定义tableview的header和cell
//header // copyright © 2016年 chason. all rights reserved. // #import <uikit/uikit.h> @interface depositfeeheader : uitableviewheaderfooterview @property (nonatomic, strong) uilabel *titlelabel; @property (nonatomic, strong) uiimageview *listimage;//尾按钮 @property (nonatomic, strong) uigesturerecognizer *tap; @end // copyright © 2016年 chason. all rights reserved. // #import "depositfeeheader.h" //手机屏幕的宽和高 #define kscreenwidth [uiscreen mainscreen].bounds.size.width #define kscreenheight [uiscreen mainscreen].bounds.size.height @implementation depositfeeheader - (instancetype)initwithreuseidentifier:(nsstring *)reuseidentifier { self = [super initwithreuseidentifier:reuseidentifier]; if (self) { uiview *backview = [[uiview alloc] initwithframe:cgrectmake(0, 0, kscreenwidth, 40)]; backview.backgroundcolor = [uicolor whitecolor]; [self addsubview:backview]; self.titlelabel = [[uilabel alloc] initwithframe:cgrectmake(20, 10, kscreenwidth - 45, 20)]; self.titlelabel.text = @"车辆押金"; self.titlelabel.userinteractionenabled = yes; self.titlelabel.textcolor = [uicolor graycolor]; [backview addsubview:self.titlelabel]; self.listimage = [[uiimageview alloc] initwithframe:cgrectmake(kscreenwidth - 25, 10, 10, 20)]; self.listimage.image = [uiimage imagenamed:@"jiantou.png"]; [backview addsubview:self.listimage]; uiimageview *headerline = [[uiimageview alloc] initwithframe:cgrectmake(0, 0, kscreenwidth, 1)]; headerline.image = [uiimage imagenamed:@"line"]; [backview addsubview:headerline]; uiimageview *footerline = [[uiimageview alloc] initwithframe:cgrectmake(0, 39, kscreenwidth, 1)]; footerline.image = [uiimage imagenamed:@"line"]; [backview addsubview:footerline]; self.tap = [[uitapgesturerecognizer alloc] init]; [self addgesturerecognizer:self.tap]; } return self; } @end //cell // copyright © 2016年 chason. all rights reserved. // #import <uikit/uikit.h> @interface depositfeewithapplytableviewcell : uitableviewcell @property (nonatomic, strong) uiview *backview; @property (nonatomic, strong) uibutton *camerabtn; @property (nonatomic, strong) uiimageview *photoimg; @property (nonatomic, strong) uilabel *updatepresent; @property (nonatomic, strong) uibutton *shouldbtn; @end // copyright © 2016年 chason. all rights reserved. // #import "depositfeewithapplytableviewcell.h" //手机屏幕的宽和高 #define kscreenwidth [uiscreen mainscreen].bounds.size.width #define kscreenheight [uiscreen mainscreen].bounds.size.height @implementation depositfeewithapplytableviewcell - (instancetype)initwithstyle:(uitableviewcellstyle)style reuseidentifier:(nsstring *)reuseidentifier { self = [super initwithstyle:style reuseidentifier:reuseidentifier]; if (self) { _backview = [[uiview alloc] initwithframe:cgrectmake(20, 15, kscreenwidth - 40, 170)]; [self addsubview:_backview]; [self adddottedlinefromimageview:_backview]; self.updatepresent = [[uilabel alloc] initwithframe:cgrectmake(0, 0, kscreenwidth - 40, 20)]; self.updatepresent.center = cgpointmake((kscreenwidth - 40) / 2, 110); self.updatepresent.text = @"点击左上角按钮添加照片"; self.updatepresent.textcolor = [uicolor lightgraycolor]; self.updatepresent.textalignment = nstextalignmentcenter; self.updatepresent.font = [uifont systemfontofsize:14]; [_backview addsubview:self.updatepresent]; self.shouldbtn = [uibutton buttonwithtype:uibuttontypecustom]; self.shouldbtn.frame = cgrectmake((kscreenwidth - 40) / 2 - 45, 130, 90, 20); [self.shouldbtn settitlecolor:[uicolor whitecolor] forstate:uicontrolstatenormal]; [self.shouldbtn settitle:@"立即上传" forstate:uicontrolstatenormal]; self.shouldbtn.layer.cornerradius = 5; self.shouldbtn.backgroundcolor = [uicolor colorwithred:18/255.0 green:129/255.0 blue:201/255.0 alpha:1]; [_backview addsubview:self.shouldbtn]; } return self; } //添加虚线框 - (void)adddottedlinefromimageview:(uiview *)superview{ cgfloat w = superview.frame.size.width; cgfloat h = superview.frame.size.height; cgfloat padding = 20; //创建四个imageview作边框 for (nsinteger i = 0; i<4; i++) { uiimageview *imageview = [[uiimageview alloc] init]; imageview.backgroundcolor = [uicolor clearcolor]; if (i == 0) { imageview.frame = cgrectmake(0, 0, w, padding); }else if (i == 1){ imageview.frame = cgrectmake(0, 0, padding, h); }else if (i == 2){ imageview.frame = cgrectmake(0, h - padding, w, padding); }else if (i == 3){ imageview.frame = cgrectmake(w - padding, 0, padding, h); } [superview addsubview:imageview]; uigraphicsbeginimagecontext(imageview.frame.size); //开始画线 [imageview.image drawinrect:cgrectmake(0, 0, imageview.frame.size.width, imageview.frame.size.height)]; cgcontextsetlinecap(uigraphicsgetcurrentcontext(), kcglinecapround); //设置线条终点形状 cgfloat lengths[] = {10,5}; cgcontextref line = uigraphicsgetcurrentcontext(); cgcontextsetstrokecolorwithcolor(line, [uicolor blackcolor].cgcolor); cgcontextsetlinedash(line, 0, lengths, 2); //画虚线 cgcontextmovetopoint(line, 0, 0); //开始画线 if (i == 0) { cgcontextaddlinetopoint(line, w, 0); }else if (i == 1){ cgcontextaddlinetopoint(line, 0, w); }else if (i == 2){ cgcontextmovetopoint(line, 0, padding); cgcontextaddlinetopoint(line, w, padding); }else if (i == 3){ cgcontextmovetopoint(line, padding, 0); cgcontextaddlinetopoint(line, padding, w); } cgcontextstrokepath(line); imageview.image = uigraphicsgetimagefromcurrentimagecontext(); } } @end
4.collectionview布局和自定义item
#import <uikit/uikit.h> @interface sectionheaderviewcollectionreusableview : uicollectionreusableview @property(nonatomic, strong)uilabel *titlelabel; @end #import "sectionheaderviewcollectionreusableview.h" @implementation sectionheaderviewcollectionreusableview -(instancetype)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { [self createviews]; } return self; } -(void)createviews { _titlelabel = [[uilabel alloc]init]; [self addsubview:_titlelabel]; } -(void)layoutsubviews { [super layoutsubviews]; _titlelabel.frame = cgrectmake(20, 30, 375, 50); _titlelabel.font = [uifont systemfontofsize:20]; } @end collectionview的item #import <uikit/uikit.h> @interface mycollectionviewcell : uicollectionviewcell typedef enum : nsinteger { cellstyledefault = 0, cellstyleselected = 1, cellstyleadd = 2, }collectionviewcellstyle; @property(nonatomic, assign)collectionviewcellstyle cellstyle; @property(nonatomic, strong)uiimageview *photo; @property(nonatomic, strong)uiimageview *imageview; @property(nonatomic, strong)nsarray *array; @property(nonatomic, strong)nsmutablearray *dataarray; -(void)layoutsubviews; @end #import "mycollectionviewcell.h" @implementation mycollectionviewcell -(instancetype)initwithframe:(cgrect)frame { self = [super initwithframe:frame]; if (self) { _photo = [[uiimageview alloc]init]; _imageview = [[uiimageview alloc]init]; } return self; } -(void)layoutsubviews { [super layoutsubviews]; [_photo setframe:self.bounds]; _imageview.frame = self.bounds; switch (_cellstyle) { case cellstyledefault: self.layer.bordercolor = [uicolor colorwithred:0 green:0.68 blue:0.94 alpha:1].cgcolor; self.layer.maskstobounds = yes; self.layer.borderwidth = 1.8; //self.layer.cornerradius = 20; self.backgroundcolor = [uicolor whitecolor]; [self.contentview addsubview:_photo]; break; case cellstyleselected: self.layer.bordercolor = [uicolor colorwithred:0 green:0.68 blue:0.94 alpha:1].cgcolor; self.layer.maskstobounds = yes; self.layer.borderwidth = 1.8; //self.layer.cornerradius = 20; self.backgroundcolor = [uicolor colorwithred:0 green:0.68 blue:0.94 alpha:1]; [self.contentview addsubview:_photo]; break; case cellstyleadd: [self.imageview setimage:[uiimage imagenamed:@"addphoto.png"]]; self.backgroundcolor = [uicolor whitecolor]; [self.contentview addsubview:_imageview]; break; default: break; } } @end
5.model
#import <foundation/foundation.h> #import <uikit/uikit.h> @interface appmodel : nsobject @property (nonatomic, assign) bool is_open; @end #import "appmodel.h" @implementation appmodel @end //设置model是为了设置一个bool类型的变量,用来记录tableview的cell是否展开,从而进行reloadsection操作,进行动画展开或收缩.