那么今天给同学们带来一个团购的小demo,主要包括图片轮播器,自定义cell,以及刷新表格,其中涉及很多基础和细节的东西,那么废话不多说,先看效果图,直接上代码!
//
// ZZTg.h
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ZZTg : NSObject
/**
* 标题
*/
@property (nonatomic,copy) NSString *title;
/**
* 价格
*/
@property (nonatomic,copy) NSString *price;
/**
* 图片
*/
@property (nonatomic,copy) NSString *icon;
/**
* 购买人数
*/
@property (nonatomic,copy) NSString *buyCount;
+ (instancetype)tgWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
//
// ZZTg.m
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTg.h"
@implementation ZZTg
+ (instancetype)tgWithDict:(NSDictionary *)dict
{
return [[selfalloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [superinit]) {
#pragma mark - kvc 直接字典转模型
[selfsetValuesForKeysWithDictionary:dict];
}
returnself;
}
@end
//
// ZZTgHeader.h
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface ZZTgHeader : NSObject
/**
* 图标
*/
@property (nonatomic,copy) NSString *icon;
+ (instancetype)headerWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
//
// ZZTgHeader.m
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTgHeader.h"
@implementation ZZTgHeader
+ (instancetype)headerWithDict:(NSDictionary *)dict
{
return [[selfalloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [superinit]) {
[selfsetValuesForKeysWithDictionary:dict];
}
returnself;
}
@end
//
// ZZTgCell.h
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@class ZZTg;
@interface ZZTgCell :UITableViewCell
/**
* 团购模型
*/
@property (nonatomic,strong) ZZTg *tg;
/**
* 通过一个tableView来创建一个cell
*/
+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end
//
// ZZTgCell.m
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTgCell.h"
#import "ZZTg.h"
@interface ZZTgCell()
/**
* 图标
*/
@property (nonatomic,weak) UIImageView *iconImg;
/**
* 标题
*/
@property (nonatomic,weak) UILabel *titleLabel;
/**
* 价格
*/
@property (nonatomic,weak) UILabel *priceLabel;
/**
* 购买数
*/
@property (nonatomic,weak) UILabel *buyLabel;
@end
@implementation ZZTgCell
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
staticNSString *ID = @"tg";
ZZTgCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if (cell ==nil) {
cell = [[ZZTgCellalloc] initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:ID];
}
return cell;
}
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [superinitWithStyle:style reuseIdentifier:reuseIdentifier];
UIImageView *iconImg = [[UIImageViewalloc] init];
[self.contentViewaddSubview:iconImg];
self.iconImg = iconImg;
UILabel *titleLabel = [[UILabelalloc] init];
titleLabel.font = [UIFontboldSystemFontOfSize:16.0f];
[self.contentViewaddSubview:titleLabel];
self.titleLabel = titleLabel;
UILabel *priceLabel = [[UILabelalloc] init];
priceLabel.font = [UIFontsystemFontOfSize:15.5f];
priceLabel.textColor = [UIColorcolorWithRed:239 /255.0 green:134 /255.0 blue:130 /255.0 alpha:1.0];
[self.contentViewaddSubview:priceLabel];
self.priceLabel = priceLabel;
UILabel *buyLabel = [[UILabelalloc] init];
buyLabel.font = [UIFontsystemFontOfSize:14.0f];
buyLabel.textColor = [UIColorlightGrayColor];
buyLabel.textAlignment =NSTextAlignmentRight;
[self.contentViewaddSubview:buyLabel];
self.buyLabel = buyLabel;
returnself;
}
/**
* 拿到真实的尺寸进行布局
*/
- (void)layoutSubviews
{
[superlayoutSubviews];
CGFloat iconImgX =10;
CGFloat iconImgY = iconImgX;
CGFloat iconImgW =110;
CGFloat iconImgH =self.contentView.frame.size.height - iconImgX * 2;
self.iconImg.frame =CGRectMake(iconImgX, iconImgY, iconImgW, iconImgH);
CGFloat titleLabelX = iconImgX + iconImgW + iconImgX;
CGFloat titleLabelY = iconImgY;
CGFloat titleLabelW =self.contentView.frame.size.width - titleLabelX;
CGFloat titleLabelH =30;
self.titleLabel.frame =CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
CGFloat priceLabelH = titleLabelH;
CGFloat priceLabelX = titleLabelX;
CGFloat priceLabelY =self.contentView.frame.size.height - iconImgY - priceLabelH;
CGFloat priceLabelW =50;
self.priceLabel.frame =CGRectMake(priceLabelX, priceLabelY, priceLabelW, priceLabelH);
CGFloat buyLabelW =100;
CGFloat buyLabelX =self.contentView.frame.size.width - buyLabelW - 10;
CGFloat buyLabelY = priceLabelY;
CGFloat buyLabelH = priceLabelH;
self.buyLabel.frame =CGRectMake(buyLabelX, buyLabelY, buyLabelW, buyLabelH);
}
- (void)setTg:(ZZTg *)tg
{
_tg = tg;
// 0.设置数据
[selfsetUpData];
}
- (void)setUpData
{
self.iconImg.image = [UIImageimageNamed:self.tg.icon];
self.titleLabel.text =self.tg.title;
self.priceLabel.text = [NSStringstringWithFormat:@"¥%@",self.tg.price];
self.buyLabel.text = [NSStringstringWithFormat:@"%@人已购买",self.tg.buyCount];
}
@end
//
// ZZTgHeaderView.h
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZTgHeaderView : UIView
/**
* 图片的数组
*/
@property (nonatomic,strong) NSMutableArray *imgsArr;
+ (instancetype)tgHeaderView;
@end
//
// ZZTgHeaderView.m
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTgHeaderView.h"
#import "ZZTgHeader.h"
@interface ZZTgHeaderView()<UIScrollViewDelegate>
/**
* 图片轮播器
*/
@property (nonatomic,weak) UIScrollView *scrollView;
/**
* 分页
*/
@property (nonatomic,weak) UIPageControl *pageControl;
/**
* 定时器
*/
@property (nonatomic,strong) NSTimer *timer;
@end
@implementation ZZTgHeaderView
+ (instancetype)tgHeaderView
{
return [[selfalloc] init];
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [superinitWithFrame:frame]) {
[selfsetUpSubViews];
}
returnself;
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
if (self = [superinitWithCoder:decoder]) {
[selfsetUpSubViews];
}
returnself;
}
/**
* 初始化所有的子控件并且进行一次性设置
*/
- (void)setUpSubViews
{
UIScrollView *scrollView = [[UIScrollViewalloc] init];
scrollView.delegate =self;
scrollView.showsHorizontalScrollIndicator =NO;
scrollView.pagingEnabled =YES;
[selfaddSubview:scrollView];
self.scrollView = scrollView;
UIPageControl *pageControl = [[UIPageControlalloc] init];
pageControl.currentPageIndicatorTintColor = [UIColorcolorWithRed:253 /255.0 green:98 /255.0 blue:42 /255.0 alpha:1.0];
pageControl.pageIndicatorTintColor = [UIColorcolorWithRed:189 /255.0 green:189 /255.0 blue:189 /255.0 alpha:1.0];
[selfaddSubview:pageControl];
self.pageControl = pageControl;
}
/**
* 拿到真实尺寸进行布局
*/
- (void)layoutSubviews
{
[superlayoutSubviews];
CGFloat scrollViewX =10;
CGFloat scrollViewY =0;
CGFloat scrollViewW =self.frame.size.width - scrollViewX * 2;
CGFloat scrollViewH =130;
self.scrollView.frame =CGRectMake(scrollViewX, scrollViewY, scrollViewW, scrollViewH);
CGFloat pageControlH =40;
CGFloat pageControlW =60;
CGFloat pageControlX =self.frame.size.width - pageControlW - scrollViewX * 2;
CGFloat pageControlY = scrollViewH -30;
self.pageControl.frame =CGRectMake(pageControlX, pageControlY, pageControlW, pageControlH);
#warning - 这里才能拿到scrollView的滚动区域
self.scrollView.contentSize = CGSizeMake(self.imgsArr.count * self.scrollView.frame.size.width,0);
}
- (void)setImgsArr:(NSMutableArray *)imgsArr
{
_imgsArr = imgsArr;
// 0.设置图片
[selfsetUpImgsView];
// 1.设置数据
[selfsetUpData];
#warning - 只有在这里才能启动定时器因为定时器要拿到真实的尺寸和图片数据(所以这里要自己打断点开方法执行顺序)
// 2.启动定时器
[selfaddTimer];
}
/**
* 添加轮播起图片到scrollView
*/
- (void)setUpImgsView
{
CGFloat imgViewY =0;
CGFloat imgViewW =self.frame.size.width -20;
CGFloat imgViewH =130;
for (int i =0; i < self.imgsArr.count; i++) {
ZZTgHeader *headerImg =self.imgsArr[i];
UIImageView *imgView = [[UIImageViewalloc] init];
CGFloat imgViewX = i * imgViewW;
imgView.frame =CGRectMake(imgViewX, imgViewY, imgViewW, imgViewH);
imgView.image = [UIImageimageNamed:headerImg.icon];
[self.scrollViewaddSubview:imgView];
}
}
/**
* 设置数据
*/
- (void)setUpData
{
self.pageControl.numberOfPages = self.imgsArr.count;
}
/**
* 添加定时器
*/
- (void)addTimer
{
self.timer = [NSTimerscheduledTimerWithTimeInterval:2.0target:selfselector:@selector(nextImage)userInfo:nilrepeats:YES];
#warning - 如果不将定时器添加到线程中那么你执行别的操作的时候他就不会分配多的内存来处理定时器
[[NSRunLoopcurrentRunLoop] addTimer:self.timerforMode:NSRunLoopCommonModes];
}
- (void)nextImage
{
// 1.增加pageControl的页码
NSInteger page =0;
if (self.pageControl.currentPage == self.imgsArr.count -1) {
page = 0;
} else {
page = self.pageControl.currentPage +1;
}
// 2.计算scrollView滚动的位置
CGFloat offsetX = page *self.scrollView.frame.size.width;
CGPoint offset =CGPointMake(offsetX, 0);
[self.scrollViewsetContentOffset:offset animated:YES];
}
/**
* 移除定时器
*/
- (void)removeTimer
{
// 关闭定时器
[self.timerinvalidate];
// 并且要将他清空
self.timer =nil;
}
#pragma mark - 代理方法
/**
* 当scrollView正在滚动就会调用
*/
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 根据scrollView的滚动位置决定pageControl显示第几页
CGFloat scrollW = scrollView.frame.size.width;
int page = (scrollView.contentOffset.x + scrollW *0.5) / scrollW;
self.pageControl.currentPage = page;
}
/**
* 开始拖拽的时候调用
*/
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// 停止定时器(一旦定时器停止了,就不能再使用)
[selfremoveTimer];
}
/**
* 停止拖拽的时候调用
*/
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
// 开启定时器
[selfaddTimer];
}
@end
//
// ZZTgFooterView.h
// 07-团购
//
// Created by 周昭 on 16/11/25.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@class ZZTgFooterView;
@protocol ZZTgFooterViewDelegate <NSObject>
@optional
- (void)tgFooterView:(ZZTgFooterView *)footerView didClickLoadingBtn:(UIButton *)loadBtn;
@end
@interface ZZTgFooterView : UIView
+ (instancetype)tgFooterView;
@property (nonatomic,weak) id <ZZTgFooterViewDelegate> delegate;
@end
//
// ZZTgFooterView.m
// 07-团购
//
// Created by 周昭 on 16/11/25.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTgFooterView.h"
@interface ZZTgFooterView()
/**
* 点击加载按钮
*/
@property (nonatomic,weak) UIButton *loadBtn;
/**
* 包装菊花和文字
*/
@property (nonatomic,weak) UIView *contentView;
/**
* 菊花
*/
@property (nonatomic,weak) UIActivityIndicatorView *indicatorView;
/**
* 加载文字
*/
@property (nonatomic,weak) UILabel *loadLabel;
@end
@implementation ZZTgFooterView
+ (instancetype)tgFooterView
{
return [[selfalloc] init];
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [superinitWithFrame:frame]) {
[selfsetUpSubViews];
}
returnself;
}
- (instancetype)initWithCoder:(NSCoder *)decoder
{
if (self = [superinitWithCoder:decoder]) {
[selfsetUpSubViews];
}
returnself;
}
/**
* 初始化所有子控件&进行一次性设置
*/
- (void)setUpSubViews
{
UIButton *loadBtn = [[UIButtonalloc] init];
loadBtn.layer.cornerRadius =5;
loadBtn.layer.masksToBounds =YES;
loadBtn.backgroundColor = [UIColorcolorWithRed:189 /255.0 green:189 /255.0 blue:189 /255.0 alpha:1.0];
[loadBtn setTitle:NSLocalizedString(@"加载更多",nil) forState:UIControlStateNormal];
[loadBtn setTitleColor:[UIColorwhiteColor] forState:UIControlStateNormal];
[loadBtn addTarget:selfaction:@selector(loadBtnClick:)forControlEvents:UIControlEventTouchUpInside];
[selfaddSubview:loadBtn];
self.loadBtn = loadBtn;
UIView *contentView = [[UIViewalloc] init];
contentView.hidden =YES;
[selfaddSubview:contentView];
self.contentView = contentView;
UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorViewalloc] init];
indicatorView.activityIndicatorViewStyle =UIActivityIndicatorViewStyleGray;
[contentView addSubview:indicatorView];
self.indicatorView = indicatorView;
UILabel *loadLabel = [[UILabelalloc] init];
loadLabel.text =NSLocalizedString(@"Z哥正在玩命加载中...",nil);
loadLabel.textColor = [UIColorlightGrayColor];
loadLabel.font = [UIFontsystemFontOfSize:15.5f];
[contentView addSubview:loadLabel];
self.loadLabel = loadLabel;
}
/**
* 拿到真实的尺寸并且进行设置
*/
- (void)layoutSubviews
{
[superlayoutSubviews];
CGFloat loadBtnX =10;
CGFloat loadBtnY =0;
CGFloat loadBtnW =self.frame.size.width - loadBtnX * 2;
CGFloat loadBtnH =self.frame.size.height;
self.loadBtn.frame =CGRectMake(loadBtnX, loadBtnY, loadBtnW, loadBtnH);
self.contentView.frame =self.loadBtn.frame;
CGFloat indicatorViewX =self.frame.size.width *0.25;
CGFloat indicatorViewY =self.frame.size.height *0.5;
CGFloat indicatorViewW =30;
CGFloat indicatorViewH = indicatorViewW;
self.indicatorView.center =CGPointMake(indicatorViewX, indicatorViewY);
self.indicatorView.bounds =CGRectMake(0,0, indicatorViewW, indicatorViewH);
CGFloat loadLabelW =150;
CGFloat loadLabelX = indicatorViewX + indicatorViewW + loadLabelW *0.5 + 10;
CGFloat loadLabelY = indicatorViewY;
CGFloat loadLabelH =30;
self.loadLabel.center =CGPointMake(loadLabelX, loadLabelY);
self.loadLabel.bounds =CGRectMake(0,0, loadLabelW, loadLabelH);
}
/**
* 点击加载按钮
*/
- (void)loadBtnClick:(UIButton *)loadBtn
{
// 1.隐藏加载按钮
self.loadBtn.hidden =YES;
// 2.显示菊花的view
self.contentView.hidden =NO;
[self.indicatorViewstartAnimating];
// 3.显示更多的数据
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 *NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
// 4.通知代理
if ([self.delegaterespondsToSelector:@selector(tgFooterView:didClickLoadingBtn:)]) {
[self.delegatetgFooterView:selfdidClickLoadingBtn:loadBtn];
}
// 5.显示按钮
self.loadBtn.hidden =NO;
// 6.隐藏菊花的view
self.contentView.hidden =YES;
[self.indicatorViewstopAnimating];
});
}
@end
//
// ZZTgTableViewController.h
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface ZZTgTableViewController :UITableViewController
@end
//
// ZZTgTableViewController.m
// 07-团购
//
// Created by 周昭 on 16/11/22.
// Copyright © 2016年 HT_Technology. All rights reserved.
//
#import "ZZTgTableViewController.h"
#import "ZZTgCell.h"
#import "ZZTg.h"
#import "ZZTgHeaderView.h"
#import "ZZTgHeader.h"
#import "ZZTgFooterView.h"
@interface ZZTgTableViewController()<ZZTgFooterViewDelegate>
/**
* 展示团购的数量
*/
@property (nonatomic,strong) NSMutableArray *tgs;
/**
* 展示图片轮播
*/
@property (nonatomic,strong) NSMutableArray *tgHeaders;
@end
@implementation ZZTgTableViewController
- (NSMutableArray *)tgs
{
if (_tgs ==nil) {
// 1.获得plist的全路径
NSString *path = [[NSBundlemainBundle] pathForResource:@"tgs.plist"ofType:nil];
// 2.加载数组
NSArray *dictArr = [NSArrayarrayWithContentsOfFile:path];
// 3.将dictArr中所有的字典转成模型对象,放到新的数组中
NSMutableArray *arr = [NSMutableArrayarray];
for (NSDictionary *dictin dictArr) {
// 3.1创建模型对象
ZZTg *tg = [ZZTgtgWithDict:dict];
// 3.2添加模型对象到数组中
[arr addObject:tg];
}
// 4.赋值
_tgs = arr;
}
return_tgs;
}
- (NSMutableArray *)tgHeaders
{
if (_tgHeaders ==nil) {
// 1.获得plist的全路径
NSString *path = [[NSBundlemainBundle] pathForResource:@"tgHeaders.plist"ofType:nil];
// 2.加载数组
NSArray *dictArr = [NSArrayarrayWithContentsOfFile:path];
// 3.将dictArr中所有的字典转成模型对象,放到新的数组中
NSMutableArray *arr = [NSMutableArrayarray];
for (NSDictionary *dictin dictArr) {
// 3.1创建模型对象
ZZTgHeader *tg = [ZZTgHeaderheaderWithDict:dict];
// 3.2添加模型对象到数组中
[arr addObject:tg];
}
// 4.赋值
_tgHeaders = arr;
}
return_tgHeaders;
}
- (void)viewDidLoad
{
[superviewDidLoad];
[selfsetUpSubViews];
}
/**
* 初始化所有子控件
*/
- (void)setUpSubViews
{
// 1.让tableView自身的y值往下移20
self.tableView.contentInset =UIEdgeInsetsMake(20,0, 0,0);
// 2.设置行高
self.tableView.rowHeight =100;
// 3.创建轮播起
[selfsetUpHeaderView];
// 4.创建底部的加载view
[selfsetUpFooterView];
}
/**
* 创建头部轮播器
*/
- (void)setUpHeaderView
{
ZZTgHeaderView *header = [ZZTgHeaderViewtgHeaderView];
header.frame =CGRectMake(0,0, self.view.frame.size.width,140);
header.imgsArr =self.tgHeaders;
self.tableView.tableHeaderView = header;
}
/**
* 创建底部的加载view
*/
- (void)setUpFooterView
{
ZZTgFooterView *footer = [ZZTgFooterViewtgFooterView];
footer.delegate =self;
footer.frame =CGRectMake(0,0, self.view.frame.size.width,40);
self.tableView.tableFooterView = footer;
}
#pragma mark - footerView的代理方法
- (void)tgFooterView:(ZZTgFooterView *)footerView didClickLoadingBtn:(UIButton *)loadBtn
{
// 1.随机添加一条数据
NSInteger index =arc4random() % self.tgs.count;
ZZTg *tg =self.tgs[index];
[self.tgsaddObject:tg];
// 2.刷新表格
[self.tableViewreloadData];
}
#pragma mark - 数据源方法
/**
* 一共有多少行数据
*/
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.tgs.count;
}
/**
* 每一行显示怎样的cell
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
ZZTgCell *cell = [ZZTgCellcellWithTableView:tableView];
// 2.给cell传递模型数据
cell.tg =self.tgs[indexPath.row];
return cell;
}
/**
* 取消选中
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPathanimated:YES];
}
@end