貓貓分享,必須精品
素材代碼地址:http://blog.csdn.net/u013357243/article/details/44976175
原文地址:http://blog.csdn.net/u013357243?viewmode=contents
1> 創(chuàng)建自定義Cell,繼承自UITableViewCell
2> 根據(jù)需求,肯定控件,并定義屬性
3> 用getter方法完成控件的實(shí)例化,只創(chuàng)建并添加到contentView,不處理位置
4> 定義1個(gè)模型屬性,通過setter方法,設(shè)置cell的顯示
設(shè)置大小由文字的長(zhǎng)度決定
用字符串方法:[@"" boundingRectWithSize:(CGSize) options:(NSStringDrawingOptions) attributes:(NSDictionary *) context:(NSStringDrawingContext *)]
//boundingRectWithSize計(jì)算給定文字字符串所占的區(qū)域,返回是1個(gè)x,y為0的CGRect
// 如果要計(jì)算多行的準(zhǔn)確高度需要傳入
// options:NSStringDrawingUsesLineFragmentOrigin
//attribbutes:dict 用于指定字體的相干屬性的字典。UIKit框架的第1個(gè)頭文件ps 這個(gè)頭文件不記很難找
// context :nil
#define kNameFont [UIFont systemFontOfSize:14]
NSDictionary *nameDict = @{NSFontAttributeName:kNameFont};
CGRect nameFrame = [self.status.name boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:nameDict context:nil];
要用到代理方法的:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
計(jì)算行高的方法,會(huì)在加載表格數(shù)據(jù)時(shí),有多少行計(jì)算多少次 contentSize
問題:此方法履行的時(shí)候,cell還沒有被實(shí)例化!
但是:行高計(jì)算是在實(shí)例化cell時(shí),通過設(shè)置status屬性,計(jì)算=》有了status模型,就能夠知道行高 !
問題:如何在cell實(shí)例化之前,取得行高?
解決方法:通過status可以計(jì)算得到行高! = 》再建立1個(gè)模型,專門計(jì)算所有控件的位置
正告:file:///Users/apple/Desktop/%E5%AD%A6%E4%B9%A0/%E4%BA%8C%E6%9C%9F%E5%AD%A6%E4%B9%A0/Day07/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9AUI/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9AUI/Base.lproj/Main.storyboard: warning: Unsupported Configuration: Prototype table cells must have reuse identifiers
正告:原形單元格必須又1個(gè)可重用標(biāo)示符
解決辦法是在Cell中的Identfier加入可重用標(biāo)示符
然后1定要關(guān)聯(lián)cell的class
――這兩部可以用1行代碼來代替
//為tableView注冊(cè)可重用單元格
[self.tableView registerClass:[NYStatusCell class] forCellReuseIdentifier:ID];
這時(shí)候候我們注釋
// if (cell == nil) {
// cell = [[NYStatusCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
// }
也能夠運(yùn)行了
在Storyboard中指定了可重用標(biāo)示符,同時(shí)指定了Cell的類是NYStatusCell,系統(tǒng)會(huì)為tableView注冊(cè)1個(gè)原形cell,專門用來做可重用單元格,1旦緩沖區(qū)不存在可重用單元格,系統(tǒng)會(huì)使用原形Cell新實(shí)例化1個(gè)Cell供程序使用!
因此如果在Storyb中,注冊(cè)了原形Cell,就不需要做 cell == nil 的判斷了
注意:這些在iOS6以后才有的。
這個(gè)小項(xiàng)目主要由這些類組成
MVC各自負(fù)責(zé)各自的東西
Model有兩個(gè)模型,1個(gè)是Status主要負(fù)責(zé)所有數(shù)據(jù)
Status中有
@property (nonatomic, copy)NSString *text;
@property (nonatomic, copy)NSString *icon;
@property (nonatomic, copy)NSString *name;
@property (nonatomic, assign)BOOL vip;
@property (nonatomic, copy) NSString *picture;
這些屬性主要包括頭像,昵稱,vip圖標(biāo),正文,圖片
StatusFrame模型主要負(fù)責(zé)寄存每個(gè)組件在cell所要寄存的位置
//提高安全性能:+readonly
@property (nonatomic, assign, readonly)CGRect textF;
@property (nonatomic, assign, readonly)CGRect iconF;
@property (nonatomic, assign, readonly)CGRect nameF;
@property (nonatomic, assign, readonly)CGRect vipF;
@property (nonatomic, assign, readonly)CGRect pictureF;
/**行高*/
@property (nonatomic, assign)CGFloat cellHeight;
/**所有控件的尺寸都可以通過Status來計(jì)算得出*/
@property (nonatomic, strong)NYStatus *status;
//ps:新建iOS交換學(xué)習(xí)群:304570962
可以加貓貓QQ:1764541256 或則微信znycat
讓我們1起努力學(xué)習(xí)吧。
原文:http://blog.csdn.net/u013357243?viewmode=contents
// NYViewController.m
// 新浪微博UI
//
// Created by apple on 15⑷⑻.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYViewController.h"
#import "NYStatus.h"
#import "NYStatusCell.h"
#import "NYStatusFrame.h"
@interface NYViewController ()
@property (nonatomic, strong) NSArray *statusFrames;
@end
@implementation NYViewController
static NSString *ID = @"Cell";
/**懶加載數(shù)據(jù)*/
-(NSArray *)statusFrames
{
if (_statusFrames == nil) {
_statusFrames = [NYStatusFrame statusFrames];
}
return _statusFrames;
}
-(void)viewDidLoad
{
[super viewDidLoad];
self.tableView.contentInset = UIEdgeInsetsMake(20, 0, 0, 0);
//為tableView注冊(cè)可重用單元格
[self.tableView registerClass:[NYStatusCell class] forCellReuseIdentifier:ID];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - 數(shù)據(jù)源方法
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.statusFrames.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
/**
在Storyboard中指定了可重用標(biāo)示符,同時(shí)指定了Cell的類是HMStatusCell
系統(tǒng)會(huì)為tableView注冊(cè)1個(gè)原形Cell,專門用來做可重用單元格的,1旦緩沖區(qū)中不存在
可重用單元格,系統(tǒng)會(huì)使用原形Cell新實(shí)例化1個(gè)Cell用程序使用!
因此如果在,Storyboard中,注冊(cè)了原形Cell,就不再需要 cell == nil的判斷了
*/
// NYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// unable to dequeue a cell with identifier Cell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard
// 使用這個(gè)方法,要求1定注冊(cè)可重用單元格,否則就會(huì)崩潰!
// 官方建議使用以下方法,利用程序的崩潰,及時(shí)發(fā)現(xiàn)問題
NYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID forIndexPath:indexPath];
// if (cell == nil) {
// cell = [[NYStatusCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
// }
NYStatusFrame *statusFrame = self.statusFrames[indexPath.row];
cell.statusFrame = statusFrame;
return cell;
}
#pragma mark - 代理方法
/**計(jì)算單元格行高*/
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
/**
計(jì)算行高的方法,會(huì)在加載表格數(shù)據(jù)時(shí),有多少行計(jì)算多少次 contentSize
問題:此方法履行的時(shí)候,cell還沒有被實(shí)例化!
但是:行高計(jì)算是在實(shí)例化cell時(shí),通過設(shè)置status屬性,計(jì)算=》有了status模型,就能夠知道行高 !
問題:如何在cell實(shí)例化之前,取得行高?
解決方法:通過status可以計(jì)算得到行高! = 》再建立1個(gè)模型,專門計(jì)算所有控件的位置
*/
NYStatusFrame *statusFrame = self.statusFrames[indexPath.row];
return statusFrame.cellHeight;
}
@end
//
// NYStatusCell.m
// 新浪微博UI
//
// Created by apple on 15⑷⑼.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYStatusCell.h"
#import "NYStatus.h"
#import "NYStatusFrame.h"
/**姓名字體*/
#define kNameFont [UIFont systemFontOfSize:14]
/**正文字體*/
#define kTextFont [UIFont systemFontOfSize:16]
@interface NYStatusCell()
//1>創(chuàng)建自定iyiCell,繼承自UITableViewCell
//2>根據(jù)需求,肯定控件,并定義屬性。
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *nameView;
@property (nonatomic, strong) UIImageView *vipView;
@property (nonatomic, strong) UILabel *textView;
@property (nonatomic, strong) UIImageView *pictureView;
@end
@implementation NYStatusCell
//3>用get方法完成控件的實(shí)例化,只創(chuàng)建并添加到contentView,不處理位置。
-(UIImageView *)iconView
{
if (_iconView == nil) {
_iconView = [[UIImageView alloc] init];
[self.contentView addSubview:_iconView];
}
return _iconView;
}
-(UILabel *)nameView
{
if (_nameView == nil) {
_nameView = [[UILabel alloc] init];
//默許字體是17號(hào),改成kNameFont
_nameView.font = kNameFont;
[self.contentView addSubview:_nameView];
}
return _nameView;
}
-(UIImageView *)vipView
{
if (_vipView == nil) {
_vipView = [[UIImageView alloc] init];
[self.contentView addSubview:_vipView];
}
return _vipView;
}
-(UILabel *)textView
{
if (_textView == nil) {
_textView = [[UILabel alloc] init];
_textView.font = kTextFont;
_textView.numberOfLines = 0;//讓他可以換行
[self.contentView addSubview:_textView];
}
return _textView;
}
-(UIImageView *)pictureView
{
if (_pictureView == nil) {
_pictureView = [[UIImageView alloc] init];
[self.contentView addSubview:_pictureView];
}
return _pictureView;
}
-(void)setStatusFrame:(NYStatusFrame *)statusFrame
{
_statusFrame = statusFrame;
//1>設(shè)置數(shù)據(jù)
[self settingData];
//2>設(shè)置位置
[self settingFrame];
}
/**設(shè)置數(shù)據(jù)*/
-(void)settingData
{
NYStatus *status = self.statusFrame.status;
//頭像
self.iconView.image = [UIImage imageNamed:status.icon];
//姓名
self.nameView.text = status.name;
//vip
if (status.vip) {
self.vipView.image = [UIImage imageNamed:@"vip"];
}
//內(nèi)容正文
self.textView.text = status.text;
//圖片可選參數(shù):
if (status.picture.length > 0) {
self.pictureView.hidden = YES;
self.pictureView.image = [UIImage imageNamed:status.picture];
}
self.pictureView.hidden = NO;
}
/**設(shè)置位置*/
-(void)settingFrame
{
//1.頭像
self.iconView.frame = self.statusFrame.iconF;
//2,姓名大小由文字的長(zhǎng)度決定
//boundingRectWithSize計(jì)算給定文字字符串所占的區(qū)域,返回是1個(gè)x,y為0的CGRect;w,h是計(jì)算好的寬高
// 如果要計(jì)算多行的準(zhǔn)確高度需要傳入
// options:NSStringDrawingUsesLineFragmentOrigin
//attribbutes:dict 用于指定字體的相干屬性的字典。UIKit框架的第1個(gè)頭文件ps 這個(gè)頭文件不記很難找
// context :nil
self.nameView.frame = self.statusFrame.nameF;
//3,vip圖片
self.vipView.frame = self.statusFrame.vipF;
//4,正文
self.textView.frame = self.statusFrame.textF;
//5,圖片
self.pictureView.frame = self.statusFrame.pictureF;
}
@end
NYStatus
//
// NYStatus.m
// 新浪微博UI
//
// Created by apple on 15⑷⑻.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYStatus.h"
@implementation NYStatus
-(instancetype)initWithDict:(NSDictionary *)dict
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+(instancetype)statusWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
+(NSArray *)statuses
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]];
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
[arrayM addObject:[self statusWithDict:dict]];
}
return arrayM;
}
@end
NYStatusFrame
//
// NYStatusFrame.m
// 新浪微博UI
//
// Created by apple on 15⑷⑼.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYStatusFrame.h"
#import "NYStatus.h"
#import "NSString+Tools.h"
#define kNameFont [UIFont systemFontOfSize:14]
/**正文字體*/
#define kTextFont [UIFont systemFontOfSize:16]
@implementation NYStatusFrame
/**
為了程序的安全(面向?qū)ο蟮乃枷耄憬o我你就相信我,讓我來改,他人別隨意動(dòng))
為了讓程序更安全,我們將類NYStatusFrame的有關(guān)位置的:(例如iconF)設(shè)置成readonly只讀屬性,這時(shí)候候我們用self.iconF(_iconF的set方法)的時(shí)候就不能用了。
此時(shí)要注意:
1旦重寫了readonly屬性的getter方法,
-(CGRect)iconF
{
}
帶_的成員變量就不存在了
這時(shí)候候如果還需要使用_成員變量,則必須用合成指令@synthesize
@synthesize iconF = _iconF;
*/
-(void)setStatus:(NYStatus *)status
{
_status = status;
//0.定義間距
CGFloat padding = 10;
//1.頭像
CGFloat iconX = padding;
CGFloat iconY = padding;
CGFloat iconW = 30;
CGFloat iconH = 30;
_iconF = CGRectMake(iconX, iconY, iconW, iconH);
//2,姓名大小由文字的長(zhǎng)度決定
//boundingRectWithSize計(jì)算給定文字字符串所占的區(qū)域,返回是1個(gè)x,y為0的CGRect;w,h是計(jì)算好的寬高
// 如果要計(jì)算多行的準(zhǔn)確高度需要傳入
// options:NSStringDrawingUsesLineFragmentOrigin
//attribbutes:dict 用于指定字體的相干屬性的字典。UIKit框架的第1個(gè)頭文件ps 這個(gè)頭文件不記很難找
// context :nil
NSDictionary *nameDict = @{NSFontAttributeName:kNameFont};
// CGRect nameFrame = [self.status.name boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:nameDict context:nil];
CGRect nameFrame = [self.status.name textRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) attributes:nameDict];
nameFrame.origin.x = CGRectGetMaxX(self.iconF) +padding;
nameFrame.origin.y = padding + (self.iconF.size.height - nameFrame.size.height)*0.5;
_nameF = nameFrame;
//3,vip圖片
CGFloat vipX = CGRectGetMaxX(self.nameF) + padding;
CGFloat vipY = self.nameF.origin.y;
CGFloat vipW = 14;
CGFloat vipH = 14;
_vipF = CGRectMake(vipX, vipY, vipW, vipH);
//4,正文
NSDictionary *textDict = @{NSFontAttributeName:kTextFont};
// CGRect textFrame = [self.status.text boundingRectWithSize:CGSizeMake(300, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:textDict context:nil];
CGRect textFrame = [self.status.text textRectWithSize:CGSizeMake(300, MAXFLOAT) attributes:textDict];
textFrame.origin.x = padding;
textFrame.origin.y = CGRectGetMaxY(self.iconF) + padding;
_textF = textFrame;
//5,配圖
if (self.status.picture.length>0) {
CGFloat pictureX = padding;
CGFloat pictureY = CGRectGetMaxY(self.iconF) + padding +self.textF.size.height +padding;
CGFloat pictureW = 100;
CGFloat pictureH = 100;
_pictureF= CGRectMake(pictureX, pictureY, pictureW, pictureH);
self.cellHeight = CGRectGetMaxY(self.pictureF) + padding;
}else{
self.cellHeight = CGRectGetMaxY(self.textF) + padding;
}
}
+(NSArray *)statusFrames
{
NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]];
NSMutableArray *arrayM = [NSMutableArray array];
for (NSDictionary *dict in array) {
//要添加statusesFrame對(duì)象
NYStatusFrame *statusFrame = [[NYStatusFrame alloc]init];
//調(diào)用statusFrame的setter方法,保存status模型,同時(shí)計(jì)算出控件的位置(setter方法中進(jìn)行的)
statusFrame.status = [NYStatus statusWithDict:dict];
//將statusFrame添加到數(shù)組
[arrayM addObject:statusFrame];
}
return arrayM;
}
@end
ps:新建iOS交換學(xué)習(xí)群:304570962
可以加貓貓QQ:1764541256 或則微信znycat
讓我們1起努力學(xué)習(xí)吧。
原文:http://blog.csdn.net/u013357243?viewmode=contents