由一个自定义分享页面的需求想到的

一个自定义分享页面引起的思考

引言

相信绝大多数人都用过或者正使用着UMeng分享,可是每每UMeng提供的分享样式知足不了咱们的需求,例如咱们想额外填加一些按钮(复制连接、举报等)。
目前在作的这个项目一开始是使用的UMeng的分享样式,准备上架时因为审核要求,咱们须要加一个举报按钮,因此将"分享"按钮改成"更多"按钮,而后须要将举报放在分享的下面一行,而且查看别人的内容的时候须要显示举报,查看本身的内容的时候是不须要显示举报按钮的(谁还须要举报本身啊,哈哈),因此一个页面有两种状态;
同时由于有些平台不支持网页跳转登陆,因此咱们须要检查用户手机上面是否有安装该平台软件来显示页面,大体效果以下图:
图片描述git

当时需求只有微信、朋友圈、短信三个分享,为了赶进度,十分钟写完,当时的思路是:github

  1. 整个页面是个UIView,点击更多的时候进行初始化,而后add到window上面;微信

  2. 页面最底下放置一个UIView来实现出现和隐藏的时候透明度在0-0.3之间渐变,添加点击手势响应Remove操做;布局

  3. 下面的主要操做区域放置一个背景颜色为rgb都是240的UIView,根据传入的type计算总高度,中间放置一个颜色为rgb都是224的UILabel作分割线,垂直方向动画移入和移出页面;学习

  4. 三个分享按钮+举报按钮都使用UIButton,设置图片和标题的EdgeInsets属性为UI所需样式,举报按钮根据传入的type控制;动画

  5. 布局页面的时候判断手机是否安装有微信,没有的话只显示短信分享;ui

  6. 使用delegate与调用分享的Controller通讯;
    而后适配一下,这样写最直接,可是代码量大,纯代码设置每一个按钮的各项属性,还要根据用户是否安装某些软件来配置显示的按钮的坐标,扩展性不强,按钮很少还好,要是随着业务发展加入更多的分享平台,就很坑爹了。atom

固然有不少人使用的是UIActionSheet+UIScrollView实现,一样的道理,这样实现须要根据按钮是否显示来动态布局页面,需求变动就得从新布局,代码写着不爽。
下面说说个人思路。spa

正题

前几天群里有个哥们问我怎么在UMeng的界面上面加个复制按钮?显然不太好弄,因而本着负责任的态度,结合我这一年来学到的知识,从新梳理了一遍整个需求:code

  1. 每组按钮可能须要组头来放置文字提示;

  2. 每一个分享的按钮的图文样式须要方便随时调节;

  3. 根据用户手机是否安装某些平台来控制是否生成/显示某些按钮(全部按钮的坐标须要动态控制);

  4. 可能有两行可能有一行,也可能有不少行(后期可能会有其余需求);

  5. 一组按钮数量过多时,可能须要一行横向滑动显示,也可能须要纵向多行排布;

  6. 须要有显示和隐藏的动画效果;

  7. 最底部可能须要有个取消或者"X"按钮;

前面提到的几种方法,一旦更改需求,好比横向滑动改为纵向排布,代码写起来就会很痛苦,仍是那句话,代码写起来要本身以为爽才行,下面看看这些需求对应的解决方案:

  1. 组头、组尾、可能单行也可能多行的需求,最底部有个取消按钮,一个UITableView就能知足了,header、section、footer,根据dataSource能够很是方便地控制显示什么和显示与否;

  2. 按钮样式的调节和有可能横向排布或纵向排布,使用UICollectionView能够完美解决,UITableView的每一行里面放置一个UICollectionView,UICollectionViewCell就是按钮样式,调节样式改一个地方就行,排布方式setScrollDirection便可;

  3. 根据软件的安装状态来动态控制显示按钮,用到这两个控件,很显然咱们只须要控制数据源就行了;
    因此数据源的结构应该是这样的:

图片描述

值得一提的思路

因为目前在重构公司项目,因此文章结尾给出来的Demo中,分享按钮事件没有使用Delegate去操做Controller,而是采用的OC的runtime反射调用,根据方法名反过来构造SEL方法,而后判断传入actionVC是否响应该方法,响应就performSelector执行;
一样的道理,其实model同样能够有个方法属性,可是这样写的话构造数据源所在的类必须声明实现该方法,而且须要引用model文件,本人的想法是简化操做,不要写太多没有必要的代码。
看看代码:

对于Controller的引用

@property (nonatomic, weak) id actionVC;
A.使用Dictionary

1.构造数据源

NSMutableDictionary *wechatDic = [[NSMutableDictionary alloc]initWithDictionary:@{@"imageName":@"wechat_icon", @"title":@"微信", @"actionName":@"shareToWeChatAction"}];

2.Item点击交互

NSDictionary *dic = _dataSource[indexPath.row];
    NSString *actionStr = dic[@"actionName"];
    SEL action = NSSelectorFromString(actionStr);
     
    if ([self.actionVC respondsToSelector:action]) {
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"//去除警告
        [self.actionVC performSelector:action withObject:nil];
    }
B.使用model(使用的地方须要引入头文件和实现响应selector构造的方法)

1.构造数据源

M_Share *wechatModel = [[M_Share alloc]init];
        wechatModel.title = @"微信";
        wechatModel.imageName = @"wechat_icon";
        wechatModel.selector = @selector(shareToWeChatAction);//所在类须要声明/实现该方法
        [sectionOne addObject:wechatModel];
    
        [_dataSource addObject:sectionOne];

2.Item点击交互

M_Share *shareModel = _dataSource[indexPath.row];
    if ([self.actionVC respondsToSelector:shareModel.selector]) {
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"//去除警告
        [self.actionVC performSelector:shareModel.selector withObject:nil];
    }

值得一提的是,这里从逻辑上来说没有任何问题,可是系统始终会报一个警告,看了一下前辈们的解决办法是加了一行代码去除leaks警告:

#pragma clang diagnostic ignored "-Warc-performSelector-leaks"

因此顺便了解一一下去除项目中没必要要的警告的方法,好比方法的废弃警告,找到项目Target中的Build Phases下的Compile Sources,将里面想要过滤警告的item后面编辑写入-w后保存该文件里面的警告就过滤掉了。

最后

抽时间整理成Demo出来放到github上面了:UMengDiyShareDemo
感谢阅读,但愿本文对你有帮助!

本人坐标杭州,后续我会陆续把工做中遇到的问题及解决方案分享出来,互相交流学习,本人QQ:815187811,欢迎结交[笑脸].

相关文章
相关标签/搜索