Sian 发表于 2016-3-11 17:34:26

自定义UIActionSheet实现分享功能,一行代码搞定!

本帖最后由 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、基本调用//
//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
{
    ;
}
/// 弹出分享面板
- (IBAction)action:(UIButton *)sender
{
    actionWithBlock:^(UIButton *item, NSInteger index) {
      switch (index) {
            case 1: ; break;
            case 2: ; break;
            case 3: ; break;
            case 4: ; break;
            case 5: ; break;
            default: break;
      }
    }];
}
/// 创建按钮数组
- (NSArray *)shareItems
{
    UIImage *image1 = ;
    UIImage *image2 = ;
    UIImage *image3 = ;
    UIImage *image4 = ;
    UIImage *image5 = ;
    UIButton *button1 = ;
    UIButton *button2 = ;
    UIButton *button3 = ;
    UIButton *button4 = ;
    UIButton *button5 = ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    ;
    return @;
}
// 附属方法,显示结果
- (void)show:(NSString *)string
{
    [[ initWithTitle:nil message:string delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil] show];
}
@end
4、代码实现//
//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) SAActionSheetBlockblock;// 完成Block

@end

@implementation SAActionSheet

+ (instancetype)sheetWithItems:(NSArray<__kindof UIButton *> *)items actionWithBlock:(SAActionSheetBlock)block
{
    SAActionSheet *sheet = [ initWithItems:items actionWithBlock:block];
    return ;
}

- (instancetype)initWithItems:(NSArray<__kindof UIButton *> *)items actionWithBlock:(SAActionSheetBlock)block
{
    if (self = ){
      // 1、接收变量
      self.block = block;
      self.items = items;
      // 2、创建基础面板视图(动画升上来的那个白色面板,用来放分享按钮、标签等)
      self.baseView = [ init];
      self.baseView.backgroundColor = ;
      ;
      // 3、创建分享按钮及对应标签
      NSMutableArray *labelArray = ;
      for (int i = 0; i < items.count; i++) {
            // 3.1、遍历传进来的按钮数组,将每个按钮添加到baseView上,并序号添加tag标记
            UIButton *button = ;
            ;
            ;
            // 3.2、创建按钮标签,取出标签后将按钮上的文字删除掉,避免重复
            UILabel *label = [ init];
            label.font = ;
            label.textAlignment = NSTextAlignmentCenter;
            label.text = ;
            ;
            ;
            // 3.3、添加按钮事件统一处理方法
            ;
            ;
      }
      self.labels = labelArray;
      // 4、取消按钮并绑定相关事件
      self.cancel = ;
      ;
      ];
      ;
      ];
      ;
      // 5、点击空白区域响应取消事件
       initWithTarget:self action:@selector(hidden)]];
    }
    return self;
}
/// 视图调整
- (void)layoutSubviews
{
    ;
    // SAActionSheet Frame:背景大小
    self.frame = [ 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 = ;
      label.frame = CGRectMake(x, y + bh, bw, kSAActionSheetLabelHeight);
    }
    // 取消按钮在最下方,高度为50
    self.cancel.frame = CGRectMake(0, h - 50, w, kSAActionSheetCancelHeight);
}

/// 显示视图(弹出动画)
- (SAActionSheet *)show
{
    // 1、调整视图大小,添加到当前Windows窗口
    ;
    [[[ 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 = ;
    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 = ;
    }];
    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 = ;
    } completion:^(BOOL finished) {
      ;
    }];
}

/// 按钮事件转交给Block处理
- (void)buttonEven:(UIButton *)button
{
    // 将事件及触发事件的按钮序号转交出去,并取消视图
    if (self.block) self.block(button, button.tag);
    ;
}
@end
5、Demo下载:**** Hidden Message *****
页: [1]
查看完整版本: 自定义UIActionSheet实现分享功能,一行代码搞定!