美文网首页
iOS开发中用到的自定义控件

iOS开发中用到的自定义控件

作者: 王宪岭 | 来源:发表于2016-11-14 17:05 被阅读0次

    一、第一个是tableView的透明度渐变效果

    1、效果:

    很多app用到了这种效果,比如歌词显示、直播间聊天记录等。

    大致效果如下:

    2、使用方法:

    /*

    * frame:tableView的frame

    * direction:透明渐进的方向

    * gradualValue:透明范围值,如果只有一个方向,此值传一个NSNumber、NSString即可,值的范围0—1。如果是两个方向,则需要传一个数组,数组里边传两个NSNumber或者NSString

    ***/

    + (instancetype)gradualTableViewWithFrame:(CGRect)frame direction:(WZBTableViewGradualDirection)direction gradualValue:(id)gradualValue;

    参数值说明一下,direction代表方向,是一个位移枚举,如果想让tableView顶部渐变,则此值为WZBTableViewGradualDirectionTop,如果为底部渐变,则此值为WZBTableViewGradualDirectionBottom,如果上下都要渐变,则需要WZBTableViewGradualDirectionTop | WZBTableViewGradualDirectionBottom。gradualValue代表渐变范围值,值的范围为0-1,如果想让顶部20%渐变,此值为@(0.2)。如果想顶部底部都有20%渐变,此值为@[@(0.2), @(0.2)]。

    如下:

    WZBGradualTableView *tableView = [WZBGradualTableView gradualTableViewWithFrame:self.view.bounds direction:(WZBTableViewGradualDirectionTop | WZBTableViewGradualDirectionBottom)  gradualValue:@[@(.3), @0.3]];

    如果这样写

    [WZBGradualTableView gradualTableViewWithFrame:CGRectMake(0, self.view.frame.size.height - 180, self.view.frame.size.width, 140) direction:WZBTableViewGradualDirectionTop  gradualValue:@.3f]

    3、实现大致原理:

    这种渐变效果主要用到tableView的mask属性,我们首先要创建一个CAGradientLayer,此类的使用网上介绍有很多,在这里不再累述,不懂得私聊我,或者加入我的技术群。

    上代码:

    if (!self.layer.mask) {

    CAGradientLayer *maskLayer = [CAGradientLayer layer];

    maskLayer.locations = @[@0.0, topValue, @(1-bottomValue.doubleValue), @1.0f];

    maskLayer.bounds = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);

    maskLayer.anchorPoint = CGPointZero;

    self.layer.mask = maskLayer;

    }

    [self addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];

    由于tableView可以滑动,滑动的时候就需要实时的作出改变,因此我这里使用KVO监听“contentOffset”属性,每当contentOffset发生改变,证明用户滑动了tableView,这时候需要调用的代码为:

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if ([keyPath isEqualToString:@"contentOffset"]) {

    [self change];

    }

    }

    - (void)change {

    UIScrollView *scrollView = (UIScrollView *)self;

    CGColorRef outerColor = [UIColor colorWithWhite:1.0 alpha:0.0].CGColor;

    CGColorRef innerColor = [UIColor colorWithWhite:1.0 alpha:1.0].CGColor;

    NSArray *colors;

    if (scrollView.contentOffset.y + scrollView.contentInset.top = scrollView.contentSize.height) {

    //Bottom of tableView

    colors = @[(__bridge id) outerColor, (__bridge id) innerColor,

    (__bridge id) innerColor, (__bridge id) innerColor];

    } else {

    //Middle

    colors = @[(__bridge id) outerColor, (__bridge id) innerColor,

    (__bridge id) innerColor, (__bridge id) outerColor];

    }

    ((CAGradientLayer *) scrollView.layer.mask).colors = colors;

    [CATransaction begin];

    [CATransaction setDisableActions:YES];

    scrollView.layer.mask.position = CGPointMake(0, scrollView.contentOffset.y);

    [CATransaction commit];

    }

    别忘了移除观察者:

    - (void)dealloc {

    [self removeObserver:self forKeyPath:@"contentOffset"];

    }

    4、GitHub源码地址:https://github.com/WZBbiao/WZBGradualTableView

    二、自定义的开关控件

    1、效果:

    2、使用方法:

    将WZBSwitch.h和WZBSwitch.m拖入工程

    在需要使用的地方调用

    /** 初始化方法

    *  switchValueChange: 开关状态改变回调block

    */

    WZBSwitch *switchView = [[WZBSwitch alloc] initWithFrame:CGRectMake(100, 100, 50, 25) switchValueChanged:^(WZBSwitch *swith, BOOL on)    {

    // do someing

    }];

    [self.view addSubview:switchView];

    对于开关状态的监听或者您还可以通过代理:

    WZBSwitch *switchView = [[WZBSwitch alloc] initWithFrame:CGRectMake(100, 100, 50, 25)];

    [self.view addSubview:switchView];

    // delegate

    switchView.delegate = self;

    然后实现代理方法即可

    #pragma mark - WZBSwitchDelegate

    - (void)switchValueChange:(WZBSwitch *)swith on:(BOOL)on {

    // do someing

    }

    如果您想自定义开关颜色,代码如下:

    //设置所有颜色

    [switchView setUpAllColors:^NSDictionary *(UIColor *__autoreleasing *onTintColor, UIColor *__autoreleasing *onBackgroundColor,                UIColor *__autoreleasing *offTintColor, UIColor *__autoreleasing *offBackgroundColor, UIColor *__autoreleasing *tintColor) {

    // 可以通过这种方法设置需要设置的颜色

    *onTintColor = [UIColor redColor];

    *onBackgroundColor = [UIColor blueColor];

    *offTintColor = [UIColor greenColor];

    *offBackgroundColor = [UIColor grayColor];

    *tintColor = [UIColor blackColor];

    return nil;

    }];

    或者这样

    [switchView setUpAllColors:^NSDictionary *(UIColor *__autoreleasing *onTintColor, UIColor *__autoreleasing *onBackgroundColor, UIColor    *__autoreleasing *offTintColor, UIColor *__autoreleasing *offBackgroundColor, UIColor *__autoreleasing *tintColor) {

    // 也可以通过这种方法设置需要设置的颜色

    return @{OnTintColor : WZBColor(234, 67, 53), OnBackgroundColor : WZBColor(244, 161, 154), OffTintColor : WZBColor(255, 255,              255), OffBackgroundColor : WZBColor(214, 214, 214), TintColor : [UIColor colorWithRed:0.8252 green:0.8252 blue:0.8252                  alpha:1.0]};

    }];

    3、实现大致原理:

    此控件由两部分组成,顶部View和底部View

    @property (nonatomic, strong) UIView *topView;

    @property (nonatomic, strong) UIView *bottomView;

    /** 一个方法设置所有颜色 && block回调

    *  switchValueChange: 开关状态改变回调block

    */

    - (void)setUpAllColors:(NSDictionary *(^)(UIColor **onTintColor,UIColor **onBackgroundColor, UIColor **offTintColor, UIColor **offBackgroundColor, UIColor **tintColor))allColorBlock switchValueChanged:(SwitchValueChangeBlock)switchValueChange;;

    这个方法有两个block参数,第一个可以设置您所需要设置的所有颜色值,第二个block是当开关状态发生改变的时候回调

    /** 设置开关状态, animated : 是否有动画 */

    - (void)setOn:(BOOL)newOn animated:(BOOL)animated;

    此方法用于设置开关状态

    @protocol WZBSwitchDelegate

    @optional

    - (void)switchValueChange:(WZBSwitch *)swith on:(BOOL)on;

    @end

    如果您不喜欢使用block,我还提供了代理方法监听开关状态的改变

    - (void)setOn:(BOOL)newOn animated:(BOOL)animated {

    //    if (_on == newOn) return;

    __block CGRect frame = self.topView.frame;

    CGFloat newX = newOn ? self.frame.size.width - self.topView.frame.size.width : 0;

    [UIView animateWithDuration:animated ? 0.2 : 0.0 animations:^{

    frame.origin.x = newX;

    self.topView.frame = frame;

    [self setSwitchColorWithStatus:newOn];

    }                completion:^(BOOL finished) {

    if (finished) {

    // delegate

    if ([self.delegate respondsToSelector:@selector(switchValueChange:on:)]) {

    [self.delegate switchValueChange:self on:newOn];

    }

    // block

    if (self.switchValueChange) {

    self.switchValueChange(self, newOn);

    }

    }

    }];

    _on = newOn;

    }

    当外界调用方法改变开关状态时,动画/非动画,改变上层View的frame即可

    4、GitHub源码地址:https://github.com/WZBbiao/WZBSwitch

    三、一个仿网易的Segment

    1、效果:

    2、使用方法:

    将WZBSegmentedControl.h和WZBSegmentedControl.m拖入工程

    在需要使用的地方调用

    /** 初始化方法

    *  titles: 所有标题

    *  titleClick: 点击标题的block回调

    */

    WZBSegmentedControl *segmentedControl = [WZBSegmentedControl segmentWithFrame:(CGRect){0, 0, 170, 25} titles:[self titles] titleClick:^(NSInteger index) {

    // do soming

    }];

    self.navigationItem.titleView = segmentedControl;

    3、实现大致原理:

    此控件还不是很完善,目前只提供一个初始化方法:

    /* 初始化方法

    * frame:控件frame

    * titleClick:点击title的时候block回调

    **/

    + (instancetype)segmentWithFrame:(CGRect)frame titles:(NSArray *)titles titleClick:(void(^)(NSInteger index))titleClick;

    - (void)setContentOffset:(CGPoint)contentOffset {

    CGRect frame = self.backgroundView.frame;

    frame.origin.x = contentOffset.x;

    self.backgroundView.frame = frame;

    // 找出要操作的两个button设置颜色(目前先这样写,后续改进)

    for (UIView *v in self.subviews) {

    if ([v isKindOfClass:[UIButton class]]) {

    UIButton *button = (UIButton *)v;

    CGFloat overLapWidth = CGRectIntersection(button.frame, self.backgroundView.frame).size.width;

    NSInteger gb = 255 - overLapWidth * (255 / (self.frame.size.width / self.titles.count));

    [button setTitleColor:WZBColor(255, gb, gb) forState:UIControlStateNormal];

    }

    }

    }

    核心方法:改变底部白色滑块的位置,但是如果注意观察,有个注意点是,在滑动的时候title的文字也会随着渐变,目前先试用这个方法临时解决,后续会提供方法设置文字颜色、选中文字颜色、背景颜色以及滑块颜色等。

    4、GitHub源码地址:https://github.com/WZBbiao/WZBSegmentedControl

    怎么样,这些您学会怎么用了吗?

    相关文章

      网友评论

          本文标题:iOS开发中用到的自定义控件

          本文链接:https://www.haomeiwen.com/subject/ihkfpttx.html