欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果

程序员文章站 2023-12-10 21:37:46
废话不多说了,直奔主题。 //需要的效果 1.设置window的根视图控制器为一个uitableviewcontroller #import...

废话不多说了,直奔主题。

//需要的效果

iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果

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

iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果

// 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];
}

iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果

-(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

iOS开发之tableView点击下拉扩展与内嵌collectionView上传图片效果

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操作,进行动画展开或收缩.