iOS_21团购_真正封装的团购详情控制器
最终效果图:
DealDetailController控制器
// // DealDetailController.h // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器 #import <UIKit/UIKit.h> @class Deal; @interface DealDetailController : UIViewController // 数据源,提供给内部的子view数据,内部子view拿到数据后,又会重写setter方法,再为它的子控件们设置数据,层层传递 @property (nonatomic, strong) Deal *deal; @end
// // DealDetailController.m // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,顶部有一个固定的半透明的buyDock #import "DealDetailController.h" #import "TopDock.h" #import "RightDock.h" #import "RightDockDelegate.h" #import "Deal.h" // 团购简介控制器 #import "SummaryController.h" // 网页控制器 #import "WebViewController.h" // 商家详情控制器 #import "MerchantController.h" // 团购收藏工具类 #import "DealCollectionTool.h" @interface DealDetailController ()<RightDockDelegate> { // 详情控制器右侧的dock,里面有三个按钮,竖线排列,分别对应三个不同的子控制器(如:团购简介,图文详情,商家详情) RightDock *_rightDock; TopDock *_topDock; } @end @implementation DealDetailController - (void)viewDidLoad { [super viewDidLoad]; // 1.基本设置 [self baseSetting]; // 2.添加顶部的购买栏 [self addTopDock]; // 3.添加右边的选项卡栏 [self addRightDock]; // 4.初始化子控制器 [self addAllChildControllers]; } #pragma 基本设置 - (void)baseSetting { // 1.背景色 self.view.backgroundColor = kGlobalBg; // 2.设置标题 self.title = _deal.title; // 3.判断并添加 传入的团购对象的收藏属性 [[DealCollectionTool sharedDealCollectionTool] updateCollectedPropertyForDeal:_deal]; // 4.右上角的2个按钮(收藏按钮) NSString *collectIcon = _deal.collected ? @"ic_collect_suc.png" : @"ic_deal_collect.png"; self.navigationItem.rightBarButtonItems = @[ [UIBarButtonItem itemWithIcon:@"btn_share.png" highlightedIcon:@"btn_share_pressed.png" target:nil action:nil], [UIBarButtonItem itemWithIcon:collectIcon highlightedIcon:@"ic_deal_collect_pressed.png" target:self action:@selector(collectBtnClicked)]]; // 5.监听收藏按钮点击时侯,发出的通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(collectChange) name:kCollectChangeNote object:nil]; } #pragma mark 2.添加顶部的购买栏 - (void)addTopDock { // 类方法创建一个TopDock对象(内部会从xib创建顶部的购买dock) _topDock = [TopDock topDock]; // 为view提供数据源Model _topDock.deal = _deal; // 设置它在订在顶部(导航高 44 ) _topDock.frame = CGRectMake(0,44, self.view.frame.size.width, 60); [self.view addSubview:_topDock]; } #pragma mark 3.添加右边的选项卡栏 - (void)addRightDock { // 类方法创建一个RightDock对象(内部会从xib创建右侧的dock,dock内部已经包含了三个item,分别是团购简介、图文详情、商家详情) RightDock *rightDock = [RightDock rightDock]; // rightDock一直贴着最右、下方 CGSize size = rightDock.frame.size; CGFloat x = self.view.frame.size.width - size.width; CGFloat y = self.view.frame.size.height - size.height - 100; rightDock.frame = CGRectMake(x, y, 0, 0); // 为了监听rightDock的里面的三个item之间的切换(点击事件),设置当前控制器为其代理,遵守协议并实现其代理方法 rightDock.delegate = self; [self.view addSubview:rightDock]; // ????? 当监听到rightDock内部的点击事件时,要当前控制器移除旧的控制器,并添加对应的新控制器,为了确定新控制器的frame,(也可以不记住....)因此要用成员变量记住rightDock _rightDock = rightDock; } #pragma mark 4.初始化子控制器 - (void)addAllChildControllers { // 1.创建 团购简介 控制器 SummaryController *summaryVC = [[SummaryController alloc] init]; // 设置数据源 summaryVC.deal = _deal; [self addChildViewController:summaryVC]; // 默认选中第0个控制器 [self rightDock:nil btnClickedFrom:0 to:0]; // 2.创建图文详情控制器 WebViewController *webVC = [[WebViewController alloc] init]; webVC.deal = _deal; [self addChildViewController:webVC]; // 3.创建商家详情控制器 MerchantController *merchant = [[MerchantController alloc] init]; merchant.view.backgroundColor = [UIColor greenColor]; [self addChildViewController:merchant]; } #pragma mark - RightDock的代理方法,由rightDock告诉代理(即控制器)它内部的item被切换了(点击了) - (void)rightDock:(RightDock *)rightDock btnClickedFrom:(int)from to:(int)to { if (to == 1) { _topDock.hidden = YES; } else { _topDock.hidden = NO; } // 1.移除旧控制器的view UIViewController *old = self.childViewControllers[from]; [old.view removeFromSuperview]; // 2.添加新控制器的view UIViewController *new = self.childViewControllers[to]; new.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; // 占据除了右侧的dock之外的所有区域 CGFloat w = self.view.frame.size.width - _rightDock.frame.size.width; CGFloat h = self.view.frame.size.height; new.view.frame = CGRectMake(0, 0, w, h); [self.view insertSubview:new.view atIndex:0]; } #pragma mark 收藏按钮被点击 - (void)collectBtnClicked { // 如果 是收藏 的,则取消收藏,并且发出通知,告诉自己要更新收藏按钮的背景图片,并且告诉收藏控制器里面重新reloadData if (_deal.collected) { // 取消收藏 [[DealCollectionTool sharedDealCollectionTool] uncollectDeal:_deal]; } else { // 加入收藏 [[DealCollectionTool sharedDealCollectionTool] collectDeal:_deal]; } // 发出通知,告诉自己要更新收藏按钮的背景图片,并且告诉收藏控制器里面重新reloadData [[NSNotificationCenter defaultCenter] postNotificationName:kCollectChangeNote object:nil]; } #pragma mark 接收到收藏状态改变的通知,重新设置按钮背景图片 - (void)collectChange { [[DealCollectionTool sharedDealCollectionTool] updateCollectedPropertyForDeal:_deal]; UIButton *btn = (UIButton *)[self.navigationItem.rightBarButtonItems[1] customView]; if (_deal.collected) { [btn setBackgroundImage:[UIImage imageNamed:@"ic_collect_suc.png"] forState:UIControlStateNormal]; } else { [btn setBackgroundImage:[UIImage imageNamed:@"ic_deal_collect.png"] forState:UIControlStateNormal]; } } @end
封装的子控件们
TopDock
// // TopDock.h // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,顶部的购买dock,包含原价,现价,立即购买按钮 #import <UIKit/UIKit.h> @class Deal, CrossLineLabel; @interface TopDock : UIView // 自绘标签,文字自带删除线 (列出的价格,贵的) @property (weak, nonatomic) IBOutlet CrossLineLabel *listPrice; // 当前价格 (便宜的) @property (weak, nonatomic) IBOutlet UILabel *currentPrice; // 依赖的数据源 @property (nonatomic, strong) Deal *deal; // 类方法,快速从xib文件中,生成一个对应的TopDock对象 + (id)topDock; // 点击了xib上最右边的购买按钮 - (IBAction)buyBtnClicked; @end
// // TopDock.m // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,顶部的购买dock,包含原价,现价,立即购买按钮 #import "TopDock.h" #import "Deal.h" // 带删除线的Label #import "CrossLineLabel.h" @implementation TopDock // 为本Dock绘制一个拉伸的背景图片(TopDock的背景是一张半透明的图片) - (void)drawRect:(CGRect)rect { [[UIImage imageStretchedWithName:@"bg_buyBtn.png"] drawInRect:rect]; } // 类方法,创建一个从xib中实例化的TopDock对象 + (id)topDock { return [[NSBundle mainBundle] loadNibNamed:@"TopDock" owner:nil options:nil][0]; } // 拦截数据源的setter方法,为内部子控件们提供数据 - (void)setDeal:(Deal *)deal { _deal = deal; // 原价 _listPrice.text = [NSString stringWithFormat:@" %@ 元 ", deal.list_price_text]; // 现价 _currentPrice.text = deal.current_price_text; } // 点击立即购买之后,打开safari进入官网购买 - (IBAction)buyBtnClicked { NSString *ID = [_deal.deal_id substringFromIndex:[_deal.deal_id rangeOfString:@"-"].location + 1]; NSString *url = [NSString stringWithFormat:@"http://o.p.dianping.com/buy/d%@", ID]; // 应该程序 openURL,会自动调用safari进行访问 [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; } @end
一个带删除线的文本标签
// // CrossLineLabel.h // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 一个带删除线的文本标签 #import <UIKit/UIKit.h> @interface CrossLineLabel : UILabel @end
// // CrossLineLabel.m // 帅哥_团购 // // Created by beyond on 14-8-20. // Copyright (c) 2014年 com.beyond. All rights reserved. // 一个带删除线的文本标签 #import "CrossLineLabel.h" @implementation CrossLineLabel // 重点~~~带删除线的文字标签 - (void)drawRect:(CGRect)rect { // 调用super的目的,就是先把文字画上去 [super drawRect:rect]; // 1.获得上下文 CGContextRef context = UIGraphicsGetCurrentContext(); // 2.设置线条颜色就是标签的文字颜色 [self.textColor setStroke]; // 3.设置线的宽度 // CGContextSetLineWidth(context, 3); // 3.画线的起点 CGFloat y = rect.size.height * 0.5; CGContextMoveToPoint(context, 0, y); // 4.短标题,根据字体确定宽度(即线条将要画多长)----不用折行的 CGSize size = [self.text sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:self.font,NSFontAttributeName, nil]]; // 5.线条的终点(文字有多长就画多长) CGContextAddLineToPoint(context, size.width, y); // 6.最后,渲染到上下文中 CGContextStrokePath(context); } @end
右侧Dock
// // RightDock.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,右边的三个按钮竖向排列组成的dock,包含简介、图文详情、商家详情 // 本view就是 右边的dock,内含三个按钮竖向排列的按钮RightDockItem,包含团购简介、图文详情、商家详情 #import <UIKit/UIKit.h> @class RightDockItem; @protocol RightDockDelegate; @interface RightDock : UIView // 内部的item 团购简介 排在首个 @property (weak, nonatomic) IBOutlet RightDockItem *dealSummaryItem; // 内部的item 【商家详情】 排在最后一个 @property (weak, nonatomic) IBOutlet RightDockItem *merchantItem; // 代理用weak,避免循环引用,告诉外界本Dock内部item被点击时的切换信息 @property (nonatomic, weak) id<RightDockDelegate> delegate; // 类方法,从xib中生成一个实例对象 + (id)rightDock; // 本方法,监听三个RightDockItem的点击状态切换 - (IBAction)rightDockItemClicked:(RightDockItem *)sender; @end
// // RightDock.m // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,右边的三个按钮竖向排列组成的dock,包含简介、图文详情、商家详情 // 本view就是 右边的dock,内含三个按钮竖向排列的按钮RightDockItem,包含团购简介、图文详情、商家详情 #import "RightDock.h" #import "RightDockItem.h" #import "RightDockDelegate.h" @interface RightDock () { // 三步曲,切换按钮的点击事件 UIButton *_selectedBtn; } @end @implementation RightDock // 类方法,从xib中生成一个实例对象 + (id)rightDock { return [[NSBundle mainBundle] loadNibNamed:@"RightDock" owner:nil options:nil][0]; } // 默认一开始就选中第一个【团购简介】 - (void)awakeFromNib { [self rightDockItemClicked:_dealSummaryItem]; } // 重写setFrame,避免外界改变右侧边栏的宽高 - (void)setFrame:(CGRect)frame { frame.size = self.frame.size; [super setFrame:frame]; } // 右侧dock的内部的三个item的 点击事件 - (IBAction)rightDockItemClicked:(RightDockItem *)sender { // 0.通知代理,调用代理的方法,将前一个选中按钮 和 被点击的按钮传递给外界 if ([_delegate respondsToSelector:@selector(rightDock:btnClickedFrom:to:)]) { [_delegate rightDock:self btnClickedFrom:_selectedBtn.tag to:sender.tag]; } // 1.标准三步曲,切换按钮状态 _selectedBtn.enabled = YES; sender.enabled = NO; _selectedBtn = sender; // 2.更改三个按钮的叠放层次,即将被点击的按钮放到最上面 if (sender == _dealSummaryItem) { // 当点击了第1个按钮 团购简介,就要把第3个【商家详情】放到最下面,即最前面 [self insertSubview:_merchantItem atIndex:0]; } else if (sender == _merchantItem) { // 当点击了第3个按钮 商家详情,就要把第1个【团购简介】放到最下面,即最前面 [self insertSubview:_dealSummaryItem atIndex:0]; } // 3.将被点击的这个item放到最上面,将指定的view推送到最前面(用户面前) [self bringSubviewToFront:sender]; } @end
右侧Dock的代理
// // RightDockDelegate.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,右边的三个按钮竖向排列组成的dock,包含简介、图文详情、商家详情 // 右边的dock,内含三个按钮竖向排列的按钮RightDockItem,包含简介、图文详情、商家详情 // 右边的Dock的代理,点击了RightDockItem时侯,告诉外界调用者,点击了哪一个,From btn To btn #import <Foundation/Foundation.h> @class RightDock; @protocol RightDockDelegate <NSObject> // 协议方法,点击RightDock里面的item时侯,Dock会调用代理delegate的方法,告诉外界,我内部被点击的按钮是从哪一个切换到了哪一个 @optional - (void)rightDock:(RightDock *)rightDock btnClickedFrom:(int)from to:(int)to; @end
右侧DockItem
// // RightDockItem.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,右边的三个按钮竖向排列组成的dock,包含简介、图文详情、商家详情 // 本按钮就是右边的RightDockItem #import <UIKit/UIKit.h> @interface RightDockItem : UIButton @end
// // RightDockItem.m // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 真正的通过xib显示一个订单的详情的控制器,右边的三个按钮竖向排列组成的dock,包含简介、图文详情、商家详情 // 本按钮就是右边的RightDockItem #import "RightDockItem.h" @implementation RightDockItem // 取消默认的点击高亮状态 - (void)setHighlighted:(BOOL)highlighted { // do nothing... } @end
团购简介控制器
SummaryController
// // SummaryController.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 团购简介控制器,当点击右侧dock里面的第一个rightDockItem按钮时,创建并显示本控制器 #import <UIKit/UIKit.h> @class Deal; @interface SummaryController : UIViewController // 数据源 @property (nonatomic, strong) Deal *deal; @end
// // SummaryController.m // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 团购简介控制器,当点击右侧dock里面的第一个rightDockItem按钮时,创建并显示本控制器 // 本控制器,最上面是SummaryHeaderView,下面是若干个SummaryTextView,一个SummaryTextView 代表一个组 如团购详情、购买须知、重要通知 #import "SummaryController.h" #import "SummaryHeader.h" #import "DealRequestTool.h" #import "Deal.h" #import "Restriction.h" // 一个SummaryTextView 代表一个组 如团购详情、购买须知、重要通知 #import "SummaryText.h" #define kVMargin 15 @interface SummaryController () { UIScrollView *_scrollView; // 本控制器,最上面是SummaryHeaderView,下面是若干个SummaryTextView SummaryHeader *_header; } @end @implementation SummaryController - (void)viewDidLoad { [super viewDidLoad]; // 1.添加滚动视图 [self addScrollView]; // 2.添加头部控件 [self addHeaderView]; // 3.通过工具,加载更详细的单个团购数据 [self loadSingleDealData]; } #pragma mark - 1.添加scrollView - (void)addScrollView { // 其他几个控件,全加到scrollView里 _scrollView = [[UIScrollView alloc] init]; _scrollView.showsVerticalScrollIndicator = NO; // scrollView的宽随便给个 430 _scrollView.bounds = CGRectMake(0, 0, 430, self.view.frame.size.height); CGFloat x = self.view.frame.size.width * 0.5; CGFloat y = self.view.frame.size.height * 0.5; _scrollView.center = CGPointMake(x, y); // 宽度固定,左边距,右边距拉伸,高度也拉伸 _scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; // 额外的滚动距离 CGFloat height = 70; _scrollView.contentInset = UIEdgeInsetsMake(height, 0, 0, 0); _scrollView.contentOffset = CGPointMake(0, -height); [self.view addSubview:_scrollView]; } #pragma mark 2.添加简介头控件 - (void)addHeaderView { _header = [SummaryHeader summaryHeader]; // 重要~~~保持开始高度为上一次的高度 _header.frame = CGRectMake(0, 0, _scrollView.frame.size.width, _header.frame.size.height); // 内部会拦截赋值 _header.deal = _deal; // 添加到scrollView [_scrollView addSubview:_header]; } #pragma mark 加载更详细的单个团购数据 - (void)loadSingleDealData { // 1.添加圈圈 UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; indicator.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin; CGFloat x = _scrollView.frame.size.width * 0.5; CGFloat y = CGRectGetMaxY(_header.frame) + kVMargin; indicator.center = CGPointMake(x, y); [_scrollView addSubview:indicator]; [indicator startAnimating]; // 2.发送请求 [[DealRequestTool sharedDealRequestTool] dealRequestWithID:_deal.deal_id success:^(Deal *deal) { // 请求成功,返回单个团购信息,用成员变量记住最新的团购数据 _deal = deal; // 提供数据源,内部会拦截赋值 _header.deal = deal; // 添加详情数据 [self addSummaryTextViews]; // 移除圈圈 [indicator removeFromSuperview]; } error:^(NSError *error) { log(@"%@",error); }]; } #pragma mark 根据请求返回的结果,添加若干个详情(简介文本控件) - (void)addSummaryTextViews { _scrollView.contentSize = CGSizeMake(0, CGRectGetMaxY(_header.frame) + kVMargin); // 1.团购详情 [self addSummaryTextView:@"ic_content.png" title:@"团购详情" content:_deal.details]; // 2.购买须知 [self addSummaryTextView:@"ic_tip.png" title:@"购买须知" content:_deal.restrictions.special_tips]; // 3.重要通知 [self addSummaryTextView:@"ic_tip.png" title:@"重要通知" content:_deal.notice]; } #pragma mark 抽取的,添加一个简介文本控件,参数:图片名,该组的标题,下文 - (void)addSummaryTextView:(NSString *)icon title:(NSString *)title content:(NSString *)content { if (content.length == 0) return; // 0.创建TextView SummaryText *textView = [SummaryText summaryText]; // 重要,先得到scrollView的高度,因为每一次添加都是将一组SummaryTextView,添加到scrollView的最后面 CGFloat y = _scrollView.contentSize.height; CGFloat w = _scrollView.frame.size.width; CGFloat h = textView.frame.size.height; textView.frame = CGRectMake(0, y, w, h); // 2.基本文字属性 textView.title = title; textView.content = content; textView.icon = icon; // 3.添加 [_scrollView addSubview:textView]; // 4.每次添加一组SummaryTextView之后,就要再次增设scrollView的内容尺寸 _scrollView.contentSize = CGSizeMake(0, CGRectGetMaxY(textView.frame) + kVMargin); } @end
封装的简介头
SummaryHeader.xib
// // SummaryHeader.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 背景是一个四周圆角图片,点击【团购简介】rightDockItem创建出来的控制器的上面一个图文并茂的view,成员有:剩余时间,购买人数,是否支持过期退款,随时退款,以及一张大图 #import <UIKit/UIKit.h> @class Deal; @interface SummaryHeader : UIView // 数据源 @property (nonatomic, strong) Deal *deal; // 与xib进行拖线的控件们 // 大图 @property (weak, nonatomic) IBOutlet UIImageView *image; // 描述,可根据文字行数动态确定高度 @property (weak, nonatomic) IBOutlet UILabel *desc; // 随时退款 @property (weak, nonatomic) IBOutlet UIButton *anyTimeRefund; // 过期退款 @property (weak, nonatomic) IBOutlet UIButton *expireRefund; // 剩余时间 @property (weak, nonatomic) IBOutlet UIButton *timeLeft; // 购买人数 @property (weak, nonatomic) IBOutlet UIButton *purchaseCount; // 类方法提供一个实例对象,内部会加载对应的xib + (id)summaryHeader; @end
// // SummaryHeader.m // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 背景是一个四周圆角图片,点击【团购简介】rightDockItem创建出来的控制器的上面一个图文并茂的view,成员有:剩余时间,购买人数,是否支持过期退款,随时退款,以及一张大图 #import "SummaryHeader.h" #import "Deal.h" // 限制条件,如(是否需要预约、是否支持随时退款、(购买须知)附加信息) #import "Restriction.h" #import "ImgDownloadTool.h" @implementation SummaryHeader // 背景是一个四周圆角图片 - (void)drawRect:(CGRect)rect { [[UIImage imageStretchedWithName:@"bg_order_cell.png"] drawInRect:rect]; } // 类方法提供一个实例对象,内部会加载对应的xib + (id)summaryHeader { return [[NSBundle mainBundle] loadNibNamed:@"SummaryHeader" owner:nil options:nil][0]; } // 拦截setter,为子控件赋值 - (void)setDeal:(Deal *)deal { _deal = deal; if (deal.restrictions) { // 有约束(完整的数据) // 1.设置是否支持退款 _anyTimeRefund.enabled = deal.restrictions.is_refundable; _expireRefund.enabled = _anyTimeRefund.enabled; } else { // 不完整的数据 // 2.下载图片 [ImgDownloadTool imgDownloadWithUrl:deal.image_url tmpImgName:kImgPlaceHolder imageView:_image]; // 3.设置剩余时间 // 设置格式器,将字符串形式的时间转成NSDate对象 NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy-MM-dd"; NSDate *dealline = [fmt dateFromString:deal.purchase_deadline]; // 例如过期时间是:2014-08-21,意思是2014-08-22 00:00:00过期 // 因此真正过期时间,还要加上24小时 dealline = [dealline dateByAddingTimeInterval:24 * 3600]; // 取得当前日期,比如2014-08-21 16:44 NSDate *now = [NSDate date]; // 调用NSDate的分类方法,内部通过公历calendar计算出NSDateComponents NSDateComponents *dateComponents = [now compareWithOther:dealline]; // 从计算好的dateComponents中取出 天 时 分 等 NSString *timeStr = [NSString stringWithFormat:@"%d 天 %d 小时 %d 分钟", dateComponents.day, dateComponents.hour, dateComponents.minute]; [_timeLeft setTitle:timeStr forState:UIControlStateNormal]; } // 4.购买人数 NSString *pc = [NSString stringWithFormat:@"%d 人已购买", deal.purchase_count]; [_purchaseCount setTitle:pc forState:UIControlStateNormal]; // 5.设置描述 _desc.text = deal.desc; // 根据字体和宽度,限制描述Label的高度 CGRect tmpRect = [_desc.text boundingRectWithSize:CGSizeMake(_desc.frame.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:_desc.font,NSFontAttributeName, nil] context:nil]; // 描述的高度 CGFloat descH = tmpRect.size.height +20; CGRect descF = _desc.frame; // 重要~~~根据最新的文字显示的高度与旧的高度的差值,确定整个View的高差变化,这句必须在赋值之前 CGFloat descDeltaH = descH - descF.size.height; descF.size.height = descH; _desc.frame = descF; // 6.设置整体的高度 CGRect selfF = self.frame; selfF.size.height += descDeltaH; self.frame = selfF; } @end
抽取后的简介文本SummaryText.xib
// // SummaryText.h // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 最上面是SummaryHeaderView,下面是若干个SummaryTextView,一个SummaryTextView 代表一个组 如团购详情、购买须知、重要通知 #import <UIKit/UIKit.h> @interface SummaryText : UIView // 标题 @property (weak, nonatomic) IBOutlet UIButton *titleView; // 内容 @property (weak, nonatomic) IBOutlet UILabel *contentView; // 数据源,为子控件提供数据 @property (nonatomic, copy) NSString *icon; // 图标 @property (nonatomic, copy) NSString *title; // 标题 @property (nonatomic, copy) NSString *content; // 内容 // 类方法提供一个实例对象,内部会加载对应的xib + (id)summaryText; @end
// // SummaryText.m // 帅哥_团购 // // Created by beyond on 14-8-21. // Copyright (c) 2014年 com.beyond. All rights reserved. // 最上面是SummaryHeaderView,下面是若干个SummaryTextView,一个SummaryTextView 代表一个组 如团购详情、购买须知、重要通知 #import "SummaryText.h" @implementation SummaryText // 背景是一个四周圆角图片 - (void)drawRect:(CGRect)rect { [[UIImage imageStretchedWithName:@"bg_order_cell.png"] drawInRect:rect]; } // 类方法提供一个实例对象,内部会加载对应的xib + (id)summaryText { return [[NSBundle mainBundle] loadNibNamed:@"SummaryText" owner:nil options:nil][0]; } // 拦截数据源,为对应子控件设置标题 - (void)setIcon:(NSString *)icon { _icon = icon; [_titleView setImage:[UIImage imageNamed:icon] forState:UIControlStateNormal]; } // 拦截数据源,为对应子控件设置标题 - (void)setTitle:(NSString *)title { _title = title; [_titleView setTitle:title forState:UIControlStateNormal]; } // 拦截数据源,为对应子控件设置标题 - (void)setContent:(NSString *)content { _content = content; // 1.设置label的文字 _contentView.text = content; // 2.计算文字的高度 // 根据字体和宽度,限制描述Label的高度 CGRect tmpRect = [_contentView.text boundingRectWithSize:CGSizeMake(_contentView.frame.size.width, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:[NSDictionary dictionaryWithObjectsAndKeys:_contentView.font,NSFontAttributeName, nil] context:nil]; CGFloat textH = tmpRect.size.height + 20; CGRect contentF = _contentView.frame; // 重要~~~根据最新的文字显示的高度与旧的高度的差值,确定整个View的高差变化,这句必须在赋值之前 CGFloat contentDeltaH = textH - contentF.size.height; contentF.size.height = textH; _contentView.frame = contentF; // 3.重要~~~调整整体的高度 CGRect selfF = self.frame; selfF.size.height += contentDeltaH; self.frame = selfF; } @end
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。