健康管理 | 六只超赞的提升功效启发创意白噪声网站

稍许自由撰稿人或者商务职员为何爱去咖啡厅举行写作或工作吗?为啥小音乐家喜欢去大自然中绘也?因为不论是咖啡馆或者大自然中,周围会存在一定之白噪声,白噪声充满整个人类耳朵可以听见的震动频率,探究注脚,白噪声可以激励大脑举办抽象思维,暴发灵感,集中注意力,提升效用,可以扶持一个人放松或睡觉。当您读书做工作平时,听在咖啡店的总人口语声、轻微小雨声、轰轰雷雨声、火车行驶声、火焰点火呲呲声、微风拂落叶声、小溪水流声、海浪轻拍声、虫鸣鸟叫声、电视机没有节目滋滋声等,让丁发种植近的发,明天被我们推荐的4单网站还颇棒,我们赶紧感受下吧。

前言

图片 1

UICollectionView进阶之路平

达到等同篇介绍了UICollectionView的底蕴及极品封装,我们扔了UICollectionView繁琐的数据源代理,即使采纳起来方便了许多,但要生只英雄的想法,不写数据源代理,把UICollectionView的咬合分为一个个小插件(widget)拼接而变成。
可以?
………..
不可以?
………..
自然好啊,(哈哈,有趣味之校友及自家一块来打探实现情势吧)

1.Coffitivity

UICollectionView插件化(widget)组成

  • XWWidget,UICollectionView插件化的构件,负责做每个插件的多少
  • UICollectionView+XWWidget,UICollectionView和XWWidget的一向互动,负责管理整合多单XWWidget,UICollectionView的数据源代理
![](https://upload-images.jianshu.io/upload_images/2546201-6d9a070e2184a61a.png)

UICollectionView-XWWidget.png

进网站会自动播放咖啡馆背景的丁语声,给人平等栽上到星巴克(Buck)喝着美味的咖啡,在中间举办写作之近乎感觉。除了网页端他,还出产AndroidIOS免费客户端软件,适合随时随地使用,假如急需选拔重新多背景音乐可以挑选升级至付费用户。

XWWidget

  • XWWidget结构

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef enum : NSUInteger {
    XWWidgetStateDefault,      // 正常状态
    XWWidgetStateRequsting,   // 正在请求刷新状态
    XWWidgetStateRequestFail,  // 请求刷新失败
    XWWidgetStateRequestSuccess,// 请求刷新成功
    XWWidgetStateRequestNoMoreData// 请求刷新无更多数据状态
}   XWWidgetState;

@interface XWWidget : NSObject

@property (nonatomic , weak , readonly,nullable)  UICollectionView *collectionView;

@property (nonatomic , assign ,readonly)  XWWidgetState state; // 当前请求状态

/**
 *  一个secion时候设置
 */
@property (nonatomic , strong , nullable) NSObject * headerData; // 头部视图数据
@property (nonatomic , strong , nullable) NSMutableArray * cellDataList; // cell视图模型数组
@property (nonatomic , strong , nullable) NSObject * footerData;       // 尾部视图模型
@property (nonatomic , copy , nullable)   Class decorationViewClass; // 修视背景图类

/**
 *  多个secion时候设置
 */
@property(nonatomic , strong , nullable) NSMutableArray * headerDataList;
@property(nonatomic , strong , nullable) NSMutableArray< NSMutableArray * > * multiCellDataList;
@property(nonatomic , strong , nullable) NSMutableArray * footerDataList;
@property(nonatomic , strong , nullable) NSMutableArray<Class> * decorationViewClassList;

/**
 刷新部件
 */
-(void) xw_reloadWidget;

/**
 头部刷新请求回调 可重写
 注:如果重写了该方法不要调用[super qw_requestUpRefresh]
 */
- (void)requestHeaderRefresh;

/**
 尾部刷新请求回调 可重写
 注:如果重写了该方法不要调用[super qw_requestDropRefresh]
 */
- (void)requestFooterRefresh;

/**
 刷新请求完成调用
 @param state 请求结果
 */

-(void)requestFinishWithState:(XWWidgetState)state;

/**
 刷新请求完成 成功 调用
 */

-(void)requestSuccess;

/**
 刷新请求完成 失败 调用
 */
-(void)requestFail;

/**
 刷新请求完成 没有更多数据 (也属于成功) 调用
 */
-(void)requestNoMoreData;

@end

代码注释得分外精晓,每一个XWWidget插件扶助单个section和两只section,为理解耦,每个插件可以独立实现网络要,你一旦做的是将页面合理的分成几单独立的widget,这样您即使完了一半了。

图片 2

UICollectionView+XWWidget

  • UICollectionView+XWWidget结构

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

@interface UICollectionView (XWWidget)

/**
 刷新所有部件
 */
-(void) xw_reloadWidgets;

/**
 刷新部件
 */
-(void) xw_reloadWidget:(XWWidget *)widget;

/**
 添加一个部件
 */
- (void)xw_addWidget:(XWWidget *) widget;

/**
 插入一个部件
 */
- (void)xw_insertWidget:(XWWidget *) widget atIndex:(NSUInteger)index ;

/**
 删除一个部件
 */
- (void)xw_removeWidget:(XWWidget *) widget;

/**
 删除所有部件
 */
- (void)xw_removeAllWidgets;

/**
 头部刷新
 */
-(void)xw_collectionViewHeaderRefresh;

/**
 加载更多
 */
-(void)xw_collectionViewFooterRefresh;

/**
 加载结束
 */
-(void)xw_endRefreshingWithWidgetState:(XWWidgetState)state;

@end

#import "UICollectionView+XWWidget.h"
#import <objc/runtime.h>
#import "UICollectionView+XW.h"

@interface UICollectionView ()

@property (nonatomic, strong)  NSMutableArray * xw_headerDataList;
@property (nonatomic, strong)  NSMutableArray * xw_cellDataList;
@property (nonatomic, strong)  NSMutableArray * xw_footerDataList;
@property (nonatomic , strong) NSMutableArray * xw_decorationViewClassList;
@property (nonatomic , strong) NSMutableArray * xw_oldSectionList;

@property(nonatomic, strong) NSMutableArray *xw_widgets;

@end

@implementation UICollectionView (XWWidget)


#pragma mark - XWCollectionViewDataSource

- (NSMutableArray *)headerDataListWithCollectionView:(UICollectionView *) collectionView{
    return self.xw_headerDataList;
}

- (NSMutableArray *)cellDataListWithCollectionView:(UICollectionView *) collectionView{
    return self.xw_cellDataList;
}

- (NSMutableArray *)footerDataListWithCollectionView:(UICollectionView *) collectionView{
    return self.xw_footerDataList;
}

- (NSMutableArray<Class> *)decorationViewClassListWithCollectionView:(UICollectionView *)collectionView{
    return self.xw_decorationViewClassList;
}

#pragma mark - public

-(void) xw_reloadWidgets{

    [self.xw_headerDataList removeAllObjects];
    [self.xw_cellDataList removeAllObjects];
    [self.xw_footerDataList removeAllObjects];
    [self.xw_decorationViewClassList removeAllObjects];
    for (XWWidget * widget in self.xw_widgets) {
        [self.xw_headerDataList addObjectsFromArray:widget.headerDataList];
        [self.xw_cellDataList addObjectsFromArray:widget.multiCellDataList];
        [self.xw_footerDataList addObjectsFromArray:widget.footerDataList];
        [self.xw_decorationViewClassList addObjectsFromArray:widget.decorationViewClassList];
    }

    self.xw_dataSource = (id<XWCollectionViewDataSource>)self;
    dispatch_async(dispatch_get_main_queue(),^{
        [UIView performWithoutAnimation:^{
            //刷新界面
            [CATransaction begin];
            [CATransaction setDisableActions:YES];
            [self reloadData];
            [CATransaction commit];
        }];

    });

}

-(void) xw_reloadWidget:(XWWidget *)widget{

    [self xw_reloadWidgets];
}


- (void)xw_addWidget:(XWWidget *) widget{
    NSUInteger index = self.xw_widgets.count;
    [self xw_insertWidget:widget atIndex:index];
}

- (void)xw_insertWidget:(XWWidget *) widget atIndex:(NSUInteger)index {
    if ([widget isKindOfClass:[XWWidget class]] && self.xw_widgets.count <= index) {
        if ([self xw_containWidget:widget] == false) {
            [widget setValue:self forKey:@"collectionView"];
            [self.xw_widgets insertObject:widget atIndex:index];
            [self xw_delayReload];
        }
    }
}

- (void)xw_removeWidget:(XWWidget *) widget{
    if ([self.xw_widgets containsObject:widget]) {
        [self.xw_widgets removeObject:widget];
        [self xw_delayReload];
    }
}

- (void)xw_removeAllWidgets{
    if (self.xw_widgets.count) {
        [self.xw_widgets removeAllObjects];
        [self xw_delayReload];
    }
}

- (BOOL)xw_containWidget:(XWWidget *)widget{
    return [self.xw_widgets containsObject:widget];
}


- (BOOL)xw_containWidgetClass:(Class) widgetClass{
    for (XWWidget * sub in self.xw_widgets) {
        if ([sub isMemberOfClass:widgetClass]) {
            return true;
        }
    }
    return false;
}


-(void)xw_collectionViewHeaderRefresh{

    for (XWWidget * widget in self.xw_widgets) {
        [widget setValue:@(true) forKey:@"needRequest"];
        [widget requestHeaderRefresh];
    }
}


-(void)xw_collectionViewFooterRefresh{
    for (XWWidget * widget in self.xw_widgets) {
        [widget setValue:@(true) forKey:@"needRequest"];
        [widget requestFooterRefresh];
    }
}


-(void)xw_endRefreshingWithWidgetState:(XWWidgetState)state{

}

/**
 *  请求数据完毕时回调
 */
- (void)xw_requestFinish{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reloadAllWidgetsIfNeed) object:nil];
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reloadData) object:nil];
    //    [self performSelectorOnMainThread:@selector(reloadAllWidgetsIfNeed) withObject:nil waitUntilDone:YES];
    [self performSelector:@selector(reloadAllWidgetsIfNeed) withObject:nil afterDelay:0];


}

-(void)reloadAllWidgetsIfNeed{
    BOOL need = true;
    for (XWWidget * widget in self.xw_widgets) {
        if (widget.state == XWWidgetStateRequsting) {
            need = false;
            break;
        }
    }
    if (need) {

        [self xw_reloadWidgets];
        [self xw_endRefreshingWithWidgetState:self.xw_state];

    }
}

#pragma mark - private

-(void) xw_delayReload{
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(xw_reloadWidgets) object:nil];
    [self performSelector:@selector(xw_reloadWidgets) withObject:nil afterDelay:0];
}

#pragma mark - getter setter

- (XWWidgetState)xw_state{
    XWWidgetState state = XWWidgetStateDefault;
    for (XWWidget * widget in self.xw_widgets) {
        if (widget.state == XWWidgetStateRequsting) {
            return XWWidgetStateRequsting;
        }
    }
    for (XWWidget * widget in self.xw_widgets) {
        if (widget.state == XWWidgetStateRequestNoMoreData) {
            state = XWWidgetStateRequestNoMoreData;
            break;
        }
        if (widget.state == XWWidgetStateRequestSuccess) {
            state = XWWidgetStateRequestSuccess;
        }
        if (widget.state == XWWidgetStateRequestFail && state != XWWidgetStateRequestSuccess) {
            state = XWWidgetStateRequestFail;
        }
    }
    return state;
}

- (NSMutableArray *)xw_headerDataList{
    NSMutableArray * list = objc_getAssociatedObject(self, @selector(xw_headerDataList));
    if (!list) {
        list = [NSMutableArray new];
        objc_setAssociatedObject(self, @selector(xw_headerDataList), list, OBJC_ASSOCIATION_RETAIN);
    }
    return list;
}

- (void)setXw_headerDataList:(NSMutableArray *)xw_headerDataList{
    objc_setAssociatedObject(self, @selector(xw_headerDataList), xw_headerDataList, OBJC_ASSOCIATION_RETAIN);
}

- (NSMutableArray *)xw_footerDataList{
    NSMutableArray * list = objc_getAssociatedObject(self, @selector(xw_footerDataList));
    if (!list) {
        list = [NSMutableArray new];
        objc_setAssociatedObject(self, @selector(xw_footerDataList), list, OBJC_ASSOCIATION_RETAIN);
    }
    return list;
}

- (void)setXw_footerDataList:(NSMutableArray *)xw_footerDataList{
    objc_setAssociatedObject(self, @selector(xw_footerDataList), xw_footerDataList, OBJC_ASSOCIATION_RETAIN);
}

- (NSMutableArray *)xw_cellDataList{
    NSMutableArray * list = objc_getAssociatedObject(self, @selector(xw_cellDataList));
    if (!list) {
        list = [NSMutableArray new];
        objc_setAssociatedObject(self, @selector(xw_cellDataList), list, OBJC_ASSOCIATION_RETAIN);
    }
    return list;
}

- (void)setXw_cellDataList:(NSMutableArray *)xw_cellDataList{
    objc_setAssociatedObject(self, @selector(xw_cellDataList), xw_cellDataList, OBJC_ASSOCIATION_RETAIN);
}

- (NSMutableArray *)xw_decorationViewClassList{
    NSMutableArray * list = objc_getAssociatedObject(self, @selector(xw_decorationViewClassList));
    if (!list) {
        list = [NSMutableArray new];
        objc_setAssociatedObject(self, @selector(xw_decorationViewClassList), list, OBJC_ASSOCIATION_RETAIN);
    }
    return list;
}

- (void)setXw_decorationViewClassList:(NSMutableArray *)xw_decorationViewClassList{
    objc_setAssociatedObject(self, @selector(xw_decorationViewClassList), xw_decorationViewClassList, OBJC_ASSOCIATION_RETAIN);
}

- (NSMutableArray *)xw_widgets{
    NSMutableArray * widgets = objc_getAssociatedObject(self, @selector(xw_widgets));
    if (!widgets) {
        widgets = [NSMutableArray new];
        objc_setAssociatedObject(self, @selector(xw_widgets), widgets, OBJC_ASSOCIATION_RETAIN);
    }
    return widgets;
}

- (void)setXw_widgets:(NSMutableArray *)xw_widgets{
    objc_setAssociatedObject(self, @selector(xw_widgets), xw_widgets, OBJC_ASSOCIATION_RETAIN);
}

@end

UICollectionView+XWWidget结构十分好领会,具体代码如上(,仅表示个人风格,如暴发大神解决这里可以改正的足联系自己,一起探讨下),就差一点个法子,除了widget插件的田间管理,还有虽然是网要,刷新,加载重多同网要了的回调。

2.Raining FM

其实应用

  • 如美团的首页,轮播图也一个widget,分类也一个widget,上边的货仍旧其他的吗一个widget,每个widget彼此独立(网络要,和响应时间独自),然后您即便召开的是将当下几乎独widget拼接起,不同之拼接顺序会生出预想不到的效劳。

  • UICollectionView插件化的以可高于你的设想,你即便而足足了然他,可以整合出各样应用或者

下边看现实落实代码:

//weak弱引用
#define KWeakSelf __weak typeof(&*self) weakSelf = self
#import "XWWidgetViewController.h"
#import "XWWidgetMacros.h"
#import "XWTest1Widget.h"
#import "XWTest2Widget.h"

@interface XWWidgetViewController ()<XWCollectionViewDataSource,UICollectionViewDelegate>

@property (nonatomic,strong) UICollectionView *cv;

@end

@implementation XWWidgetViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self creatUI];

    // Do any additional setup after loading the view, typically from a nib.
}

-(void)creatUI{

    [self.view addSubview:self.cv];

}

-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    NSLog(@"drag...");

}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

    NSLog(@"scroll-viewcontroller...");
}

-(UICollectionView *)cv{

    if (_cv == nil) {

        _cv = [UICollectionView createWithFlowLayout];
        _cv.frame = self.view.bounds;
        _cv.backgroundColor = [UIColor whiteColor];
//        _cv.alwaysBounceVertical = YES;
        [_cv xw_addWidget:[[XWTest1Widget alloc]init]];
        [_cv xw_addWidget:[[XWTest2Widget alloc]init]];
        [_cv.xw_delegates addObject:self];
    }
    return _cv;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(void)dealloc{

    NSLog(@"XWWidgetViewController dealloc");
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
  • XWTest1Widget

@interface XWTest1Widget ()

@end

@implementation XWTest1Widget

-(instancetype)init{

    if (self = [super init]) {

        [self creatCellData];
    }
    return self;
}

-(void)creatCellData{

    NSObject *header = [NSObject new];
    header.xw_height = 0.01;
    header.xw_width = [UIScreen mainScreen].bounds.size.width;
    header.cell_secionInset = UIEdgeInsetsMake(10, 0, 10, 0);
    header.cell_minimumLineSpacing = 10;
    header.cell_minimumInteritemSpacing = 10;

    self.headerData = header;

    NSMutableArray *cells = [NSMutableArray array];
    for (int i = 0; i < 20; i++) {

        [cells addObject:[[XWTest1Data alloc]init] ];
    }

    self.cellDataList = cells;
}

@end
  • XWTest2Widget

@interface XWTest2Widget ()

@end

@implementation XWTest2Widget

-(instancetype)init{

    if (self = [super init]) {

        [self creatCellData];
    }
    return self;
}

-(void)creatCellData{

    NSObject *header = [NSObject new];
    header.xw_height = 50;
    header.xw_width = [UIScreen mainScreen].bounds.size.width;
    header.cell_secionInset = UIEdgeInsetsMake(5, 0, 5, 0);
    header.cell_minimumLineSpacing = 5;
    header.cell_minimumInteritemSpacing = 5;

    self.headerData = header;

    NSMutableArray *cells = [NSMutableArray array];
    for (int i = 0; i < 20; i++) {

        [cells addObject:[[XWTest1Data alloc]init] ];
    }

    self.cellDataList = cells;
}

@end

由代码可以见见代码结构非凡清晰,业务范围看不到UICollectionVie
w繁琐的数据源代理,当然矣点击事件与任何代理可以当cell上落实为得由具体事务实现,内部也壮大了大多代理转发机制。

自己个人最好喜爱的如出一辙种植白噪声网站,使用方便,分别点击方框中的6独图标可以开启对应功效,点击“咖啡”图标可以当作番茄钟使用,比如改成为25分钟(一个西红柿)或者50分钟(二独西红柿),比如每一天朝本身举办创作时,会调动成为100分钟(四单西红柿),然后轻易挑好喜欢的降雨背景声情势,犹如在雨中疯狂奔于小满冲去疲劳的舒适感。推出的付费版AndroidIOS客户端,强烈提出喜欢的爱侣举办付费买,当做番茄钟使用绝对化超值。

写于最终

延长阅读:

UICollectionView插件化优点
  • 代码结构清晰,由数量令视图(数据即视图),解决控制器臃肿,代码容易看
  • 增长支付功效,项目面临距离不起始列表,UITableView和UICollectionView的数据源代理几乎无处不在,UICollectionView插件化很好之解决了即刻同痛点
  • 最终可维护性强,只要做好合理分widget,先前时期修改某插件内的情,或者新增删除某个插件,只要管理widget即可
  • 而是复用性强,有做过电商与情节外之档次都懂,往往有同片内容基本上处可见,这时候若才待来单通用的Widget即可,什么地方需要哪add

20150331更新:为啥自己无能为力吃少三光青蛙啊?

闲言杂语

如上内容仅代表个人想法,假设你来更好之想法,更好之解决办法,可以合切磋。若是你认为自己的想法是,可以在群639762230一起探索哦~

图片 3

3.Ambient-Mixer

一个那么些好游戏来新意之DIY环境音乐合成网站,可以任意点击图片或网站左侧来挑选条件音乐序列播放,协理十三大类。

图片 4

点击某图片后,要稍等片刻因为用加载8只音轨的条件音乐,然后出现下图后好好肆意的改参数或者滑动8个音轨的轻重甚至静音,感觉温馨就是比如一个DJ一样可以自由创作好之乐小样,不过假设欲下载的说话则用付费。同样生产的Android和IOS客户端分成免费或付费格局,相当人性化考量,两者都足以当线听所以种音乐,假诺欲保留音乐小样则付费。

季种植客户端下载地址:http://www.ambient-mixer.com/mobile-download

图片 5

4.Noisli

层见迭出上网站经常背景颜色如下,当接纳随机播放情势要为生滑动网页日常,选用好喜欢的一定背景声:比如火焰燃烧呲呲声、微风拂落叶声、小溪水流声、海浪轻拍声、虫鸣鸟叫声、电视机没有节目滋滋声,超发痛感,播放一会儿网站背景颜色为会合时刻切换成其余纯色,近来独生产付费IOS客户端,拔取的凡离线音乐下载包情势,所以app体积庞大,达到251M.

图片 6

小结:

目前这三只白噪声网站是本身死喜欢的网站,需要集中注意力提高功能启发创意时有不错的效应哦!依据自己的情怀,随意切换使用,强烈推荐给读者朋友等,也欢迎各位分享你协调喜欢的白噪声网站哦!

图片 7

Post Author: admin

发表评论

电子邮件地址不会被公开。 必填项已用*标注