UIButton选中状态下的点击

作者: CoderAO | 来源:发表于2015-07-03 12:59 被阅读25152次

    在类似点赞或切换浏览模式等功能的时候,需要用到button的选中状态:即点击后按钮切换图片,并保持这个状态,直到下一次点击.
    如:


    接下来我们就以这两个图片为例子.

    已知点击前那张图片名字是like.png,简称"like",
    嫩绿色那张图片名字是like_selected.png,简称为"like_selected".

    初学者可能的做法

    • 创建button的时候设置normal状态下的图片为like,点击后重新设置normal状态下的图片为like_selected,代码如下:
    // 省略了部分非关键代码
    [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    
    - (void)buttonClick:(UIButton *)button {
        if ([button.currentImage isEqual:[UIImage imageNamed:@"like"]]) {
            [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateNormal];
        }
        else {
            [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
        }
    }
    

    虽然我也曾经写过这样写过(往事不堪回首...),虽然是可以勉强达到要求,但不得不承认,这是一段糟糕的代码,强烈不建议大家使用.

    进阶做法

    • 分别设置按钮在normal和selected状态下的图片,点击按钮时切换按钮的选中状态:
    // 省略了部分非关键代码
        [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
        [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
        [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    - (void)buttonClick:(UIButton *)button {
        button.selected = !button.selected;
    }
    

    看起来好多了,代码似乎也更加合理.

    但是使用过这种方法的人应该都会遇到这样一个问题:不管按钮从normal状态转为selected状态,还是反过来,中间都会经历一个highLighted状态,这就导致在状态切换的过程中有一次图片的跳变.如图:

    • 改进

      我们可能想到给button的highted状态也设置图片:
    [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"like"] forState: UIControlStateHighlighted];
    [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
    

    这样设置后,按钮从normal变为selected的过程看起来似乎行得通了,但是,从selected再变回normal的过程还是会出现那个该死的hightLighted状态.

    感到奇怪吧?我们明明已经设置了hightLighted状态下的图片,怎么回来的路行不通呢? 有没有可能从selected状态变回normal状态这个过程经历的并不是hightLighted状态,而是其他什么状态呢?

    没错,这个状态就是UIControlStateSelected | UIControlStateHighlighted,我们可以理解成选中时候的高亮状态.

    初学的时候对这个状态不理解,还以为是同时设置选中状态高亮状态下的图片,学习过程中发现真谛后大彻大悟.

    • 再改进
    [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"like"] forState: UIControlStateHighlighted];
    [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
    [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];
    

    这样就完全达可以了,不管如何点击按钮,按钮的图片只显示两种,而且都是手指抬起来的时候改变.

    更先进一点的做法

    • 重写button的setHighted:方法

    我们需要自定义一个继承自UIButton的子类,并将刚才创建的button类型改为我们创建的类型.

    接着在自定义button的内部重写setHighted:方法

    - (void)setHighlighted:(BOOL)highlighted {
    
    }
    

    当然你不需要在方法里面做任何事情,这表示我们阻止了系统按钮默认的做法,屏蔽了它的高亮效果.按钮也只需简单地设置为:

    [button setImage:[UIImage imageNamed:@"like"] forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected];
    

    ok,以上就是今天的全部内容.
    当然说"更先进一点的做法"这种说法可能不够准确,仁者见仁嘛,也许你觉得仅为了一个高亮就不需要大费周章地自定义一个button了.我保留意见,只要大家不要用第一种做法就好了.

    相关文章

      网友评论

      • 李某lkb:不错
      • _moses:如果从代码量的方面考虑的话,还是你说的所谓的初学者的方法更好;如果从便于理解的方面考虑的话,也是一样。
        这篇文章的意义仅仅在于能多了解点知识;实际使用中,无论需不需要高亮,如果需要设置button的选中状态,一定是更改normal状态的image最合适。
      • 小刘_假装是个程序员:谢谢 分享,很好。
      • GodLiekZ:可以通过重写高亮方法 改变系统高亮的颜色么 我只需要让系统高亮颜色再浅一点
      • konglei:刚好遇到,mark
      • iOS_Xue:牛逼,干净利落麻利!!!
      • Corbin___:我设置了,但是点击button后,差不多有0.05s的延迟后才变为选中status的image
        CoderAO:设置了是按照哪个方法设置的? 0.05s的延迟是怎么计算的?
      • cookov:之前为选中状态下的高亮纠结了蛮久,原来这样。学习了:+1:
      • 897948f5dfd3:好. 有用. 学习了!
      • Megatron9527:感谢分享
      • yinxing29:完美解决我的问题,感谢博主。
      • 子胥:666
      • 骑马纵天下:学习了
      • Rickie_Lambert:同一个地方 栽跟头两次。。。。哈哈:sweat_smile:
      • roc_lei:刚好遇到这个问题
      • _Alice丶:感谢楼主,写的很好
      • Coolerting:卧槽,重写setHighlighted真的达到我要的效果了~:+1:
      • 溜了12315:赞赞赞,找了大半天才发现!!!!!!!!
      • 0cceab5346ce:学习啦~感谢
      • iOS之星:大神分享的非常好, 但是能不能不通过集成按钮的方式来弄呢, 有没有这两种方法之外的方法呢,因为大神说的最后一个方法,要重新写一个集成UIButton的自定义按钮, 在别的地方又得导入该按钮的头文件,如果是XIB的话又得让该按钮集成自定义的按钮,感觉不舒服
      • 木子尚武:最重要的是原理讲的很细,最后的办法很巧妙
      • 霖溦:button.adjustsImageWhenHighlighted = NO;可以屏蔽系统的点击高亮状态,但是如果设置selected还是会在点击时出现一个不希望的过渡状态,设置博主的[button setImage:[UIImage imageNamed:@"like_selected"] forState:UIControlStateSelected | UIControlStateHighlighted];后效果立竿见影,感谢博主分享

      • code_间特门:真的很厉害
        我想打赏 :grin:
      • Randall_Steven:学习了 :smile:
      • devchena:不错 :clap:
      • 小凡凡520:good mark

      本文标题:UIButton选中状态下的点击

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