美文网首页UIKitiOS图形处理相关iOS小记
干货!老司机工作中用到的自定义控件,总有一个适合你的(一)

干货!老司机工作中用到的自定义控件,总有一个适合你的(一)

作者: 杂雾无尘 | 来源:发表于2016-11-10 23:50 被阅读4976次

今天总结了一下平时工作中为那些奇葩的UI设计自定义的控件,下面一个个分享给大家。


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

1、效果:

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

技术交流群:413050745

除此之外还在.h放出了这些属性

// 所有title
@property (nonatomic, strong, readonly) NSArray *titles;
// 底部的滑块
@property (nonatomic, strong, readonly) UIView *backgroundView;
// 辅助属性,当前选中的Button
@property (nonatomic, strong, readonly) UIButton *selectButton;
// 为选中的button颜色
@property (nonatomic, strong) UIColor *normalColor;
// 选中的button颜色
@property (nonatomic, strong) UIColor *selectColor;
// 滑块颜色
@property (nonatomic, strong) UIColor *sliderColor;
// 边框颜色
@property (nonatomic, strong) UIColor *edgingColor;
// 边框颜色
@property (nonatomic, assign) CGFloat edgingWidth;

以便使用者可以单独设置某个颜色

// 点击title的block回调
@property (nonatomic, copy) void(^tClick)(NSInteger index);
// 点击title的block回调,selectButton:选中的button
@property (nonatomic, copy) void(^titleClick)(NSInteger index, UIButton *selectButton);

还有这两个block,一个block只有选中下标参数,另外一个有选中下标和选中的button两个参数

好吧!我承认很多人喜欢用代理而不是block,为什么不提供代理方法呢?OK,Here!

@protocol WZBSegmentedControlDelegate <NSObject>
@optional
// segmented点击的时候调用,selectIndex:选中的index
- (void)segmentedValueDidChange:(WZBSegmentedControl *)segment selectIndex:(NSInteger)selectIndex;
// segmented点击的时候调用,selectIndex:选中的index,fromeIndex:从哪个index点过来的
- (void)segmentedValueDidChange:(WZBSegmentedControl *)segment selectIndex:(NSInteger)selectIndex fromeIndex:(NSInteger)fromeIndex;
// segmented点击的时候调用,selectIndex:选中的index,fromeIndex:从哪个index点过来的,selectButton:选中的button
- (void)segmentedValueDidChange:(WZBSegmentedControl *)segment selectIndex:(NSInteger)selectIndex fromeIndex:(NSInteger)fromeIndex selectButton:(UIButton *)selectButton;
// segmented点击的时候调用,selectIndex:选中的index,fromeIndex:从哪个index点过来的,selectButton:选中的button,allButtons:所有的button
- (void)segmentedValueDidChange:(WZBSegmentedControl *)segment selectIndex:(NSInteger)selectIndex fromeIndex:(NSInteger)fromeIndex selectButton:(UIButton *)selectButton allButtons:(NSArray *)allButtons;
@end

注释很清楚

简单给大家讲下拖动的时候颜色渐变的实现,直接上代码

// 根据颜色拿到RGB数值
void getRGBValue(CGFloat colorArr[3], UIColor *color) {
    unsigned char data[4];
    // 宽,高,内存中像素的每个组件的位数(RGB应该为32),bitmap的每一行在内存所占的比特数
    size_t width = 1, height = 1, bitsPerComponent = 8, bytesPerRow = 4;
    // bitmap上下文使用的颜色空间
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    // 指定bitmap是否包含alpha通道
    uint32_t bitmapInfo = 1;
    // 创建一个位图上下文。当你向上下文中绘制信息时,Quartz把你要绘制的信息作为位图数据绘制到指定的内存块。一个新的位图上下文的像素格式由三个参数决定:每个组件的位数,颜色空间,alpha选项。alpha值决定了绘制像素的透明性
    CGContextRef context = CGBitmapContextCreate(&data, width, height, bitsPerComponent, bytesPerRow, space, bitmapInfo);
    // 设置当前上下文中填充颜色
    CGContextSetFillColorWithColor(context, [color CGColor]);
    // 在此区域内填入当前填充颜色
    CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
    CGContextRelease(context);
    CGColorSpaceRelease(space);
    for (NSInteger i = 0; i < 3; i++) {
        colorArr[i] = data[i];
    }
}

这是写的一个c语言函数,每句基本都有注释,说白了就是把RGB颜色拆分开,R是多少,G是多少,B是多少,然后放数组里。

// 找出要操作的两个button设置颜色
    NSMutableArray *buttonArr = [NSMutableArray array];
    for (UIButton *button in self.allButtons) {
        CGFloat overLapWidth = CGRectIntersection(button.frame, self.backgroundView.frame).size.width;
        if (overLapWidth > 0) {
            [buttonArr addObject:button];
        }
    }
    
    // 切换的时候
    if (buttonArr.count > 1) {
        UIButton *leftButton = buttonArr.firstObject;
        UIButton *rightButton = buttonArr.lastObject;
        // 设置要渐变的两个button颜色
        [rightButton setTitleColor:WZBColor([self getRGBValueWithIndex:0 button:rightButton], [self getRGBValueWithIndex:1 button:rightButton], [self getRGBValueWithIndex:2 button:rightButton]) forState:UIControlStateNormal];
        [leftButton setTitleColor:WZBColor([self getRGBValueWithIndex:0 button:leftButton], [self getRGBValueWithIndex:1 button:leftButton], [self getRGBValueWithIndex:2 button:leftButton]) forState:UIControlStateNormal];
    }

先找到两个需要更改颜色的button,按照button和底部滑块交叉区域的宽度比例,切换每个R、G、B的值,具体大家可以下载最新的源码

有不懂或者任何疑问的地方都可以在下方评论,或者随时联系我,您还可以用QQ扫描底部的二维码加入我们的技术交流群,我在那里等着你!

想看更多,请点击:干货!老司机工作中用到的自定义控件,总有一个适合你的(二)

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

请不要吝惜,随手点个喜欢或者关注一下吧!您的支持是我最大的动力😊!
此系列文章持续更新,您可以关注我以便及时查看我的最新文章或者您还可以加入我们的群,大家庭期待您的加入!

我们的社区我们的社区

相关文章

网友评论

  • c7fd7e0ef519:666,能用到
  • ca4debe814a1:膜拜一下,你的代码很想敲一遍
  • 2349f65f6410:已加入大家庭,希望楼主多多关照:smile:
  • 119ae31c9761:简书有你更精彩
  • 大牛的春天:有帮助,已关注,希望能多出点类似的技术分享:smile:
  • 繁华乱世沧桑了谁的容颜:仿网易界面切换那个 WZBSegmentedControl *segmentedControl = [WZBSegmentedControl segmentWithFrame:(CGRect){0, 0, 170, 25} titles:[self titles] tClick:^(NSInteger index) {
    [self.scrollView setContentOffset:CGPointMake(index * WZBScreenW, 0)];
    }];
    当点击第一个按钮的时候 就0索引 你的index 返回的是nil
    还有就是滑动的时候 哪个地方返回idex 的值? 这个用的时候肯定用的到 ,谢谢
    杂雾无尘:@繁华乱世沧桑了谁的容颜 感谢您的评论🙏
    如果你在断点的时候使用po打印,它只能打印指针类型,如果是基本数据类型,你可以直接用p打印。如:p index
    繁华乱世沧桑了谁的容颜:@杂雾无尘 我是直接下载你的Demo,然后点击打断点,当点击第一个的时候打印的index是NILL,点击后面的正常,可能是显示问题
    杂雾无尘:@繁华乱世沧桑了谁的容颜 非常感谢您的评论🙏
    1、我在block里加了句NSLog(@"clickIndex : %zd", index);,从打印来看并没有复现您说的index为nil的情况,请问您的调试方法是怎样的?
    2、scrollView滑动的时候不会调用block,若想拿到索引可以通过当前scrollView的x轴的偏移量计算出来。
  • 584582a8b011:我曾经实现过一个类似的效果,其实在上下盖两个png的渐变图片就解决了
    春泥Fu:@hlily :scream: :flushed: 好土好暴力的方法,我喜欢!
  • 一舟孤月:老司机,干货有点少啊,不够用啊
    班蹄子:可以。希望多出点
    杂雾无尘:@一舟孤月 哈哈……好东西一次不能多给,等待下次更新吧,很快的:smile:
  • 花前月下:可以的。666

本文标题:干货!老司机工作中用到的自定义控件,总有一个适合你的(一)

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