您的位置:首页 > 产品设计 > UI/UE

IOS_UI_控件总结+九宫格+仿QQ好友列表+小图片拉伸

2014-05-28 23:08 615 查看
H:/0718/00_UIKit_控件总结.m
一、UIView常见属性
1.frame  位置和尺寸(以父控件的左上角为原点(0,0))
2.center 中点(以父控件的左上角为原点(0,0))
3.bounds  位置和尺寸(以自己的左上角为原点(0,0))
4.transform  形变属性(缩放、旋转)
5.backgroundColor 背景颜色
6.tag  标识(父控件可以根据这个标识找到对应的子控件,同一个父控件中的子控件tag不要一样)
7.hidden 设置是否要隐藏
8.alpha  透明度(0~1)
9.opaque 不透明度(0~1)
10.userInteractionEnabled  能否跟用户进行交互(YES能交互)
11.superview 父控件
12.subviews 子控件
13.contentMode 内容显示的模式
二、UIView常见方法
1.addSubview:
添加子控件,被添加到最上面(subviews中的最后面)
2.removeFromSuperview
从父控件中移除
3.viewWithTag:
父控件可以根据这个tag标识找到对应的子控件(遍历所有的子控件)
4.insertSubview:atIndex:
添加子控件到指定的位置
5.利用两个类方法执行动画
+ (void)beginAnimations:(NSString *)animationID context:(void *)context;
/* ...需要执行动画的代码..*/
+ (void)commitAnimations;
6.利用block执行动画
/* duration 动画持续时间
animations 存放需要执行动画的代码
completion  存放动画完毕后需要执行的操作代码*/
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
三、UIControl
1.只要继承了UIControl,就能简单处理一些事件(点击事件、值改变事件)
2.继承了UIControl的子类:
UIButton、UISlider、UISwitch、UIDatePicker等等
3.当需要监听一个子控件事件的时候,解决步骤:
1> 先看它是否继承自UIControl
2> 再看它内部是否有delegate属性
4.常用属性
1> enabled 能否处理事件,跟UIView的userInteractionEnabled属性类似
2> contentVerticalAlignment 内容在垂直方向上的排布方式
3> contentHorizontalAlignment 内容在水平方向上的排布方式
5.常用方法
1> 添加监听器
/* target 监听器对象
action  事件触发时所调用的方法,调用target的方法
controlEvents 事件类型 */
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
2> 删除监听器
// 删除监听器后,事件触发时就不会再通知监听器了,也就不会再调用target的action方法了
- (void)removeTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents;
3> 获得所有的监听器对象
- (NSSet *)allTargets;
四、UILabel的常见属性
1.text 所显示的文本内容
2.textColor  文本颜色
3.font  字体
4.shadowColor 文字的阴影颜色
5.shadowOffset 阴影的偏差距离(width水平方向的偏差距离,正数右边、height垂直方向的偏差距离,正数下边)
6.textAlignment  设置文字的排布方式(偏左、偏右、居中)
7.numberOfLines 允许文字最多有几行(默认是1,如果为0,自动换行)
五、UIButton
1.常见属性
1> titleLabel 获取内部的UILabel对象
2> imageView 获取内部的UIImageView对象
2.常见方法
1> 设置内部UILabel显示的文本内容
// 设置按钮文本的时候不能  btn.titleLabel.text = @"4324324";
- (void)setTitle:(NSString *)title forState:(UIControlState)state;
2> 设置内部UILabel的文字颜色
- (void)setTitleColor:(UIColor *)color forState:(UIControlState)state;
3> 设置内部UILabel的文字阴影颜色
- (void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state;
4> 设置内部UIImageView的图片
// 设置内部UIImageView的图片不能:btn.imageView.image = [UIImage imagedName:@"0.png"];
- (void)setImage:(UIImage *)image forState:(UIControlState)state;
5> 设置背景图片
- (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state;
6> 下面两个方法需要交给子类去重写
// 返回内部UILabel的frame(位置和尺寸)
- (CGRect)titleRectForContentRect:(CGRect)contentRect;
// 返回内部UIImageView的frame(位置和尺寸)
- (CGRect)imageRectForContentRect:(CGRect)contentRect;
7> 下面这些方法可以获取不同状态下的一些属性值
- (NSString *)titleForState:(UIControlState)state;
- (UIColor *)titleColorForState:(UIControlState)state;
- (UIColor *)titleShadowColorForState:(UIControlState)state;
- (UIImage *)imageForState:(UIControlState)state;
- (UIImage *)backgroundImageForState:(UIControlState)state;

H:/0718/01_九宫格_MJViewController.h
//  MJViewController.h
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
/* 1.添加图片资源
2.初始化测试数据(Product)
3.添加UITableView(数据源、代理、实现相应的方法)
4.自定义Cell(ProductRowCell,创建3、4、5个格子)
5.设置显示的数据(截取每一行Cell所需的数据,再按顺序显示到对应的格子上)
6.调整按钮内部UIImageView和UILabel的位置*/

#import <UIKit/UIKit.h>
@interface MJViewController : UITableViewController
@end

H:/0718/01_九宫格_MJViewController.m
//  MJViewController.m
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 . All rights reserved.
/* 1.添加图片资源
2.初始化测试数据(Product)
3.添加UITableView(数据源、代理、实现相应的方法)
4.自定义Cell(ProductRowCell,里面可以随便创建3、4、5个格子)
5.重点!!!设置显示的数据(截取每一行Cell所需的数据组成参数数组,再交给cell按顺序显示到对应的格子上)
6.自定义按钮,目的是重写方法,方便调整按钮内部UIImageView和UILabel的位置*/
#import "MJViewController.h"
#import "Product.h"
#import "ProductRowCell.h"
@interface MJViewController ()
//成员可变数组,模拟数据来源,填充假数据
@property (nonatomic, strong) NSMutableArray *products;
@end
@implementation MJViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 不允许选中TableView的一整行
self.tableView.allowsSelection = NO;
// 初始化产品数据
self.products = [NSMutableArray array];
for (int i = 1; i<=39; i++) {
// 初始化产品对象
Product *p = [[Product alloc] init];
// 设置产品名称
p.name = [NSString stringWithFormat:@"产品-%d", i];
// 设置产品图标(1~11.png)
int iconIndex = arc4random_uniform(11) + 1;
p.icon = [NSString stringWithFormat:@"images.bundle/tmall_icon_cat_outing_%d.png", iconIndex];
// 添加产品到成员产品数组
[self.products addObject:p];
}
}
#pragma mark - 数据源、代理方法
#pragma mark numberOfRowsInSection,返回对应Section的行数
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
/*
假设列数为3,即每一row显示三个按钮(每个按钮展示一个产品)
1.情况之一:产品个数除于列数的余数为0
个数:3、6、9、12、15。。。。
行数:1、2、3、 4、5。。。。个数/列数

2.情况之二:产品个数除于列数的余数不为0
个数:4、7、16。。。。
行数:2、3、6。。。。个数/列数 + 1*/

/*
if (self.products.count%kColumn==0) { // 余数为0
return self.products.count/kColumn;
} else { // 余数不为0
return self.products.count/kColumn + 1;
}*/
// 优化的算法,行数 = (产品数 + 列数 -1)/列数
return (self.products.count + kColumn - 1) / kColumn;
}

#pragma mark 每当有一个cell进入视野范围内就会调用,返回当前这行显示的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 0.用static修饰的局部变量,只会初始化一次
static NSString *ID = @"cell";
// 1.拿到一个标识先去缓存池中查找对应的Cell(ProductRowCell)
ProductRowCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 2.如果缓存池中没有,才需要传入一个标识创建新的Cell
if (cell == nil) {
cell = [[ProductRowCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
// 3.为cell填充独一无二的数据!
// 自定义Cell:每一个Cell里面都有N个格子,N即常量列数kColumn
//截取这行Cell所需的产品数据
/*假设产品总个数:16
每行显示3个格子,即MyButton(内含产品图片和名称)
则产品索引范围:0~15
cell的行号  对应所需展现的产品的索引值范围(注意最后一个cell)
0:      0 1 2
1:      3 4 5
2:      6 7 8
3:      9 10 11
4:      12 13 14
5:      15*/
// 从产品数组中,截取的开始位置,即所在行号 * 常量列数
int location = indexPath.row * kColumn;
// 从产品数组,要截取的长度(即要分配给对应row的cell的产品)
int length = kColumn;
// 特殊情况:最后一行的cell,可能产品不够,如果截取的范围越界
if (location + length >= self.products.count) {
//给最后一行的cell,分派产品,供它展示
//例如:16-15=1,最后一行的cell只能展示一个格子
length = self.products.count - location;
}
// 从产品数组,要给对应的row的cell,分派的产品个数,即截取范围
NSRange range = NSMakeRange(location, length);
// 根据截取范围,从产品总数组中,获取这行所需的产品个数,交给cell自行填充
NSArray *rowProducts = [self.products subarrayWithRange:range];
// cell自行填充,设置这个行Cell所需的产品数据
[cell setRowProducts:rowProducts];
return cell;
}
#pragma mark 每一行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return kCellHeight;
}

@end

H:/0718/01_九宫格_MyButton.h
//  MyButton.h
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import <UIKit/UIKit.h>
@interface MyButton : UIButton
@end

H:/0718/01_九宫格_MyButton.m
//  MyButton.m
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.

//自定义按钮 继承自UIButton

// 按钮里面,图片所占的高度比例
#define kImageRatio 0.7
#import "MyButton.h"
@implementation MyButton
#pragma mark 任何方式(代码)创建按钮都会调用这个方法
- (id)initWithFrame:(CGRect)frame
{
//先调用父类的方法
if (self = [super initWithFrame:frame]) {
// 设置按钮文字颜色
[self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// 设置按钮中的文字居中
self.titleLabel.textAlignment = NSTextAlignmentCenter;
// 让图片按照原来的宽高比显示出来,即自适应AspectFit
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
// 设置按钮文字的字体尺寸
self.titleLabel.font = [UIFont systemFontOfSize:15];
// 设置按钮里面的内容(即控件UILabel、UIImageView)居中
// btn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
}
return self;
}

#pragma mark - 重写UIButton的imageRectForContentRect方法
#pragma mark 目的是要控制按钮里面的UIImageView的位置和尺寸
//  参数:contentRect其实就是按钮的位置和尺寸
//  返回值:按钮里面的UIImageView的位置和尺寸
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
CGFloat imageX = 0;
CGFloat imageY = 0;
//按钮里面的图片宽:为按钮宽
CGFloat imageWidth = contentRect.size.width;
//按钮里面的图片高:为按钮高*0.7
CGFloat imageHeight = contentRect.size.height * kImageRatio;
return CGRectMake(imageX, imageY, imageWidth, imageHeight);
}

#pragma mark - 重写UIButton的titleRectForContentRect方法
#pragma mark 目的是要控制按钮里面的UILabel的位置和尺寸
//  参数:contentRect其实就是按钮的位置和尺寸
//  返回值:按钮里面的UILabel的位置和尺寸
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
CGFloat titleX = 0;
//按钮里面UILabel的Y:为图片的最大Y值(即最下面的位置)
CGFloat titleY = contentRect.size.height * kImageRatio;
//按钮里面的UILabel宽:为按钮宽
CGFloat titleWidth = contentRect.size.width;
//按钮里面的UILabel高:为按钮高-Y坐标(即按钮内除去图片余下的所有高度)
CGFloat titleHeight = contentRect.size.height - titleY;
return CGRectMake(titleX, titleY, titleWidth, titleHeight);
}
@end

H:/0718/01_九宫格_Product.h
//  Product.h
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
//  产品类
#import <Foundation/Foundation.h>
@interface Product : NSObject
// 产品图片名
@property (nonatomic, strong) NSString *icon;
// 产品名称
@property (nonatomic, strong) NSString *name;
@end

H:/0718/01_九宫格_Product.m
//  Product.m
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "Product.h"
@implementation Product
@end

H:/0718/01_九宫格_ProductRowCell.h
//  ProductRowCell.h
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import <UIKit/UIKit.h>
// 每一行要显示多少列数
#define kColumn 5
// 每一行cell的高度
#define kCellHeight 100
@interface ProductRowCell : UITableViewCell
// 设置这一行对应的产品数据(1~3),例如排3列时,前面参数是3个产品,最后一行可能只有1-2个产品
- (void)setRowProducts:(NSArray *)rowProducts;
@end

H:/0718/01_九宫格_ProductRowCell.m
//  ProductRowCell.m
//  01-九宫格
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
//定义每个格子,即按钮的tag起始值,方便找到cell中对应的MyButton
#define kTagStart 100
#import "ProductRowCell.h"
#import "Product.h"
#import "MyButton.h"
@implementation ProductRowCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
//先调用父类的构造方法
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// 根据常量:每一行cell要显示的列数添加对应数目个格子
// self.frame.size.height 永远是44
for (int i = 0; i<kColumn; i++) {
// 初始化格子(自定义的button,只能用custome样式)按钮的构造方法内设置了...
MyButton *btn = [MyButton buttonWithType:UIButtonTypeCustom];
//[[MyButton alloc] initWithFrame:<#(CGRect)#>];
//[[MyButton alloc] init];
// 设置一行中,每个格子的宽高和位置
//每个格子的宽:cell一行的宽/列数(即一行的格子数)
CGFloat btnWidth = self.frame.size.width / kColumn;
//每个格子的x坐标:i*格子宽
CGFloat btnX = i * btnWidth;
//每个格子的y都是0
CGFloat btnY = 0;
//每个格子的高度,就是cell的高度
CGFloat btnHeight = kCellHeight;
btn.frame = CGRectMake(btnX, btnY, btnWidth, btnHeight);
// 设置每个格子的tag,方便填充产品数据到cell中的每个格子
btn.tag = i + kTagStart;
// 添加格子到cell的contentView中
[self.contentView addSubview:btn];
}
}
return self;
}
#pragma mark 设置所有格子的数据(个数可能是1、2、3、...kColumn)
// 参数:对应个数的产品组成的数组(可能是3个,最后一行row对应的cell也可能是2个,或1个)
- (void)setRowProducts:(NSArray *)rowProducts
{
// 遍历所有的格子
for (int i = 0; i<kColumn; i++) {
// 格子的tag
int tag = i + kTagStart;
// 取出对应的格子
MyButton *btn = (MyButton *)[self.contentView viewWithTag:tag];
// 重点!!!!!如果这个格子没有对应的数据,特别是指最后一行cell的格子
//条件:如果i > 参数数组里最大的下标
if (i>rowProducts.count - 1) {
btn.hidden = YES; // 由于没有产品数据要展现,隐藏格子
} else { // 如果这个格子有对应的数据
// 获得这个格子对应的产品数据
Product *p = rowProducts[i];
// 设置格子的产品名称
[btn setTitle:p.name forState:UIControlStateNormal];
// 设置格子显示的图片
UIImage *image = [UIImage imageNamed:p.icon];
// 设置内部UIImageView的图片
[btn setImage:image forState:UIControlStateNormal];
// 设置背景图片,会被拉伸
//[btn setBackgroundImage:image forState:UIControlStateNormal];
//记住!千万要显示格式(产品),在cell重用reuse时见效果~~~
btn.hidden = NO; // 显示格子
}
}
}
@end

H:/0718/02_QQ好友列表_friends.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>group</key>
<string>我的好友</string>
<key>friends</key>
<array>
<string>2B</string>
<string>战斗机</string>
<string>西门吹雪</string>
<string>西门抽血</string>
<string>西门抽筋</string>
<string>西门抽奖</string>
<string>西门庆</string>
</array>
</dict>
<dict>
<key>group</key>
<string>大学同学</string>
<key>friends</key>
<array>
<string>大学同学1</string>
<string>大学同学2</string>
<string>大学同学3</string>
<string>大学同学4</string>
<string>大学同学5</string>
<string>大学同学6</string>
<string>大学同学7</string>
<string>大学同学8</string>
</array>
</dict>
<dict>
<key>group</key>
<string>高中同学</string>
<key>friends</key>
<array>
<string>高中同学1</string>
<string>高中同学2</string>
<string>高中同学3</string>
</array>
</dict>
<dict>
<key>group</key>
<string>初中同学</string>
<key>friends</key>
<array>
<string>初中同学1</string>
<string>初中同学2</string>
<string>初中同学3</string>
<string>初中同学4</string>
<string>初中同学5</string>
<string>初中同学6</string>
</array>
</dict>
<dict>
<key>group</key>
<string>小学同学</string>
<key>friends</key>
<array>
<string>小学同学1</string>
<string>小学同学2</string>
<string>小学同学3</string>
<string>小学同学4</string>
<string>小学同学5</string>
</array>
</dict>
<dict>
<key>group</key>
<string>老乡</string>
<key>friends</key>
<array>
<string>老乡1</string>
<string>老乡2</string>
<string>老乡3</string>
<string>老乡4</string>
</array>
</dict>
<dict>
<key>group</key>
<string>欠我钱的</string>
<key>friends</key>
<array>
<string>王八羔子</string>
<string>

H:/0718/02_QQ好友列表_HeaderView.h
//  HeaderView.h
//  02-QQ好友列表
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import <UIKit/UIKit.h>
//实际上是一个按钮
@interface HeaderView : UIButton
@end

H:/0718/02_QQ好友列表_HeaderView.m
//  HeaderView.m
//  02-QQ好友列表
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "HeaderView.h"
@implementation HeaderView
//自定义按钮的构造方法
- (id)initWithFrame:(CGRect)frame
{
//先调用父类的构造方法
self = [super initWithFrame:frame];
if (self) {
//图片显示模式:自适应
//self.imageView.contentMode = UIViewContentModeScaleAspectFit;
// 只允许这种方法设置按钮内部UIImageview要显示的图片
[self setImage:[UIImage imageNamed:@"disclosure.png"] forState:UIControlStateNormal];
//[self setBackgroundImage:<#(UIImage *)#> forState:<#(UIControlState)#>];
}
return self;
}
#pragma mark 重写按钮的方法,目的是设置UIImageView的位置和尺寸
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
return CGRectMake(0, 0, 32, 32);
}
@end

H:/0718/02_QQ好友列表_MJViewController.h
//  MJViewController.h
//  02-QQ好友列表
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
/* 1.加载好友数据
2.简单地分组显示好友数据
3.实现tableView:viewForHeaderInSection:方法返回每一组的标题对象
4.监听标题的点击事件
* 初始化一个字典对象,用来记录每一组的状态(展开\合并)
* 点击标题后,对每一组的状态进行取反
* 刷新数据(reloadData)
5.添加箭头*/
#import <UIKit/UIKit.h>
@interface MJViewController : UITableViewController
@end

H:/0718/02_QQ好友列表_MJViewController.m
//  MJViewController.m
//  02-QQ好友列表
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
/* 1.加载好友数据,mainBundle得到path,根据path得到字典数组,
字典数组的:每个成员都是字典,字典中共2对键值,
其中"group"对应分组名,"friends"对应数组,
数组每个成员都是一个好友名称
2.简单地分组显示好友数据
3.实现tableView:viewForHeaderInSection:方法返回每一组的标题对象视图
4.监听标题的点击事件
* 初始化一个字典对象,作用是:记录每一组的状态(展开\合并)
* 点击标题后,对每一组的状态进行取反
* 刷新数据(reloadData)
5.添加箭头*/
#import "MJViewController.h"
#import "HeaderView.h"
@interface MJViewController ()
/*字典数组的:每个成员都是字典,字典中共2对键值,
其中"group"对应分组名,"friends"对应数组,
数组每个成员都是一个好友名称*/
@property (nonatomic, strong) NSArray *allFriends;
// 存放所有组的展开\合并状态
// key=组号  value=对应组的状态(1代表展开,0代表合并)
@property (nonatomic, strong) NSMutableDictionary *status;
@end
@implementation MJViewController
#pragma mark - View加载完毕
- (void)viewDidLoad
{
[super viewDidLoad];
// 加载好友数据
NSString *path = [[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"];
self.allFriends = [NSArray arrayWithContentsOfFile:path];
// 初始化状态字典
self.status = [NSMutableDictionary dictionary];
}
#pragma mark - 数据源、代理方法
#pragma mark 有多少组数据
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//字典数组中字典的个数,即分组数
return self.allFriends.count;
}
#pragma mark 每一组中有多少行数据
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// 取出第section组对应的状态
int result = [self.status[@(section)] intValue];
if (result == 0) {
// 代表当前组是:合并状态,故返回0行,即不显示
return 0;
} else { // 展开状态
// 1.先获取这组对应的数据
NSDictionary *group = self.allFriends[section];
// 2.获取这组里面的好友数组,返回好友数组长度
NSArray *friends = group[@"friends"];
return friends.count;
}
}
#pragma mark 每当有一个cell进入视野范围内就会调用,返回当前这行显示的cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 0.用static修饰的局部变量,只会初始化一次
static NSString *ID = @"cell";
// 1.拿到一个标识先去缓存池中查找对应的Cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 2.如果缓存池中没有,才需要传入一个标识创建新的Cell
if (cell == nil) {
//UITableViewCellStyleSubtitle
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
// 3.封装这行独一无二的数据
// 3.1 获取这组对应的字典数据
NSDictionary *dict = self.allFriends[indexPath.section];
// 3.2 获取这组的好友数据
NSArray *friends = dict[@"friends"];
// 3.3 设置具体数据,好友名称
cell.textLabel.text = friends[indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"me.jpeg"];
cell.detailTextLabel.text = @"正在输入中....";
return cell;
}
#pragma mark 每一行的高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 50;
}
#pragma mark 每一组标题的高度
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 40;
}
#pragma mark 第section组对应的标题
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
//创建自定义按钮HeaderView,作为标题栏,目的响应点击,进行展开和闭合
HeaderView *titleView = [HeaderView buttonWithType:UIButtonTypeCustom];
// 设置标题内容
NSDictionary *dict = self.allFriends[section];
[titleView setTitle:dict[@"group"] forState:UIControlStateNormal];
// 设置标题颜色
[titleView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
// 设置背景颜色
[titleView setBackgroundColor:[UIColor grayColor]];
// 重点!!!设置按钮的tag为组号,方便点击方法里面调用!
titleView.tag = section;
// 监听标题点击
[titleView addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];
// 取出第section组的状态
int result = [self.status[@(section)] intValue];
// 对状态进行取反
if (result == 0) {
//如果是闭合,图片箭头向右
titleView.imageView.transform = CGAffineTransformIdentity;
} else {
//如果是展开,图片箭头向下,顺时针转90度
titleView.imageView.transform = CGAffineTransformMakeRotation(M_PI_2);
}
return titleView;
}
#pragma mark - 监听标题点击,先改数据模型,再刷新视图
- (void)titleClick:(UIButton *)btn {
// 取出标题按钮对应的组号,即为被单击的组
int section = btn.tag;
// 取出第section组的状态
int result = [self.status[@(section)] intValue];
// 对状态进行取反
if (result == 0) {
[self.status setObject:@1 forKey:@(section)];
} else {
[self.status setObject:@0 forKey:@(section)];
}
// 刷新数据(会重新给数据源发送消息)
[self.tableView reloadData];
}
//下面这个代理方法,只能设置标题的文字,不能设置标题的视图view
//- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
//{
//    // 1.获取这组对应的字典数据
//    NSDictionary *dict = self.allFriends[section];
//    return dict[@"group"];
//}
@end

H:/0718/03_小图片拉伸_MJViewController.m
//  MJViewController.m
//  03-小图片拉伸
//  Created by apple on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "MJViewController.h"
@interface MJViewController ()
@end
@implementation MJViewController
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(10, 10, 250, 200);
[btn setTitle:@"rsdrwerwerwerwer" forState:UIControlStateNormal];
UIImage *image = [UIImage imageNamed:@"chatfrom_bg_normal.png"];
// 设置图片左边不需要拉伸的宽度
CGFloat leftWidth = image.size.width * 0.5;
// 设置图片顶部不需要拉伸的高度
CGFloat topHeight = image.size.height * 0.6;
//IOS4.0已经存在的方法stretchableImageWithLeftCapWidth
image = [image stretchableImageWithLeftCapWidth:leftWidth topCapHeight:topHeight];
[btn setBackgroundImage:image forState:UIControlStateNormal];
[self.view addSubview:btn];
/*
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.frame = CGRectMake(100, 100, 100, 60);
UIImage *image = [UIImage imageNamed:@"bg.png"];
image = [image stretchableImageWithLeftCapWidth:image.size.width * 0.5 topCapHeight:image.size.height * 0.5];
[btn setBackgroundImage:image forState:UIControlStateNormal];
[self.view addSubview:btn];*/
//UIEdgeInsetsMake(<#CGFloat top#>, <#CGFloat left#>, <#CGFloat bottom#>, <#CGFloat right#>)
// ios 5.0 UIEdgeInsets可以分别设置上下左右不需要拉伸的范围
[image resizableImageWithCapInsets:<#(UIEdgeInsets)#>];
// ios 6.0UIImageResizingMode可以设置是Tile平铺,还是stretch拉撑
[image resizableImageWithCapInsets:<#(UIEdgeInsets)#> resizingMode:<#(UIImageResizingMode)#>];
}
@end

H:/0718/04_QQ好友列表_friends.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>group</key>
<string>我的好友</string>
<key>friends</key>
<array>
<string>2B</string>
<string>战斗机</string>
<string>西门吹雪</string>
<string>西门抽血</string>
<string>西门抽筋</string>
<string>西门抽奖</string>
<string>西门庆</string>
</array>
</dict>
<dict>
<key>group</key>
<string>大学同学</string>
<key>friends</key>
<array>
<string>大学同学1</string>
<string>大学同学2</string>
<string>大学同学3</string>
<string>大学同学4</string>
<string>大学同学5</string>
<string>大学同学6</string>
<string>大学同学7</string>
<string>大学同学8</string>
</array>
</dict>
<dict>
<key>group</key>
<string>高中同学</string>
<key>friends</key>
<array>
<string>高中同学1</string>
<string>高中同学2</string>
<string>高中同学3</string>
</array>
</dict>
<dict>
<key>group</key>
<string>初中同学</string>
<key>friends</key>
<array>
<string>初中同学1</string>
<string>初中同学2</string>
<string>初中同学3</string>
<string>初中同学4</string>
<string>初中同学5</string>
<string>初中同学6</string>
</array>
</dict>
<dict>
<key>group</key>
<string>小学同学</string>
<key>friends</key>
<array>
<string>小学同学1</string>
<string>小学同学2</string>
<string>小学同学3</string>
<string>小学同学4</string>
<string>小学同学5</string>
</array>
</dict>
<dict>
<key>group</key>
<string>老乡</string>
<key>friends</key>
<array>
<string>老乡1</string>
<string>老乡2</string>
<string>老乡3</string>
<string>老乡4</string>
</array>
</dict>
<dict>
<key>group</key>
<string>欠我钱的</string>
<key>friends</key>
<array>
<string>王八羔子</string>
<string>

H:/0718/04_QQ好友列表_Header.h
//
//  Header.h
//  QQ好友列表
//
//  Created by mj on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface Header : UIButton
//按钮成员,记住是否展开该组
@property (nonatomic, assign) BOOL open;
@end

H:/0718/04_QQ好友列表_Header.m
//  Header.m
//  QQ好友列表
//  Created by mj on 13-7-18.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "Header.h"
@implementation Header
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setImage:[UIImage imageNamed:@"disclosure.png"] forState:UIControlStateNormal];
self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.adjustsImageWhenHighlighted = NO;
}
return self;
}
- (void)setOpen:(BOOL)open
{
_open = open;
[UIView beginAnimations:nil context:nil];
//如果展开该组,图片的箭头向下
//如果关闭该组,图片的箭头向右
self.imageView.transform = CGAffineTransformMakeRotation(_open?M_PI_2:0);
[UIView commitAnimations];
}
//重写按钮的方法,返回ImageView的位置和尺寸
- (CGRect)imageRectForContentRect:(CGRect)contentRect
{
return CGRectMake(0, 0, 25, contentRect.size.height);
}
//重写按钮的方法,返回Lable的位置和尺寸
- (CGRect)titleRectForContentRect:(CGRect)contentRect
{
return CGRectMake(30, 0, contentRect.size.width, contentRect.size.height);
}
@end

H:/0718/04_QQ好友列表_MJViewController.m
//  MJViewController.m
//  QQ好友列表
//  Created by mj on 13-7-17.
//  Copyright (c) 2013年 itcast. All rights reserved.
#import "MJViewController.h"
#import "Header.h"
@interface MJViewController ()
//字典数组,每个成员是一个字典,字典中有两对k--v
//group-->组名
//friends-->好友名组成的数组
@property (nonatomic, strong) NSArray *friends;
//字典,记住,每一组的,标题view
@property (nonatomic, strong) NSMutableDictionary *headers;
@end
@implementation MJViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//全路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"friends" ofType:@"plist"];
//字典数组
self.friends = [NSArray arrayWithContentsOfFile:path];
//初始化标题view组成的数组
self.headers = [NSMutableDictionary dictionary];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//快速创建Number对象时,变量要加小括号
//从成员数组中,取出对应section的标题view对象(实为自定义按钮)
Header *header = self.headers[@(section)];
//取出字典数组中的字典的好友数组的长度
NSArray *groupFriends = self.friends[section][@"friends"];
//如果是打开的,返回组内所有的行数,否则返回0行
int count = header.open ? groupFriends.count : 0;
return count;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//一共有多少组,只要返回字典数组的长度
return self.friends.count;
}
#pragma mark 创建每一行的Cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//标准代码 1:
static NSString *ID = @"cell";
//标准代码 2:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//标准代码 3:
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
//设置独一无二的数据,即好友名
NSArray *groupFriends = self.friends[indexPath.section][@"friends"];
cell.textLabel.text = groupFriends[indexPath.row];
return cell;
}
//代理方法,设置每一组的标题要显示的view,为自定义view
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
Header *btn = self.headers[@(section)];
if (!btn) {
//如果为空,创建HeadView并添加到成员数组中
btn = [Header buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor orangeColor];
btn.bounds = CGRectMake(0, 0, 320, 44);
//字典数组中的字典中的组名
NSString *group = self.friends[section][@"group"];
[btn setTitle:group forState:UIControlStateNormal];
//添加点击事件
[btn addTarget:self action:@selector(expandGroup:event:) forControlEvents:UIControlEventTouchUpInside];
//添加到成员数组中,其他方法中要用到
[self.headers setObject:btn forKey:@(section)];
}
return btn;
}
//响应按钮点击,展开或关闭该组,然后刷新数据
- (void)expandGroup:(Header *)header event:(UIEvent *)event
{
header.open = !header.open;
[self.tableView reloadData];
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ui ios
相关文章推荐