0821-TableView Cell(UITableviewController控件使用)(UITableviewController - 团购Cell+xib)(新浪微博 - 图文混合)(copy的使用)(内存)

0821-TableView Cell

----------

UITableviewController控件使用 

(开发中使用很频繁)

1、删除storyboard中原有的控制器

2、拖UITableViewController控件、勾选该控件属性 is initial view controller、删除该控件里的tableview cell

3、让viewController.h中的viewController:UITableViewController

可以自己新建一个ViewController(或者FFViewController) 继承 UITableViewController ,这时候自建的viewController中多了很多方法了 如实现了代理协议的方法    (得到了UITableViewController模板)

里面常用的方法都注释了 可以用来参考用     但不建议这么新建控制器  这么慢

4、让storyboard中控件指定类 ViewController

【   额外的

// 在ViewControlller.m-viewDidLoad方法中self.view就是self.tableView
    NSLog(@"%p %p", self.view, self.tableView);

---------

UITableviewController - 团购Cell+xib

1、self.tableView == self.view (赋值:tableView = view)在viewController对象包含了view属性对象

2、这里是已经完成的: 在tableView get方法中已经设置了dataSource和delegate = self (storyboard-tableViewController-tableView自动设置了datasource和delegate)

tableViewController已经遵守了tableViewDataSource协议

3、实现datasource协议 (2个require的协议 numberOfRowsInsection cell)

4、设置行高self.tableView.rowHeight = 80

5、隐藏状态栏

重写控制器方法 preferStartusBarHidden

 6、设置contentInset 让顶部下来20   (tableView继承自scrollView)

 7、新建一个xib (FFTgCell.xib)  拖一个UITableViewCell控件

 9、新建类 FFTgCell 继承 UITableViewCell

 10、指定xib-tableViewcell类为FFTgCell

11、连线 FFTgCell.h连线到.h中 (否则导入后 对象不能.出提示)

 cell控件中的imageView连线不能写成imageView

12、控制器协议实现方法cell方法中 返回xib中的cell

 

13、指定xib-FFTgCell的可重复使用标识符为 Cell字符串

FFTgCell.h m文件(FFTg对象数据给Cell视图 赋值)

-(void)setTg:(FFTg *)tg
{
    _tg = tg;
    self.titleLabel.text = tg.title;
    self.iconView.image = [UIImage imageNamed:tg.icon];
    self.priceLabel.text = tg.price;
    self.buyCountLabel.text = tg.buyCount;
    
}

 14、创建cell的类方法   instancetype

FFTgCell类 (UITabelViewCell类)初始化 方法执行 (FFTgCell.m中自动已经有这个方法了)

  代码初始化Cell对象 执行initWithStyle

  XIB加载初始化的Cell对象执行 awakeFromNib

     setSelected方法 选中和取消选中都执行   (切换背景很好用)  设置self.contentView  不能设置backGroundView   所有的Cell只能设置contentView不能用backGroundView

 15、tableFooterView 对象不用指定宽度

 16、新建FFTgFooterView.xib  FFTgFooterViewCell继承UIView

拖一个view到FFTgFooterView.xib中  指定这个view的类为FFTgFooterViewCell

 17、xib-view里拖一个button 连线方法loadMore

18、xibView中 小菊花(style设置white 勾选animation 和hide while hidden)和label(正在加载中)放到一个view中

19、loadMore方法中 加入一个延迟方法 dispatch_after(GCD)快代码

 

tableView.reloadData

//  ViewController.m

#import "ViewController.h"
#import "FFTg.h"
#import "FFTgCell.h"
#import "FFTgFooterView.h"
@interface ViewController () <FFTgFooterViewDelegate>

@property (nonatomic,strong) NSMutableArray *tgs;

@end

@implementation ViewController

-(NSMutableArray *)tgs
{
    if (_tgs == nil) {
        _tgs = [FFTg tgs];
    }
    return _tgs;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.rowHeight = 80;
    self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
    
    // 设置footerViewxib ->footerview视图类-》实例化footerView类 》设置tableView.tableFooterView
    FFTgFooterView *footerView = [FFTgFooterView tgFooterView];
    footerView.delegate = self;
    
    self.tableView.tableFooterView = footerView;
    
    self.tableView.tableHeaderView = [[[NSBundle mainBundle] loadNibNamed:@"FFTgHeaderView" owner:nil options:nil] lastObject];
    
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    FFTgCell *cell = [FFTgCell tgCellWithTableView:tableView];
    
    cell.tg = self.tgs[indexPath.row]; //给cell赋值
    
    return cell;
}
// ----
-(void)tgFooterViewDidClickDownButton:(FFTgFooterView *)footerView
{
    NSLog(@"从网上获取数据");
    // 网上拿到的数据为
    NSDictionary *dict = @{@"title":@"橘子",@"icon":@"ad_00",@"price":@"100.2",@"buyCount":@"200"};
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 获取数据后执行
        // 数据字典转 交给模型对象
        FFTg *tg = [FFTg tgWithDict:dict];
        // 数据模型数据 增加一条数据
        [self.tgs addObject:tg];
        
        // 新建一个indexPath
        NSIndexPath *path = [NSIndexPath indexPathForItem:(self.tgs.count-1) inSection:0];
        [self.tableView insertRowsAtIndexPaths:@[path] withRowAnimation:UITableViewRowAnimationMiddle];
       // 调整加载显示
        [footerView reloadStop];
    });
}


@end
ViewController.m

 

//  FFTgFooterView.h

#import <UIKit/UIKit.h>
@class FFTgFooterView;
@protocol FFTgFooterViewDelegate <NSObject>

@optional
//代理方法
- (void)tgFooterViewDidClickDownButton:(FFTgFooterView *)footerView;

@end

@interface FFTgFooterView : UIView


//代理属性
@property (nonatomic,weak) id <FFTgFooterViewDelegate> delegate;

+ (instancetype)tgFooterView;

- (void)reloadStop;

@end
FFTgFooterView.h

 

//  FFTgFooterView.m

#import "FFTgFooterView.h"

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

@end
//--------
@implementation FFTgFooterView


- (IBAction)loadMore {
    NSLog(@"加载");
    // 加载数据
    
    // 隐藏loadMorebutton 显示view
    self.loadMoreButton.hidden = YES;
    self.tipsView.hidden = NO;
    // 延迟2秒 -》 显示tipsView  隐藏loadMore
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//            self.loadMoreButton.hidden = NO;
//            self.tipsView.hidden = YES;
//    });
    // 判断是否实现了代理协议
    if ([self.delegate respondsToSelector:@selector(tgFooterViewDidClickDownButton:)]) {
        //通知代理  执行了点击加载操作
        [self.delegate tgFooterViewDidClickDownButton:self];
    }
    
}

- (void)reloadStop
{
    self.loadMoreButton.hidden = NO;
    self.tipsView.hidden = YES;
}

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

@end
FFTgFooterView.m

 

-------------

新浪微博 - 图文混合

1、文件夹目录抽取

2、根据plist 新建模型类

3、storyboard拖 tableViewController  保留里面的Cell

4、代码创建FFTableViewCell

 (

  新建UIStatusCell类继承 UITabelViewCell

)

5、1模型对象 交给cell属性(模型对象类型),  2利用cell属性setter方法  给cell标准属性设置值 ,设置cell位置

6、单个cell内部控件的位置计算

boundingRectWithSize 计算字符串的size  x,y=0   宽度高度根据字体的大小自动计算合适的高度

UIKit框架第一个头文件中有字体的属性常量(如:粗体等)

7、cell默认字体大小是17号  初始化的时候需要指定字体大小   方便boundingRectWithSize计算size

8、label文本多行显示属性

textLabel.numberOfLine = 0;

9、vipView懒加载中的vip图片是隐藏的  vip的是红色的 非vip的图片是黑色的    

后续cell根据判断是否为vip来显示vip图标或者不显示

10、图片imageNamed:nil解决方法

if(self.status.picture.length >0){

  //给pictureView设置图片

    self.pictureView.hidden = NO;

  self.pictureView.image = [UIImage imageNamed:self.status.picture];

}else{

  //不给pictureView设置图片

  self.pictureView.hidden = YES;

}

11、hieghtForRow计算每行的行高,比cell先执行  所以需要创建一个frameModel来计算行高数据  并将计算结果保存起来

weiboFrame 模型保存每行数据的frame

 

其他:

(

可充用单元格设置的更简单方法 - 官方推荐

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    // 为tableView注册可重用单元格
    [self.tableView registerClass:[HMStatusCell class] forCellReuseIdentifier:ID];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

HMStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];

}

storyboard中设置tableview-tableviewcell 设置identifier 为 Cell

)

 

-------

copy的使用

NSString指针变量指向的空间内容不可变

copy得到新地址与否
(copy操作得到新地址与否 [array copy]复制给NSString类型变量时候 不能得到新地址        其他都能得到新地址)

NSMutableString *str  [str copy]  得到了新地址 但是变成了NSString类型了

所以@property (nonatomic,copy) NSMutableString *string是错误的【这里执行了copy操作 变成了NSString了  反而不能修改值了】

 

 

新建commondLine  选择Fundation框架

可变 不可不按针对Fundation框架

 NSString Block都使用copy @Property (nonatomic,copy) NSString *str; 默认都做了copy操作 (str拿到一个新地址 NSString类型地址内容不可修改)     

(如果用strong就是潜复制 拿到的是指针 retain计数器+1)(指针就是地址)

自定义类 copy都得到新地址

-(NSArray *)statusFrames
{
    if (_statusFrames == nil) {
        NSString *fullPath = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:fullPath];
        NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictArray.count];
        for (NSDictionary *dict in dictArray) {
            NJWeibo *weibo = [NJWeibo weiboWithDict:dictArray];
            //根据模型数据创建frame模型
            NJWeiboFrame *wbF = [[NJWeiboFrame alloc] init];
            wbF.weibo = weibo;
            [models addObject:wbF];
        }
        self.statusFrames = [models copy];  // copy得到一个新地址  可变数组和不可变数组间通过copy才不报错 否则报错 
    }
    return nil;
}

 

//  Person.h

#import <Foundation/Foundation.h>

/**
 NSString 
 Block
 
 都使用copy属性,copy属性,在赋值时,会默认做一次copy操作,“不可变的类型”
 
 strong相当于MRC中的retain,在赋值时,只是引用计数+1
 */
@interface Person : NSObject

@property (nonatomic, copy) NSString *name;
// *** 对于"可变类型"的属性,不要使用copy描述符定义,否则赋值后,就是不可变了!
//@property (nonatomic, copy) NSMutableString *name;

@property (nonatomic, assign) int age;

// 以下两个方法,方便对象的实例化
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)personWithDict:(NSDictionary *)dict;

- (id)copyWithZone:(NSZone *)zone;

@end
Person.h

 

//  Person.m

#import "Person.h"

/**
 自定义对象要实现copy功能
 1> 遵守NSCopying协议,本质上就是方便程序员编写代码时候,有快捷提示
 2> 实现- (id)copyWithZone:(NSZone *)zone
 */
@implementation Person

// zone,区域,极少用
// 所有的copy方法,最终都会调用copyWithZone
// copy操作将一个对象,复制(当前对象的属性)给一个新的对象
- (id)copyWithZone:(NSZone *)zone
{
    // 1> 实例化对象,self 是对象
    // self.class能够保证继承的子类同样使用copy方法
    Person *p = [[self.class alloc] init];
    
    // 2> 给属性赋值
    p.name = self.name;
    p.age = self.age;
    
    // 3> 返回新对象
    return p;
}

- (instancetype)initWithDict:(NSDictionary *)dict
{
    self = [super init];
    if (self) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}

+ (instancetype)personWithDict:(NSDictionary *)dict
{
    // self 是 class
    return [[self alloc] init];
}

- (NSString *)description
{
    return [NSString stringWithFormat:@"<%@, %p> {name: %@, age: %@}", self.class, self, self.name, @(self.age)];
}

@end
Person.m

 

//  Student.h

#import "Person.h"

@interface Student : Person
// 学号
@property (nonatomic, copy) NSString *no;
@end
Student.h

 

//  Student.m

#import "Student.h"

@implementation Student

- (id)copyWithZone:(NSZone *)zone
{
    // 直接调用父类的copy方法
    Student *s = [super copyWithZone:zone];
    
    // 赋值,只需要给子类的属性赋值即可!
    s.no = self.no;
    
    // 返回
    return s;
}

@end
Student.m

 

工作中常用的自定义对象copy

//Person.m

- (id)copyWithZone:(NSZone *)zone //zone参数不用管 极少用到 内存用的
{
    // 1> 实例化对象,self 是对象
    // self.class能够保证继承的子类同样使用copy方法
    Person *p = [[self.class alloc] init];// [[不能用Person alloc] init]  子类Person继承后 这里的self.class就是Student类   这时候p的真实类型是Person类对象
    
    // 2> 给属性赋值
    p.name = self.name;
    p.age = self.age;
    
    // 3> 返回新对象
    return p;
}

 

//Student.m

- (id)copyWithZone:(NSZone *)zone
{
    // 直接调用父类的copy方法
    Student *s = [super copyWithZone:zone];
    
    // 赋值,只需要给子类的属性赋值即可!
    s.no = self.no;
    
    // 返回
    return s;
}

 -----------

内存  -

iphone引用程序栈区域内存1M 

 

oc中没有垃圾回收器  (以前MAC是有的)

p=nil p是指向NULL的空对象   调用任何方法不会报错

----------------

其他注意点

约定:Cell设置contentView 不能设置backgroundView

NSMutableArray 才能添加 对象

    if ([self.delegate respondsToSelector:@selector(tgFooterViewDidClickDownButton:)]) {
        //通知代理  执行了点击加载操作
        [self.delegate tgFooterViewDidClickDownButton:self];
    }

 

[[[NSBundle mainBundle] loadNibNamed:@"FFTgFooterView" owner:nil options:nil] lastObject];

posted @ 2016-02-27 21:53  海龙王来了  阅读(181)  评论(0)    收藏  举报
友情链接:废钢破碎机  带式压滤机