首页 > 代码库 > iOS开发项目篇—41cell的frame的细节处理
iOS开发项目篇—41cell的frame的细节处理
iOS开发项目篇—41cell的frame的细节处理
一、简单说明
在首页控制器中使用自定义的UITableViewcell
代码如下:
YYHomeTableViewController.m文件
1 // 2 // YYHomeTableViewController.m 3 // 4 5 #import "YYHomeTableViewController.h" 6 #import "YYOneViewController.h" 7 #import "YYTitleButton.h" 8 #import "YYPopMenu.h" 9 #import "YYAccountModel.h" 10 #import "YYAccountTool.h" 11 //#import "AFNetworking.h" 12 #import "UIImageView+WebCache.h" 13 #import "YYUserModel.h" 14 #import "YYStatusModel.h" 15 #import "MJExtension.h" 16 #import "YYloadStatusesFooter.h" 17 //#import "YYHttpTool.h" 18 #import "YYHomeStatusesParam.h" 19 #import "YYHomeStatusesResult.h" 20 #import "YYStatusTool.h" 21 #import "YYUserInfoParam.h" 22 #import "YYUserTool.h" 23 #import "YYStatusFrame.h" 24 #import "YYStatusCell.h" 25 26 @interface YYHomeTableViewController ()<YYPopMenuDelegate> 27 @property(nonatomic,assign)BOOL down; 28 @property(nonatomic,strong)NSMutableArray *statusesFrame; 29 @property(nonatomic,strong)YYloadStatusesFooter *footer; 30 @property(nonatomic,strong) YYTitleButton *titleButton; 31 @property (nonatomic, weak) UIRefreshControl *refreshControl; 32 @end 33 34 @implementation YYHomeTableViewController 35 36 #pragma mark- 懒加载 37 -(NSMutableArray *)statusesFrame 38 { 39 if (_statusesFrame==nil) { 40 _statusesFrame=[NSMutableArray array]; 41 } 42 return _statusesFrame; 43 } 44 - (void)viewDidLoad 45 { 46 [super viewDidLoad]; 47 48 //设置导航栏内容 49 [self setupNavBar]; 50 51 //集成刷新控件 52 [self setupRefresh]; 53 54 //设置用户的昵称为标题 55 //先显示首页标题,延迟两秒之后变换成用户昵称 56 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 57 [self setupUserInfo]; 58 }); 59 } 60 61 /** 62 *设置用户的昵称为标题 63 */ 64 -(void)setupUserInfo 65 { 66 //1.封装请求参数 67 // YYUserInfoParam *params=[[YYUserInfoParam alloc]init]; 68 // params.access_token=[YYAccountTool accountModel].access_token; 69 YYUserInfoParam *params=[YYUserInfoParam param]; 70 params.uid=[YYAccountTool accountModel].uid; 71 72 //2.发送网络请求 73 [YYUserTool userInfoWithParam:params success:^(YYUserInfoResult *result) { 74 75 //字典转模型 76 YYUserModel *user=result; 77 78 //设置标题 79 [self.titleButton setTitle:user.name forState:UIControlStateNormal]; 80 // 存储账号信息(需要先拿到账号) 81 YYAccountModel *account=[YYAccountTool accountModel]; 82 account.name=user.name; 83 //存储 84 [YYAccountTool save:account]; 85 } failure:^(NSError *error) { 86 YYLog(@"请求失败"); 87 }]; 88 } 89 90 //集成刷新控件 91 -(void)setupRefresh 92 { 93 // 1.添加下拉刷新控件 94 UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; 95 [self.tableView addSubview:refreshControl]; 96 self.refreshControl=refreshControl; 97 98 //2.监听状态 99 [refreshControl addTarget:self action:(@selector(refreshControlStateChange:)) forControlEvents:UIControlEventValueChanged];100 101 //3.让刷新控件自动进入到刷新状态102 [refreshControl beginRefreshing];103 104 //4.手动调用方法,加载数据105 //模拟网络延迟,延迟2.0秒106 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{107 [self refreshControlStateChange:refreshControl];108 });109 110 //5.上拉刷新数据111 YYloadStatusesFooter *footer=[YYloadStatusesFooter loadFooter];112 self.tableView.tableFooterView=footer;113 self.footer=footer;114 }115 116 /**117 * 当下拉刷新控件进入刷新状态(转圈圈)的时候会自动调用118 */119 -(void)refreshControlStateChange:(UIRefreshControl *)refreshControl120 {121 [self loadNewStatuses:refreshControl];122 }123 124 #pragma mark- 刷新125 -(void)refresh:(BOOL)fromSelf126 {127 if (self.tabBarItem.badgeValue) {//如果有数字128 //转圈圈129 [self.refreshControl beginRefreshing];130 131 //刷新数据132 [self loadNewStatuses:self.refreshControl];133 }else if(fromSelf) // 没有数字134 {135 //让表格回到最顶部136 NSIndexPath *firstRow=[NSIndexPath indexPathForItem:0 inSection:0];137 [self.tableView scrollToRowAtIndexPath:firstRow atScrollPosition:UITableViewScrollPositionTop animated:YES];138 139 }140 }141 #pragma mark-加载微博数据142 143 /**144 * 根据微博模型数组 转成 微博frame模型数据145 *146 * @param statuses 微博模型数组147 *148 */149 - (NSArray *)statusFramesWithStatuses:(NSArray *)statuses150 {151 NSMutableArray *frames = [NSMutableArray array];152 for (YYStatusModel *status in statuses) {153 YYStatusFrame *frame = [[YYStatusFrame alloc] init];154 // 传递微博模型数据,计算所有子控件的frame155 frame.status = status;156 [frames addObject:frame];157 }158 return frames;159 }160 161 -(void)loadNewStatuses:(UIRefreshControl *)refreshControl162 {163 //1.封装请求参数164 // YYHomeStatusesParam *param=[[YYHomeStatusesParam alloc]init];165 // param.access_token=[YYAccountTool accountModel].access_token;166 YYHomeStatusesParam *param=[YYHomeStatusesParam param];167 YYStatusFrame *firstStatusFrame=[self.statusesFrame firstObject];168 YYStatusModel *firstStatus=firstStatusFrame.status;169 if (firstStatus) {170 param.since_id=@([firstStatus.idstr longLongValue]);171 }172 173 //2.加载微博数据174 [YYStatusTool homeStatusesWithParam:param success:^(YYHomeStatusesResult *result) {175 //获取最新的微博数组176 // NSArray *newStatuses=result.statuses;177 NSArray *newFrames=[self statusFramesWithStatuses:result.statuses];178 179 //把新数据添加到旧数据的前面180 NSRange range=NSMakeRange(0, newFrames.count);181 NSIndexSet *indexSet=[NSIndexSet indexSetWithIndexesInRange:range];182 [self.statusesFrame insertObjects:newFrames atIndexes:indexSet];183 YYLog(@"刷新了--%d条新数据",newFrames.count);184 185 //重新刷新表格186 [self.tableView reloadData];187 //让刷新控件停止刷新(回复默认的状态)188 [refreshControl endRefreshing];189 [self showNewStatusesCount:newFrames.count];190 191 } failure:^(NSError *error) {192 YYLog(@"请求失败");193 //让刷新控件停止刷新(回复默认的状态)194 [refreshControl endRefreshing];195 196 }];197 198 }199 200 /**201 * 加载更多的微博数据202 */203 - (void)loadMoreStatuses204 {205 //1.封装请求参数206 YYHomeStatusesParam *param=[YYHomeStatusesParam param];207 YYStatusFrame *lastStatusFrame=[self.statusesFrame lastObject];208 YYStatusModel *lastStatus=lastStatusFrame.status;209 if (lastStatus) {210 param.max_id=@([lastStatus.idstr longLongValue]-1);211 }212 213 //2.发送网络请求214 [YYStatusTool homeStatusesWithParam:param success:^(YYHomeStatusesResult *result) {215 216 //获取最新的微博数组217 // NSArray *newStatuses=result.statuses;218 NSArray *newFrames=[self statusFramesWithStatuses:result.statuses];219 220 // 将新数据插入到旧数据的最后面221 [self.statusesFrame addObjectsFromArray:newFrames];222 // 重新刷新表格223 [self.tableView reloadData];224 // 让刷新控件停止刷新(恢复默认的状态)225 [self.footer endRefreshing];226 } failure:^(NSError *error) {227 YYLog(@"请求失败--%@", error);228 // 让刷新控件停止刷新(恢复默认的状态)229 [self.footer endRefreshing];230 }];231 }232 233 /**234 * 提示用户最新的微博数量235 *236 * @param count 最新的微博数量237 */238 -(void)showNewStatusesCount:(int)count239 {240 //0.清零提醒数字241 [UIApplication sharedApplication].applicationIconBadgeNumber -=self.tabBarItem.badgeValue.intValue;242 self.tabBarItem.badgeValue=http://www.mamicode.com/nil;243 244 //1.创建一个label245 UILabel *label=[[UILabel alloc]init];246 247 //2.设置label的文字248 if (count) {249 label.text=[NSString stringWithFormat:@"共有%d条新的微博数据",count];250 }else251 {252 label.text=@"没有最新的微博数据";253 }254 255 //3.设置label的背景和对其等属性256 label.backgroundColor=[UIColor colorWithPatternImage:[UIImage imageWithName:@"timeline_new_status_background"]];257 label.textAlignment=UITextAlignmentCenter;258 label.textColor=[UIColor whiteColor];259 260 //4.设置label的frame261 label.x=0;262 label.width=self.view.width;263 label.height=35;264 label.y=self.navigationController.navigationBar.height+20-label.height;265 266 //5.把lable添加到导航控制器的View上267 [self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];268 269 //6.设置动画效果270 CGFloat duration=0.75;271 //设置提示条的透明度272 label.alpha=0.0;273 [UIView animateWithDuration:duration animations:^{274 //往下移动一个label的高度275 label.transform=CGAffineTransformMakeTranslation(0, label.height);276 label.alpha=1.0;277 } completion:^(BOOL finished) {//向下移动完毕278 279 //延迟delay秒的时间后,在执行动画280 CGFloat delay=0.5;281 282 [UIView animateKeyframesWithDuration:duration delay:delay options:UIViewAnimationOptionCurveEaseOut animations:^{283 284 //恢复到原来的位置285 label.transform=CGAffineTransformIdentity;286 label.alpha=0.0;287 288 } completion:^(BOOL finished) {289 290 //删除控件291 [label removeFromSuperview];292 }];293 }];294 }295 296 /**设置导航栏内容*/297 -(void)setupNavBar298 {299 self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_friendsearch" highImageName:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendsearch)];300 self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImageName:@"navigationbar_pop" highImageName:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];301 302 //设置导航栏按钮303 YYTitleButton *titleButton=[[YYTitleButton alloc]init];304 305 //设置尺寸306 titleButton.height=35;307 308 //设置文字309 YYAccountModel *account= [YYAccountTool accountModel];310 NSString *name=account.name;311 NSLog(@"%@",name);312 // name=@"yangye";313 //判断:如果name有值(上一次登录的用户名),那么就使用上次的,如果没有那么就设置为首页314 if (name) {315 [titleButton setTitle:name forState:UIControlStateNormal];316 }else{317 [titleButton setTitle:@"首页" forState:UIControlStateNormal];318 }319 //设置图标320 [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];321 //设置背景322 [titleButton setBackgroundImage:[UIImage resizedImage:@"navigationbar_filter_background_highlighted"] forState:UIControlStateHighlighted];323 324 //监听按钮的点击事件325 [titleButton addTarget:self action:@selector(titleButtonClick:) forControlEvents:UIControlEventTouchUpInside];326 self.navigationItem.titleView=titleButton;327 self.titleButton=titleButton;328 }329 -(void)titleButtonClick:(UIButton *)titleButton330 {331 332 [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_up"] forState:UIControlStateNormal];333 334 UITableView *tableView=[[UITableView alloc]init];335 [tableView setBackgroundColor:[UIColor yellowColor]];336 YYPopMenu *menu=[YYPopMenu popMenuWithContentView:tableView];337 [menu showInRect:CGRectMake(60, 55, 200, 200)];338 menu.dimBackground=YES;339 340 menu.arrowPosition=YYPopMenuArrowPositionRight;341 menu.delegate=self;342 }343 344 345 #pragma mark-YYPopMenuDelegate346 //弹出菜单347 -(void)popMenuDidDismissed:(YYPopMenu *)popMenu348 {349 YYTitleButton *titleButton=(YYTitleButton *)self.navigationItem.titleView;350 [titleButton setImage:[UIImage imageWithName:@"navigationbar_arrow_down"] forState:UIControlStateNormal];351 }352 -(void)pop353 {354 YYLog(@"---POP---");355 }356 -(void)friendsearch357 {358 //跳转到one这个子控制器界面359 YYOneViewController *one=[[YYOneViewController alloc]init];360 one.title=@"One";361 //拿到当前控制器362 [self.navigationController pushViewController:one animated:YES];363 364 }365 366 #pragma mark - Table view data source367 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section368 {369 #warning 监听tableView每次显示数据的过程370 //在tableView显示之前,判断有没有数据,如有有数据那么就显示底部视图371 self.footer.hidden=self.statusesFrame.count==0;372 return self.statusesFrame.count;373 }374 375 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath376 {377 // static NSString *ID = @"cell";378 // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];379 // if (!cell) {380 // cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];381 // }382 // 383 // //取出这行对应的微博字典数据,转换为数据模型384 // YYStatusModel *status=self.statuses[indexPath.row];385 // cell.textLabel.text=status.text;386 // cell.detailTextLabel.text=status.user.name;387 // NSString *imageUrlStr=status.user.profile_image_url;388 // [cell.imageView setImageWithURL:[NSURL URLWithString:imageUrlStr] placeholderImage:[UIImage imageWithName:@"avatar_default_small"]];389 390 YYStatusCell *cell=[YYStatusCell cellWithTableView:tableView];391 cell.statusFrame=self.statusesFrame[indexPath.row];392 return cell;393 }394 395 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath396 {397 //点击cell的时候,跳到下一个界面398 UIViewController *newVc = [[UIViewController alloc] init];399 newVc.view.backgroundColor = [UIColor redColor];400 newVc.title = @"新控制器";401 [self.navigationController pushViewController:newVc animated:YES];402 }403 404 #pragma mark-代理方法405 - (void)scrollViewDidScroll:(UIScrollView *)scrollView406 {407 if (self.statusesFrame.count <= 0 || self.footer.isRefreshing) return;408 409 // 1.差距410 CGFloat delta = scrollView.contentSize.height - scrollView.contentOffset.y;411 // 刚好能完整看到footer的高度412 CGFloat sawFooterH = self.view.height - self.tabBarController.tabBar.height;413 414 // 2.如果能看见整个footer415 if (delta <= (sawFooterH - 0)) {416 // 进入上拉刷新状态417 [self.footer beginRefreshing];418 419 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{420 // 加载更多的微博数据421 [self loadMoreStatuses];422 });423 }424 }425 426 #pragma mark-返回cell的高度427 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath428 {429 //取出对应的模型430 YYStatusFrame *statusFrame=self.statusesFrame[indexPath.row];431 return statusFrame.cellHight;432 }433 @end
在自定义cell类中提供一个方法:
1 // 2 // YYStatusCell.h 3 // 4 5 #import <UIKit/UIKit.h> 6 @class YYStatusFrame; 7 @interface YYStatusCell : UITableViewCell 8 #warning 注意这里不能直接使用frame作为属性名。继承自UIview,而它本身就有一个frame。 9 @property(nonatomic,strong)YYStatusFrame *statusFrame;10 11 //类方法,提供cell的初始化12 +(instancetype)cellWithTableView:(UITableView *)tableView;13 @end
YYStatusCell.m文件
1 // 2 // YYStatusCell.m 3 // 自定义cell 4 5 #import "YYStatusCell.h" 6 #import "YYStatusDetailView.h" 7 #import "YYStatusToolbar.h" 8 //#import "YYStatusDetailFrame.h" 9 #import "YYStatusFrame.h"10 11 @interface YYStatusCell ()12 @property(nonatomic,weak)YYStatusDetailView *detailView;13 @property(nonatomic,weak)YYStatusToolbar *toolbar;14 @end15 16 @implementation YYStatusCell17 18 +(instancetype)cellWithTableView:(UITableView *)tableView19 {20 static NSString *ID = @"cell";21 YYStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];22 if (!cell) {23 cell = [[YYStatusCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];24 }25 return cell;26 }27 28 29 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier30 {31 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];32 if (self) {33 //初始化子控件34 35 //1.添加微博具体内容36 [self setupDetailView];37 38 //2.添加工具条39 [self setupToolbar];40 }41 return self;42 }43 44 /**添加微博具体内容*/45 -(void)setupDetailView46 {47 YYStatusDetailView *detailView=[[YYStatusDetailView alloc]init];48 [self.contentView addSubview:detailView];49 self.detailView=detailView;50 }51 52 /**添加工具条*/53 -(void)setupToolbar54 {55 YYStatusToolbar *toolbar=[[YYStatusToolbar alloc]init];56 toolbar.backgroundColor=[UIColor grayColor];57 [self.contentView addSubview:toolbar];58 self.toolbar=toolbar;59 }60 61 -(void)setStatusFrame:(YYStatusFrame *)statusFrame62 {63 _statusFrame=statusFrame;64 //1.微博具体内容的frame数据65 self.detailView.detailFrame=statusFrame.StatusDetailFrame;66 67 //2.底部工具条的frame数据68 self.toolbar.frame=statusFrame.toolbarFrame;69 }70 @end
二、细节处理
1.上述代码运行后的效果
出现这种情况可能的原因:
(1)frame计算出现错误
(2)没有给有文字显示的地方为文字设置字体大小
(3)正文等需要换行的地方,没有设置多行显示。
(4)在UItableView的方法中,没有返回cell的高度
1 //2.昵称 2 UILabel *nameLabel=[[UILabel alloc]init]; 3 nameLabel.font=YYStatusOrginalNameFont; 4 [self addSubview:nameLabel]; 5 self.nameLabel=nameLabel; 6 7 //3.正文 8 UILabel *textLabel=[[UILabel alloc]init]; 9 textLabel.font=YYStatusOrginalTextFont;10 textLabel.numberOfLines=0;11 [self addSubview:textLabel];12 self.textLabel=textLabel;
调整后显示效果:
先把微博来源注释掉,调整bug后的最终显示效果:
补充代码:
YYStatusDetailFrame.m文件
1 // 2 // YYStatusDetailFrame.m 3 // 4 5 #import "YYStatusDetailFrame.h" 6 #import "YYStatusOriginalFrame.h" 7 #import "YYStatusRetweetedFrame.h" 8 #import "YYStatusModel.h" 9 10 @interface YYStatusDetailFrame ()11 @property(nonatomic,assign)CGFloat tempHeight;12 @end13 @implementation YYStatusDetailFrame14 15 -(void)setStatus:(YYStatusModel *)status16 {17 _status=status;18 //1.计算原创微博的frame19 [self setupStatusOriginalFrame];20 21 //2.计算转发微博的frame22 [self setupStatusRetweetedFrameWithStatus:status];23 24 //3.计算自己的frame25 [self setupDetailFrame];26 27 }28 29 /**30 * 计算原创微博的frame31 */32 -(void)setupStatusOriginalFrame33 {34 YYStatusOriginalFrame *originalFrame=[[YYStatusOriginalFrame alloc]init];35 originalFrame.status=self.status;36 self.originalFrame=originalFrame;37 }38 39 /**40 * 计算转发微博的frame41 */42 -(void)setupStatusRetweetedFrameWithStatus:(YYStatusModel *)status43 {44 if (status.retweeted_status) {45 YYStatusRetweetedFrame *retweetedFrame=[[YYStatusRetweetedFrame alloc]init];46 retweetedFrame.retweeted_status=status.retweeted_status;47 self.retweetedFrame=retweetedFrame;48 49 CGRect f=retweetedFrame.frame;50 f.origin.y=CGRectGetMaxY(self.originalFrame.frame);51 retweetedFrame.frame=f;52 self.tempHeight=CGRectGetMaxY(self.retweetedFrame.frame);53 }else54 {55 self.tempHeight=CGRectGetMaxY(self.originalFrame.frame);56 }57 58 }59 60 /**61 * 计算自己的frame62 */63 -(void)setupDetailFrame64 {65 CGFloat x=0;66 CGFloat y=0;67 CGFloat w=YYScreenW;68 CGFloat h=self.tempHeight;69 self.frame=CGRectMake(x, y, w, h);70 }71 @end
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。