概述

接下来,我们要做的是团购界面的设计,最张要实现的效果图及项目结构图

    

团购数据的展示

思路:

  • 系统自带的tableCell不能展示三个文本,不能满足条件,自定义tableCell
  • 每一个tableCell样式固定不变,使用xib来实现。
  • 数据来源通过加载plist文件

定义展示数据模型

Tuangou.h

//
// Tuangou.h
// 9.1团购
//
// Created by jiangys on 15/9/16.
// Copyright (c) 2015年 uxiaoyuan. All rights reserved.
// #import <Foundation/Foundation.h> @interface Tuangou : NSObject
/** 标题 */
@property (nonatomic, copy) NSString *title; /** 价格 */
@property (nonatomic, copy) NSString *price; /** 购买人数 */
@property (nonatomic, copy) NSString *buyCount; /** 图片 */
@property (nonatomic, copy) NSString *icon; -(instancetype)initWithDict:(NSDictionary *)dict;
+(instancetype)tuangouWithDit:(NSDictionary *)dict;
@end

Tuangou.m

#import "Tuangou.h"

@implementation Tuangou

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

使用xib自定义cell

使用xib封装一个view的步骤

  1. 新建一个xib文件描述一个view的内部结构(假设叫做TuangouCell.xib)
  2. 新建一个自定义的类(自定义类需要继承自系统自带的view, 继承自哪个类,  取决于xib根对象的Class),当前继续自UITableViewCell
  3. 新建类的类名最好跟xib的文件名保持一致(比如类名就叫做TuangouCell)
  4. 将xib中的控件 和 自定义类的.m文件 进行连线
  5. 提供一个类方法返回一个创建好的自定义view(屏蔽从xib加载的过程)
  6. 提供一个模型属性让外界传递模型数据
  7. 重写模型属性的setter方法,在这里将模型数据展示到对应的子控件上面
TuangouCell.xib

说明:cell 大小为320*80,图片为95*60。注意要设置identifier为tuangou,为了从缓存中记取cell使用

Tuangou.h

#import <UIKit/UIKit.h>
@class Tuangou; @interface TuangouCell : UITableViewCell /**
* 通过一个tableView来创建一个cell
*/
+ (instancetype)cellWithTableView:(UITableView *)tableView; /** 团购模型 */
@property (nonatomic, strong) Tuangou *tuangou;
@end

TuangouCell.m

#import "TuangouCell.h"
#import "Tuangou.h" @interface TuangouCell()
//将xib中的控件 和 自定义类的.m文件 进行连线
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *titleView;
@property (weak, nonatomic) IBOutlet UILabel *priceView;
@property (weak, nonatomic) IBOutlet UILabel *buyCountView; @end @implementation TuangouCell //提供一个类方法返回一个创建好的自定义view(屏蔽从xib加载的过程)
+ (instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"tuangou";
TuangouCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
// 从xib中加载cell
cell = [[[NSBundle mainBundle] loadNibNamed:@"TuangouCell" owner:nil options:nil] lastObject];
}
return cell;
} //重写模型属性的setter方法,在这里将模型数据展示到对应的子控件上面
- (void)setTuangou:(Tuangou *)tuangou
{
_tuangou = tuangou; // 1.图片
self.iconView.image = [UIImage imageNamed:tuangou.icon]; // 2.标题
self.titleView.text = tuangou.title; // 3.价格
self.priceView.text = [NSString stringWithFormat:@"¥%@", tuangou.price]; // 4.购买数
self.buyCountView.text = [NSString stringWithFormat:@"%@人已购买", tuangou.buyCount];
} @end

控制器实现

Main.storyboard里拉入一个TableView,并设置ViewController为dataSouce数据源。

ViewController.m

#import "ViewController.h"
#import "Tuangou.h"
#import "TuangouCell.h" @interface ViewController ()<UITableViewDataSource>
@property (weak, nonatomic) IBOutlet UITableView *tableView; /** 数据源 */
@property (nonatomic, strong) NSMutableArray *tgs; @end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.tableView.rowHeight=;
} /**
* 数据的懒加载
*/
-(NSMutableArray *)tgs
{
if(_tgs==nil)
{
NSString *path=[[NSBundle mainBundle] pathForResource:@"tgs.plist" ofType:nil];
NSArray *dictArray=[NSArray arrayWithContentsOfFile:path]; NSMutableArray *tgArray=[NSMutableArray array];
for (NSDictionary *dict in dictArray) {
Tuangou *tg=[Tuangou tuangouWithDit:dict];
[tgArray addObject:tg];
}
_tgs=tgArray;
}
return _tgs;
} /**
* 一共有多少行数据
*/
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tgs.count;
} /**
* 每一行显示怎样的cell
*/
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 1.创建cell
TuangouCell *cell = [TuangouCell cellWithTableView:tableView]; // 2.给cell传递模型数据
cell.tuangou = self.tgs[indexPath.row];
return cell;
} /**
* 隐藏状态栏
*/
- (BOOL)prefersStatusBarHidden
{
return YES;
}
@end

这样,运行起来,就看到数据已经加载了,效果:

加载更多数据

建立TuangouFooterView.xib

说明:UIView的大小为320*44。Button 为300*35 。View下面封装了菊花和Lable,设置Hidden为Yes。

新建一个xib根对象的Class ,并定义代理。

TuangouFooterView.h

#import <UIKit/UIKit.h>
@class TuangouFooterView; @protocol TuangouFooterViewDelegate <NSObject> @optional
-(void)tuangouFooterDidClickedLoadBtn:(TuangouFooterView *)tuangouFooterView; @end
@interface TuangouFooterView : UIView
/**
* 快速创建一个footerView对象
*/
+ (instancetype)footerView; // 要使用weak,避免循环引用
@property(nonatomic,weak) id<TuangouFooterViewDelegate> delegate;
@end

TuangouFooterView.m

#import "TuangouFooterView.h"

@interface TuangouFooterView()
@property (weak, nonatomic) IBOutlet UIButton *loadBtn;
@property (weak, nonatomic) IBOutlet UIView *loadingView;
- (IBAction)loadBtnClick; @end @implementation TuangouFooterView + (instancetype)footerView
{
return [[[NSBundle mainBundle] loadNibNamed:@"TuangouFooterView" owner:nil options:nil] lastObject];
} /**
* 点击"加载"按钮
*/
- (IBAction)loadBtnClick {
// 1.隐藏加载按钮
self.loadBtn.hidden = YES; // 2.显示"正在加载"
self.loadingView.hidden = NO; // 3.显示更多的数据
// GCD ,1s后执行时面的代码
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // 通知代理,先判断是否有实现代理的方法。
if ([self.delegate respondsToSelector:@selector(tuangouFooterDidClickedLoadBtn:)]) {
[self.delegate tuangouFooterDidClickedLoadBtn:self];
} // 4.显示加载按钮
self.loadBtn.hidden = NO; // 5.隐藏"正在加载"
self.loadingView.hidden = YES;
});
}
@end

ViewController.m就很简单了,实现TuangouFooterViewDelegate代理。

@interface ViewController ()<UITableViewDataSource,TuangouFooterViewDelegate>

设置代理

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.tableView.rowHeight=; TuangouFooterView *footerView=[TuangouFooterView footerView];
footerView.delegate=self;// 设置当前footerView为代理
self.tableView.tableFooterView=footerView;
}

实现里面的代理方法

/**
* 加载更多的数据
*/
- (void)tuangouFooterDidClickedLoadBtn:(TuangouFooterView *)tuangouFooterView
{
#warning 正常开发:发送网络请求给远程的服务器
// 1.添加更多的模型数据
Tuangou *tg = [[Tuangou alloc] init];
tg.icon = @"ad_01";
tg.title = @"新增加的团购数据..";
tg.price = @"";
tg.buyCount = @"";
[self.tgs addObject:tg]; // 2.刷新表格(告诉tableView重新加载模型数据, 调用tableView的reloadData)
[self.tableView reloadData];
}

效果:

使用delegate的步骤

1.先搞清楚谁是谁的代理(delegate)
2.定义代理协议,协议名称的命名规范:控件类名 + Delegate
3.定义代理方法
  • 代理方法一般都定义为@optional
  • 代理方法名都以控件名开头
  • 代理方法至少有1个参数,将控件本身传递出去
4.设置代理(delegate)对象  (比如myView.delegate = xxxx;)
代理对象遵守协议
代理对象实现协议里面该实现的方法
5.在恰当的时刻调用代理对象(delegate)的代理方法,通知代理发生了什么事情

(在调用之前判断代理是否实现了该代理方法)

加载顶部广告

新建一个TuangouHeaderView.xib

说明:分割线使用的是UIView,宽为320,高为1,Background 设置为灰色,Alpha 设置为0.5 。

TuangouHeaderView.h

#import <UIKit/UIKit.h>

@interface TuangouHeaderView : UIView
+ (instancetype)headerView;
@end

TuangouHeaderView.m

#import "TuangouHeaderView.h"

@interface TuangouHeaderView()

@end

@implementation TuangouHeaderView

+ (instancetype)headerView
{
return [[[NSBundle mainBundle] loadNibNamed:@"TuangouHeaderView" owner:nil options:nil] lastObject];
} /**
* 当一个对象从xib中创建初始化完毕的时候就会调用一次
*/
- (void)awakeFromNib
{
// 在这里面添加图片轮播器
} @end

当然,这一块可以使用幻灯,幻灯的效果请参考:http://www.cnblogs.com/jys509/p/4811509.html

最终效果

源代码下载:点击下载

iOS UI基础-9.1 UITableView 团购的更多相关文章

  1. iOS UI基础-9.0 UITableView基础

    在iOS中,要实现表格数据展示,最常用的做法就是使用UITableView.UITableView继承自UIScrollView,因此支持垂直滚动,而且性能极佳. UITableView有两种样式: ...

  2. iOS UI基础-9.2 UITableView 简单微博列表

    概述 我们要实现的效果: 这个界面布局也是UITableView实现的,其中的内容就是UITableViewCell,只是这个UITableViewCell是用户自定义实现的.虽然系统自带的UITab ...

  3. iOS UI基础-17.0 UILable之NSMutableAttributedString

    在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘UILabel的textLayer,有的是用html5实现的,都比较麻烦 ...

  4. IOS UI 第十一篇: UITABLEVIEW

    DIY a tableviewcell :   - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *) ...

  5. IOS UI 第十篇: UITABLEVIEW

    uitableView review yesterday’s knowledge :         folding group :   ------------------------------- ...

  6. iOS UI基础-19.0 UICollectionView

    直接上代码,说明请看注释吧 1.继承三个代理 UICollectionViewDataSource,UICollectionViewDelegate,UICollectionViewDelegateF ...

  7. iOS UI基础-13.0 数据存储

    应用沙盒 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 应用沙盒的文件系统目录,如下图所示(假设应用的名称叫Lay ...

  8. iOS UI基础-6.0 UIActionSheet的使用

    UIActionSheet是在iOS弹出的选择按钮项,可以添加多项,并为每项添加点击事件. 使用 1.需要实现UIActionSheetDelegate  协议 @interface NJWisdom ...

  9. iOS UI基础-4.2应用程序管理 Xib文件使用

    Xib调整使用 1.新建xib文件 New File-->User Interface-->Empty 2.打开新建的xib文件,出现可视化窗口 (1)拖入一个UIView (不是UIVi ...

随机推荐

  1. 洛谷P1032 字串变换【bfs】

    题目链接:https://www.luogu.org/problemnew/show/P1032 题意: 给定一个原字符串和目标字符串,以及几个字符串变换的规则. 问能否根据这几个规则在十步之内把原字 ...

  2. 通过Jenkins在IIS上布署站点

    当需要在多台服务器的IIS上布署站点时,如果纯粹靠人工手动完成此任务的话,过于低效,而借助Jenkins之类的自动化工具,则可以极大提升工作效率. 以下便是Jenkins Pipeline所使用的脚本 ...

  3. atoi函数的用法

    库函数原型: #inclue <stdlib.h> int atoi(const char *nptr); 用法:将字符串里的数字字符转化为整形数.返回整形值. 注意:转化时跳过前面的空格 ...

  4. java整形数据和浮点型数据

    在定义数据的时候,如果有不是整形的数据(单精度,双精度之类的),那么运算的时候要在其所在式子里的数据后面加上.0,否则会出现(1/2=0.1.0/2=0.5)的现象,比如如下代码 public cla ...

  5. Python:if __name__ == '__main__'

    简介: __name__是当前模块名,当模块被直接运行时模块名为_main_,也就是当前的模块,当模块被导入时,模块名就不是__main__,即代码将不会执行. 关于代码if __name__ == ...

  6. Yarn && npm设置镜像源

    安装yarn npm i -g yarn yarn yarn config set registry https://registry.npm.taobao.org --global yarn con ...

  7. Java代理和动态代理机制分析和应用

    本博文中项目代码已开源下载地址:GitHub Java代理和动态代理机制分析和应用 概述 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息 ...

  8. ldap,openldap-docker,

    ldap basic and usage in devops: https://blog.csdn.net/weixin_42578481/article/details/80863890 maybe ...

  9. [qemu][kvm] 在一个vmware虚拟机里安装qemu-kvm虚拟机

    说起来这个需求,简直是傻傻的.但却实实在在的摆在我的面前.... VM无外乎就是为了模拟场景:我现在要的场景就是一台很多个core的linux主机.但是我只有一个装了windows的笔记本.上边有一个 ...

  10. 文件处理----Properties文件处理

    properties是一种属性文件,这种文件以key=value格式存储内容,代码中可以使用Properties类来读取这个文件,然后得到数据. 当配置文件用,由于难以表达层次,复杂点可以使用xml做 ...