本帖最后由 Sian 于 2016-3-13 17:36 编辑
1、先上图,有图好说话
2、设置思路
2.1、我希望这是一个View,并非控制器,节省开支;
2.2、 这个View包含一个背景,一个面板,若干个按钮或标签;
2.3、我希望实现的功能是视图展示+事件响应;
2.4、希望无偶合性,并且一行代码搞定(能一行代码搞定的必定包含block);
2.5、这若干个按钮最好是外面传进来,要不我怎么知道需要什么样的按钮?传一组图片?那文字呢?再传一组文字?如何对应?
2.6、我希望开始调用的时候只要传按钮给你,结束后告诉我用户点了哪个按钮,其他的我都不想管(高度无偶封装),呵呵!
2.7、调用时还最好是类方法,我不喜欢alloc;
2.8、例如:+ (instancetype)sheetWithItems:(NSArray<__kindof UIButton *> *)items actionWithBlock:(SAActionSheetBlock)block
3、基本调用[Objective-C] 纯文本查看 复制代码 //
// ViewController.m
// Test
//
// Created by 余西安 on 16/3/11.
// Copyright © 2016年 Sian. All rights reserved.
//
#import "ViewController.h"
#import "SAActionSheet.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
/// 弹出分享面板
- (IBAction)action:(UIButton *)sender
{
[SAActionSheet sheetWithItems:[self shareItems] actionWithBlock:^(UIButton *item, NSInteger index) {
switch (index) {
case 1: [self show:@"微信好友"]; break;
case 2: [self show:@"朋友圈"]; break;
case 3: [self show:@"微信收藏"]; break;
case 4: [self show:@"QQ好友"]; break;
case 5: [self show:@"QQ空间"]; break;
default: break;
}
}];
}
/// 创建按钮数组
- (NSArray *)shareItems
{
UIImage *image1 = [UIImage imageNamed:@"Action_Share.png"];
UIImage *image2 = [UIImage imageNamed:@"Action_Moments.png"];
UIImage *image3 = [UIImage imageNamed:@"Action_MyFavAdd.png"];
UIImage *image4 = [UIImage imageNamed:@"Action_QQ.png"];
UIImage *image5 = [UIImage imageNamed:@"Action_qzone.png"];
UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeSystem];
UIButton *button4 = [UIButton buttonWithType:UIButtonTypeSystem];
UIButton *button5 = [UIButton buttonWithType:UIButtonTypeSystem];
[button1 setBackgroundImage:image1 forState:UIControlStateNormal];
[button2 setBackgroundImage:image2 forState:UIControlStateNormal];
[button3 setBackgroundImage:image3 forState:UIControlStateNormal];
[button4 setBackgroundImage:image4 forState:UIControlStateNormal];
[button5 setBackgroundImage:image5 forState:UIControlStateNormal];
[button1 setTitle:@"微信好友" forState:UIControlStateNormal];
[button2 setTitle:@"朋友圈" forState:UIControlStateNormal];
[button3 setTitle:@"微信收藏" forState:UIControlStateNormal];
[button4 setTitle:@"QQ好友" forState:UIControlStateNormal];
[button5 setTitle:@"QQ空间" forState:UIControlStateNormal];
return @[button1, button2, button3, button4, button5];
}
// 附属方法,显示结果
- (void)show:(NSString *)string
{
[[[UIAlertView alloc] initWithTitle:nil message:string delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil] show];
}
@end
4、代码实现[Objective-C] 纯文本查看 复制代码 //
// SAActionSheet.m
// fisher
//
// Created by 余西安 on 16/3/10.
// Copyright © 2016年 Sian. All rights reserved.
//
#define kSAActionSheetItemColumns 3 // 每行按钮数(纵列数)
#define kSAActionSheetItemWidth 60 // 单个按钮长宽
#define kSAActionSheetItemSpace 25 // 按钮上下之间间隔
#define kSAActionSheetLabelHeight 25 // 按钮标签文字高度
#define kSAActionSheetCancelHeight 50 // 取消按钮高度
#import "SAActionSheet.h"
@interface SAActionSheet ()
@property (nonatomic, strong) UIView *baseView; // 按钮基础板
@property (nonatomic, strong) NSArray *items; // 按钮数组
@property (nonatomic, strong) NSArray *labels; // 按钮标签
@property (nonatomic, strong) UIButton *cancel; // 取消按钮
@property (nonatomic, copy) SAActionSheetBlock block; // 完成Block
@end
@implementation SAActionSheet
+ (instancetype)sheetWithItems:(NSArray<__kindof UIButton *> *)items actionWithBlock:(SAActionSheetBlock)block
{
SAActionSheet *sheet = [[self alloc] initWithItems:items actionWithBlock:block];
return [sheet show];
}
- (instancetype)initWithItems:(NSArray<__kindof UIButton *> *)items actionWithBlock:(SAActionSheetBlock)block
{
if (self = [super init]){
// 1、接收变量
self.block = block;
self.items = items;
// 2、创建基础面板视图(动画升上来的那个白色面板,用来放分享按钮、标签等)
self.baseView = [[UIView alloc] init];
self.baseView.backgroundColor = [UIColor colorWithWhite:0.9 alpha:0.9];
[self addSubview:self.baseView];
// 3、创建分享按钮及对应标签
NSMutableArray *labelArray = [NSMutableArray array];
for (int i = 0; i < items.count; i++) {
// 3.1、遍历传进来的按钮数组,将每个按钮添加到baseView上,并序号添加tag标记
UIButton *button = [items objectAtIndex:i];
[button setTag:i + 1];
[self.baseView addSubview:button];
// 3.2、创建按钮标签,取出标签后将按钮上的文字删除掉,避免重复
UILabel *label = [[UILabel alloc] init];
label.font = [UIFont systemFontOfSize:11];
label.textAlignment = NSTextAlignmentCenter;
label.text = [button titleForState:UIControlStateNormal];
[labelArray addObject:label];
[self.baseView addSubview:label];
// 3.3、添加按钮事件统一处理方法
[button setTitle:nil forState:UIControlStateNormal];
[button addTarget:self action:@selector(buttonEven:) forControlEvents:UIControlEventTouchUpInside];
}
self.labels = labelArray;
// 4、取消按钮并绑定相关事件
self.cancel = [UIButton buttonWithType:UIButtonTypeSystem];
[self.cancel addTarget:self action:@selector(hidden) forControlEvents:UIControlEventTouchUpInside];
[self.cancel setBackgroundColor:[UIColor whiteColor]];
[self.cancel setTitle:@"取消" forState:UIControlStateNormal];
[self.cancel.titleLabel setFont:[UIFont systemFontOfSize:20]];
[self.baseView addSubview:self.cancel];
// 5、点击空白区域响应取消事件
[self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hidden)]];
}
return self;
}
/// 视图调整
- (void)layoutSubviews
{
[super layoutSubviews];
// SAActionSheet Frame:背景大小
self.frame = [[UIScreen mainScreen] bounds];
/* BaseView Frame:基础视图尺寸
rows: 为按钮总行数
h: baseView视图的高 = (上下间隔高度 + 按钮高度 + 标签高度) * 行数 + 上下间隔高度 + 取消按钮高度
w: baseView视图的宽 = 屏幕宽度
*/
NSInteger rows = (self.items.count - 1) / kSAActionSheetItemColumns + 1;
CGFloat h = rows * (kSAActionSheetItemWidth + kSAActionSheetItemSpace + kSAActionSheetLabelHeight) + kSAActionSheetItemSpace + kSAActionSheetCancelHeight;
CGFloat w = self.bounds.size.width;
self.baseView.bounds = CGRectMake(0, 0, self.bounds.size.width, h);
/* Items Frame:按钮尺寸
bw: 按钮宽度
bh: 按钮高度
sp: 按钮间隔 = (总宽度 - 按钮个数 * 按钮宽度)/ 间隔数
*/
CGFloat bw = kSAActionSheetItemWidth;
CGFloat bh = kSAActionSheetItemWidth;
CGFloat sp = (w - bw * kSAActionSheetItemColumns) / (kSAActionSheetItemColumns + 1);
for (UIButton *button in self.items) {
NSInteger index = button.tag; // 按钮序号
NSInteger row = (index - 1) / kSAActionSheetItemColumns + 1; // 行序号
NSInteger col = (index - 1) % kSAActionSheetItemColumns + 1; // 列序号
// 按钮x值、y值
CGFloat x = (col - 1) * bw + col * sp;
CGFloat y = (row - 1) * (bh + kSAActionSheetLabelHeight) + row * kSAActionSheetItemSpace;
button.frame = CGRectMake(x, y, bw, bh);
// 在按钮下方设置相对应的标签,宽度与按钮相同,高度为预设定值
UILabel *label = [self.labels objectAtIndex:index - 1];
label.frame = CGRectMake(x, y + bh, bw, kSAActionSheetLabelHeight);
}
// 取消按钮在最下方,高度为50
self.cancel.frame = CGRectMake(0, h - 50, w, kSAActionSheetCancelHeight);
}
/// 显示视图(弹出动画)
- (SAActionSheet *)show
{
// 1、调整视图大小,添加到当前Windows窗口
[self layoutSubviews];
[[[[UIApplication sharedApplication] delegate] window] addSubview:self];
// 2、将基础视图调整到屏幕最下方、背景设置透明
CGFloat height = self.bounds.size.height;
CGFloat w = self.baseView.bounds.size.width;
CGFloat h = self.baseView.bounds.size.height;
self.backgroundColor = [UIColor clearColor];
self.baseView.center = CGPointMake(w * 0.5, height + h * 0.5);
// 3、执行自下至上的推出及背景变半透明黑的动画
[UIView animateWithDuration:0.25 animations:^{
self.baseView.center = CGPointMake(w * 0.5, height - h * 0.5);
self.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
}];
return self;
}
/// 隐藏视图(退出释放)
- (void)hidden
{
// 按键视图块整体下移至超出屏幕动画,背景变透明,动画结束后将视图从窗口移除
CGFloat height = self.bounds.size.height;
CGFloat w = self.baseView.bounds.size.width;
CGFloat h = self.baseView.bounds.size.height;
[UIView animateWithDuration:0.35 animations:^{
self.baseView.center = CGPointMake(w * 0.5, height + h * 0.5);
self.backgroundColor = [UIColor clearColor];
} completion:^(BOOL finished) {
[self removeFromSuperview];
}];
}
/// 按钮事件转交给Block处理
- (void)buttonEven:(UIButton *)button
{
// 将事件及触发事件的按钮序号转交出去,并取消视图
if (self.block) self.block(button, button.tag);
[self hidden];
}
@end
5、Demo下载: |