您的位置:首页 > 移动开发 > IOS开发

IOS-Excel表格制作

2015-09-20 15:51 489 查看
仿照UITableView、UITableViewDataSource和UITableViewDelegate,支持自定义每一个小框内的视图。

视图:HJExcelView.h

//
//  HJExcelView.h
//  mehr 工作表
//
//  Created by 阳君 on 14-6-9.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "HJExcelViewCell.h"

@protocol HJExcelViewViewDelegate, HJExcelViewViewDataSource;

@interface HJExcelView : UIView <HJExcelViewViewCellDelegate>

/** 数据源代理*/
@property (nonatomic, assign) id <HJExcelViewViewDataSource> dataSource;
/** 界面代理*/
@property (nonatomic, assign) id <HJExcelViewViewDelegate>   delegate;

/** 边框颜色*/
@property (nonatomic, strong) UIColor *borderColor;
/** 边框大小(>0才有效果,默认为1.0)*/
@property (nonatomic)         CGFloat borderWidth;

/** cell到边框的间隙*/
@property (nonatomic) CGFloat  cellToBordeSpace;

/**
*  刷新全部数据
*
*  @return void
*/
- (void)reloadData;

@end

@protocol HJExcelViewViewDelegate <NSObject>

@optional

/**
*  点击cell
*
*  @param excelView HJExcelView
*  @param indexPath 位置
*
*  @return void
*/
- (void)excelView:(HJExcelView *)excelView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

/**
*  cell的行高,默认40,包含了borderWidth/2
*
*  @param excelView HJExcelView
*  @param row       行
*
*  @return CGFloat
*/
- (CGFloat)excelView:(HJExcelView *)excelView heightForRow:(NSInteger)row;

/**
*  cell的列宽,默认:60,包含了borderWidth/2
*
*  @param excelView HJExcelView
*  @param section   列
*
*  @return CGFloat
*/
- (CGFloat)excelView:(HJExcelView *)excelView widthInSection:(NSInteger)section;

@end

@protocol HJExcelViewViewDataSource <NSObject>

@required

/**
*  有多少行数据
*
*  @param excelView HJExcelView
*
*  @return NSInteger
*/
- (NSInteger)numberOfRowsInExcelView:(HJExcelView *)excelView;

/**
*  有多少列数据
*
*  @param excelView HJExcelView
*
*  @return NSInteger
*/
- (NSInteger)numberOfSectionsInExcelView:(HJExcelView *)excelView;

/**
*  生成cell
*
*  @param cell      已初始化的HJExcelViewCell
*  @param indexPath 位置
*
*  @return HJExcelViewCell
*/
- (HJExcelViewCell *)excelViewCell:(HJExcelViewCell *)cell cellForRowAtIndexPath:(NSIndexPath *)indexPath;

@end


实现:HJExcelView.m

//
//  HJExcelView.m
//  mehr
//
//  Created by 阳君 on 14-6-9.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import "HJExcelView.h"
#import "HJExcelViewPoint.h"

@interface HJExcelView ()
{
@private
/** 画版*/
UIView *_boardView;
/** 画布*/
UIView *_contentView;

/** 行列坐标点*/
NSMutableArray *_cellRowArray, *_cellSectionArray;
}

@end

@implementation HJExcelView

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_boardView = [[UIView alloc] initWithFrame:self.frame];
[self addSubview:_boardView];
// 手势操作
// 移动
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];
[_boardView addGestureRecognizer:panRecognizer];
}
return self;
}

#pragma mark  - 图形移动
- (void)handlePan:(UIPanGestureRecognizer *)recognizer
{
// 取点
CGPoint translatedPoint = [recognizer translationInView:_boardView];
// 计算
CGFloat x = recognizer.view.center.x + translatedPoint.x;
CGFloat y = recognizer.view.center.y + translatedPoint.y;

// 移动范围
CGFloat contentWidth  = _contentView.frame.size.width / 2;
CGFloat contentHeight = _contentView.frame.size.height / 2;
CGFloat mainWidth  = self.frame.size.width / 2;
CGFloat mainHeight = self.frame.size.height / 2;

// 上移动
if (translatedPoint.y < 0)
{
// 画布高度低于屏幕高度
if (contentHeight < mainHeight)
{
// 禁止上边框离开屏幕边缘
y = y > contentHeight ? y : contentHeight;
}
}
// 下移动
else
{
// 画布高度低于屏幕高度
if (contentHeight < mainHeight)
{
// 禁止下边框离开屏幕边缘
y = y < self.frame.size.height - contentHeight ? y : self.frame.size.height - contentHeight;
}
}

// 左移动
if (translatedPoint.x < 0)
{
// 画布高度低于屏幕高度
if (contentWidth < mainWidth)
{
// 禁止左边框离开屏幕边缘
x = x > contentWidth ? x : contentWidth;
}

}
// 右移动
else
{
if (contentWidth < mainWidth)
{
// 禁止右边框离开屏幕边缘
x = x < self.frame.size.width - contentWidth ? x : self.frame.size.width - contentWidth;
}

}

// 移动
recognizer.view.center = CGPointMake(x, y);

// 回归中心点
[recognizer setTranslation:CGPointMake(0, 0) inView:_boardView];
}

#pragma mark - 获得边框颜色
- (UIColor *)borderColor
{
// 是否设置为默认
_borderColor = _borderColor ? _borderColor : [UIColor colorWithWhite:0.821 alpha:1.000];

return _borderColor;
}

#pragma mark 获得边框大小
- (CGFloat)borderWidth
{
// 是否设置为默认
_borderWidth = _borderWidth > 0 ? _borderWidth : 1.0;

return _borderWidth;
}

#pragma mark - 刷新数据
- (void)reloadData
{
// 必须实现的代理方法
if ([self.dataSource respondsToSelector:@selector(numberOfSectionsInExcelView:)] && [self.dataSource respondsToSelector:@selector(numberOfRowsInExcelView:)] && [self.dataSource respondsToSelector:@selector(excelViewCell:cellForRowAtIndexPath:)])
{
// 清空上次的画布
[_contentView removeFromSuperview];
_contentView = [[UIView alloc] initWithFrame:self.frame];
[_boardView addSubview:_contentView];

// 行
NSInteger rows = [self.dataSource numberOfRowsInExcelView:self];
// 列
NSInteger sections = [self.dataSource numberOfSectionsInExcelView:self];

CGFloat borderWidth = self.borderWidth / 2;

// cell的大小位置
CGRect frame = CGRectMake(borderWidth + self.cellToBordeSpace * 2, borderWidth + self.cellToBordeSpace * 2, 0, 0);

_cellRowArray     = [NSMutableArray array];
_cellSectionArray = [NSMutableArray array];

NSInteger sumHeight = 0, sumWidth = 0;

// 行操作
for (int row = 0; row < rows; row ++ )
{
// 行高
frame.size.height = [self heightForRow:row];
// 保存行点
HJExcelViewPoint *point = [HJExcelViewPoint excelViewPointWithX:frame.origin.x y:frame.origin.y];
[_cellRowArray addObject:point];

// 列操作
for (int section = 0; section < sections; section ++ )
{
// 列宽
frame.size.width = [self widthInSection:section];
// 位置
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];

[self addExcelViewCellWithIndexPath:indexPath frame:frame];

if (row == 0)
{
// 保存列点
HJExcelViewPoint *point = [HJExcelViewPoint excelViewPointWithX:frame.origin.x y:frame.origin.y];
[_cellSectionArray addObject:point];
}
// 下一列位置
frame.origin.x += frame.size.width + self.cellToBordeSpace * 2;
}

// 下一行第0个位置
frame.origin.y += frame.size.height + self.cellToBordeSpace * 2;
// 当出现最后一个点时,保存长度
if (row == rows - 1)
{
sumHeight = frame.origin.y;
sumWidth = frame.origin.x;
}
frame.origin.x = self.borderWidth / 2 + self.cellToBordeSpace * 2;
}

// 画边框
HJExcelViewPoint *point;
UIView *line;

sumHeight -= self.cellToBordeSpace * 2;
sumWidth  -= self.cellToBordeSpace * 2;

// 画行
for (int row = 0; row < rows; row ++ )
{
point = [_cellRowArray objectAtIndex:row];
line = [[UIView alloc] initWithFrame:CGRectMake(point.x - borderWidth - self.cellToBordeSpace, point.y - borderWidth - self.cellToBordeSpace, sumWidth, self.borderWidth)];
line.backgroundColor = self.borderColor;
[_contentView addSubview:line];
}

// 画最后一行
line = [[UIView alloc] initWithFrame:CGRectMake(point.x - borderWidth - self.cellToBordeSpace, sumHeight - borderWidth + self.cellToBordeSpace, sumWidth, self.borderWidth)];
line.backgroundColor = self.borderColor;
[_contentView addSubview:line];

// 画列
for (int section = 0; section < sections; section ++ )
{
point = [_cellSectionArray objectAtIndex:section];
line = [[UIView alloc] initWithFrame:CGRectMake(point.x - borderWidth - self.cellToBordeSpace, point.y - borderWidth - self.cellToBordeSpace, self.borderWidth, sumHeight)];
line.backgroundColor = self.borderColor;
[_contentView addSubview:line];
}
// 画最后一列
line = [[UIView alloc] initWithFrame:CGRectMake(sumWidth - borderWidth + self.cellToBordeSpace, point.y - borderWidth - self.cellToBordeSpace, self.borderWidth, sumHeight)];
line.backgroundColor = self.borderColor;
[_contentView addSubview:line];

// 调整画板
frame = _boardView.frame;
frame.origin.x = - self.frame.size.width / 2;
frame.origin.y = - self.frame.size.height / 2;
frame.size.height = self.borderWidth + self.cellToBordeSpace + sumHeight + self.frame.size.height;
frame.size.width  = self.borderWidth + self.cellToBordeSpace + sumWidth + self.frame.size.width;
_boardView.frame = frame;

// 调整画布
frame = _contentView.frame;
frame.origin.x = self.frame.size.width / 2;
frame.origin.y = self.frame.size.height / 2;
frame.size.height = self.borderWidth + self.cellToBordeSpace + sumHeight;
frame.size.width  = self.borderWidth + self.cellToBordeSpace + sumWidth;
_contentView.frame = frame;
}

}

#pragma mark - cell的行高
- (CGFloat)heightForRow:(NSInteger)row
{
if ([self.delegate respondsToSelector:@selector(excelView:heightForRow:)])
{
return [self.delegate excelView:self heightForRow:row];
}
else
{
return 44;
}
}

#pragma mark cell的列宽
- (CGFloat)widthInSection:(NSInteger)section
{
if ([self.delegate respondsToSelector:@selector(excelView:heightForRow:)])
{
return [self.delegate excelView:self widthInSection:section];
}
else
{
return 70;
}
}

#pragma mark - 视图增加cell
- (void)addExcelViewCellWithIndexPath:(NSIndexPath *)indexPath frame:(CGRect)frame
{
// 初始化cell
HJExcelViewCell *cell = [[HJExcelViewCell alloc] initWithFrame:frame];
// 通知主视图向cell中添加内容
cell = [self.dataSource excelViewCell:cell cellForRowAtIndexPath:indexPath];
// 调整大小
cell.frame = frame;
// 绑定位置
cell.indexPath = indexPath;
// 代理
cell.excelViewDelegate = self;
//  加到页面中
[_contentView addSubview:cell];

}

#pragma mark - HJExcelViewViewCellDelegate
- (void)excelViewCell:(HJExcelViewCell *)excelViewCell didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// 判断是否开启可点击和实现回调
if (excelViewCell.selected && [self.delegate respondsToSelector:@selector(excelView:didSelectRowAtIndexPath:)])
{
// 通知主视图,被点击
[self.delegate excelView:self didSelectRowAtIndexPath:excelViewCell.indexPath];
}
}

@end


每一个cell:HJExcelViewCell.h

//
//  HJExcelViewCell.h
//  mehr
//
//  Created by 阳君 on 14-6-10.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import <UIKit/UIKit.h>

@protocol HJExcelViewViewCellDelegate;

@interface HJExcelViewCell : UIView

/** 是否可选,默认no关闭*/
@property (nonatomic) BOOL selected;

//以下属性,和HJExcelView通信,外部调用无用
/** 位置*/
@property (nonatomic, strong) NSIndexPath *indexPath;
@property (nonatomic, assign) id <HJExcelViewViewCellDelegate> excelViewDelegate;

@end

// 和HJExcelView通信,外部不用实现
@protocol HJExcelViewViewCellDelegate <NSObject>

@optional

/**
*  点击cell
*
*  @param excelViewCell HJExcelViewCell
*  @param indexPath 位置
*
*  @return void
*/
- (void)excelViewCell:(HJExcelViewCell *)excelViewCell didSelectRowAtIndexPath:(NSIndexPath *)indexPath;

@end


实现:HJExcelViewCell.m

//
//  HJExcelViewCell.m
//  mehr
//
//  Created by 阳君 on 14-6-10.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import "HJExcelViewCell.h"

@implementation HJExcelViewCell

- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self.excelViewDelegate excelViewCell:self didSelectRowAtIndexPath:self.indexPath];
}

@end


位置点:HJExcelViewPoint.h 

//
//  HJExcelViewPoint.h
//  mehr
//
//  Created by 阳君 on 14-6-10.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface HJExcelViewPoint : NSObject

/** 坐标x*/
@property (nonatomic) CGFloat x;
/** 坐标y*/
@property (nonatomic) CGFloat y;

/**
*  生成坐标
*
*  @param x x
*  @param y y
*
*  @return HJExcelViewPoint
*/
+ (id)excelViewPointWithX:(CGFloat)x y:(CGFloat)y;

@end


实现:HJExcelViewPoint.m 

//
//  HJExcelViewPoint.m
//  mehr
//
//  Created by 阳君 on 14-6-10.
//  Copyright (c) 2014年 Hjsj. All rights reserved.
//

#import "HJExcelViewPoint.h"

@implementation HJExcelViewPoint

+ (id)excelViewPointWithX:(CGFloat)x y:(CGFloat)y
{
HJExcelViewPoint *point = [[[self class] alloc] init];

point.x = x;
point.y = y;

return point;
}

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: