IOS第八天(2:UITableViewController团购,点击底部,xib加载更多, 代理模式)

******* HMViewController.h

#import "HMViewController.h"
#import "HMTg.h"
#import "HMTgCell.h"
#import "HMTgFooterView.h"

@interface HMViewController () <HMTgFooterViewDelegate>
@property (nonatomic, strong) NSMutableArray *tgs;
@end

@implementation HMViewController

- (NSArray *)tgs
{
    if (_tgs == nil) _tgs = [HMTg tgs];  //数据转模型
    return _tgs;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.tableView.rowHeight = 80;
    
    // 调整边距,可以让表格视图让开状态栏
    self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
    
    // footerView
    // footerView的宽度会和表格整体宽度一致,只需要指定高度即可
//    self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd];
//    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 44)];
//    view.backgroundColor = [UIColor redColor];
//    self.tableView.tableFooterView = view;
    // 从XIB加载最后一个视图设置为footerView
    HMTgFooterView *footer = [HMTgFooterView footerView];
    // 视图控制器成为footerView的代理
    footer.delegate = self;
    self.tableView.tableFooterView = footer;
    
    self.tableView.tableHeaderView = [[[NSBundle mainBundle] loadNibNamed:@"HMTgHeadView" owner:nil options:nil] lastObject];
}

///** 隐藏状态栏 */
//- (BOOL)prefersStatusBarHidden
//{
//    return YES;
//}

#pragma mark - footerView的代理方法
/** 
 预处理指令
 #if 0
 所有代码都不会执行
 
 #endif
 */
#if 1
- (void)tgFooterViewDidDownloadButtonClick:(HMTgFooterView *)footerView   //代理来的方法
{
    // 加载数据
    NSLog(@"努力加载数据中....");
    
    // 向数组中添加数据,模拟网络加载完成之后的效果
    NSDictionary *dict = @{@"title": @"哈哈", @"icon": @"ad_00", @"price": @"100.2", @"buyCount": @"250"};
    HMTg *tg = [HMTg tgWithDict:dict];
    
    NSLog(@"加数据前 %d", self.tgs.count);
    
    [self.tgs addObject:tg];

    NSLog(@"加数据后 %d", self.tgs.count);
    // 刷新数据
//    [self.tableView reloadData];
    // 新建一个indexPath
    NSIndexPath *path = [NSIndexPath indexPathForRow:(self.tgs.count - 1) inSection:0];
    [self.tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle];
}
#endif

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 1. 创建cell
    HMTgCell *cell = [HMTgCell cellWithTableView:tableView];
    
    // 2. 通过数据模型,设置Cell内容,可以让视图控制器不需要了解cell内部的实现细节
    cell.tg = self.tgs[indexPath.row];
    
    return cell;
}

@end

***HMTgCell.m

#import "HMTgCell.h"
#import "HMTg.h"

@interface HMTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;
@end

@implementation HMTgCell

+ (instancetype)cellWithTableView:(UITableView *)tableView
{
    // 1. 可重用标示符
    static NSString *ID = @"Cell";
    // 2. tableView查询可重用Cell
    HMTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    // 3. 如果没有可重用cell
    if (cell == nil) {
        NSLog(@"加载XIB");
        // 从XIB加载自定义视图
        cell = [[[NSBundle mainBundle] loadNibNamed:@"HMTgCell" owner:nil options:nil] lastObject];
    }
    
    return cell;
}

- (void)setTg:(HMTg *)tg
{
    // setter方法中,第一句要赋值,否则要在其他方法中使用模型,将无法访问到
    _tg = tg;

    self.titleLabel.text = tg.title;
    self.iconView.image = [UIImage imageNamed:tg.icon];
    self.priceLabel.text = tg.price;
    self.buyCountLabel.text = tg.buyCount;
}

#pragma mark - 模板提供的方法
/** 
 初始化方法
 
 使用代码创建Cell的时候会被调用,如果使用XIB或者Storyboard,此方法不会被调用
 */
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        NSLog(@"%s", __func__);
    }
    return self;
}

/**
 从XIB被加载之后,会自动被调用,如果使用纯代码,不会被执行
 */
- (void)awakeFromNib
{
    NSLog(@"%s", __func__);
    self.contentView.backgroundColor = [UIColor clearColor];
}

/**
 Cell 被选中或者取消选中是都会被调用
 
 如果是自定义Cell控件,所有的子控件都应该添加到contentView中
 */
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    if (selected) {
        self.contentView.backgroundColor = [UIColor redColor];
    } else {
        self.contentView.backgroundColor = [UIColor greenColor];
    }
}

@end

*********HMTgCell.h

#import <UIKit/UIKit.h>
@class HMTg;

@interface HMTgCell : UITableViewCell
/** 团购的数据模型 */
@property (nonatomic, strong) HMTg *tg;

/** 提供一个类方法,可以快速创建 Cell */
+ (instancetype)cellWithTableView:(UITableView *)tableView;

@end

HMTgFooterView.h

#import <UIKit/UIKit.h>
@class HMTgFooterView;

@protocol HMTgFooterViewDelegate <NSObject>

@optional
/** 视图的下载按钮被点击 */
- (void)tgFooterViewDidDownloadButtonClick:(HMTgFooterView *)footerView;

@end

@interface HMTgFooterView : UIView

// 代理如果使用强引用,就会产生循环引用,造成控制器和子视图都无法被释放,造成内存泄露
@property (nonatomic, weak) id <HMTgFooterViewDelegate> delegate;

+ (instancetype)footerView;

@end

 

HMTgFooterView.m

#import "HMTgFooterView.h"

@interface HMTgFooterView()
@property (weak, nonatomic) IBOutlet UIButton *loadMoreButton;
@property (weak, nonatomic) IBOutlet UIView *tipsView;
@end

@implementation HMTgFooterView

+ (instancetype)footerView
{
    return [[[NSBundle mainBundle] loadNibNamed:@"HMTgFooterView" owner:nil options:nil] lastObject];
}

- (IBAction)loadMore
{
    NSLog(@"加载更多");
    // 1. 隐藏按钮
    self.loadMoreButton.hidden = YES;
    // 2. 显示提示视图
    self.tipsView.hidden = NO;

    // 延时执行命令,多线程GCD
    // 今后关于延时的操作,统一使用dispatch_after
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 块代码中的代码会在1.0秒之后执行
        
        // 3. 加载数据(从网络服务器加载,需要时间...)
        // view是用来显示数据的,用代理来实现!
        // 代理是用来监听的,发生某些事情的时候,通知"代理"-》控制器去"工作"->加载数据
        
        // 3.1 判断代理是否实现了协议方法
        if ([self.delegate respondsToSelector:@selector(tgFooterViewDidDownloadButtonClick:)]) {
            [self.delegate tgFooterViewDidDownloadButtonClick:self];
        }
        
        // 4. 加载完成数据
        self.loadMoreButton.hidden = NO;
        self.tipsView.hidden = YES;
    });
}

@end

 

posted @ 2015-08-07 16:30  iso  阅读(229)  评论(0编辑  收藏  举报