最终效果图:
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