美文网首页
UIButton 的 isSelected 设置为 true 时

UIButton 的 isSelected 设置为 true 时

作者: AndyGF | 来源:发表于2020-09-10 21:32 被阅读0次

需求:

一个 testButton按钮, 设置上normalselected 状态下的 titletitle颜色, 在点击按钮时, 改变选中状态, title随之改变, 不需要高亮状态.

当按钮处于选中状态时, 长按 testButton 不松手, 按钮显示 normal 状态对应的设置,

  • 如果松开手, 那么按钮的 selected 状态将被改成 false, 一切正常;
  • 如果不松手,而是将手拖动至按钮范围之外, 按钮又会恢复到 选中状态, 实际此时按钮的选中状态并未改变, 还是 true. 如何验证选中状态未改变呢 ? 可以在按钮点击方法中打个断点, 未松手前并没有进入方法.

这就有点不完美了. 体验就不好了, 特别是作为自定义 tabBar 按钮时, 明显不是我们想要的.

待解决的问题:

当处于选中状态时, 长按时不发生任何变化, 即不显示 normal 状态的设置, 只有当松开手执行了按钮点击方法, 选中状态被改变才显示对应的设置.

本案例只设置了不同状态的 titletitle的颜色, 不同状态的图片也是一样的.

有问题的代码

import UIKit

class ViewController: UIViewController {
    
    private lazy var testButton: UIButton = {
        
        let btn = UIButton(type: .custom)
        
        btn.backgroundColor = .gray
        btn.frame = CGRect(x: 157, y: 300, width: 100, height: 40)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 20)
        
        btn.setTitle("normal", for: .normal)
        btn.setTitleColor(.red, for: .normal)
        
        btn.setTitle("selected", for: .selected)
        btn.setTitleColor(.green, for: .selected)
        
        btn.adjustsImageWhenHighlighted = false
        
        btn.addTarget(self, action: #selector(btnAction(_ :)), for: .touchUpInside)
        return btn
    }()
   
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(testButton)
    }
    
    @objc func btnAction(_ sender: UIButton) {
        
        sender.isSelected.toggle()
    }
}

如何解决这个问题呢

解决问题的方法很简单, 只要在按钮初始化中对 titletitle 的颜色增加一个设置即可, 这个设置的内容同选中状态, 图片同理. 具体看代码:

let select = UIControl.State.selected.rawValue
let high = UIControl.State.highlighted.rawValue
btn.setTitle("selected", for: UIControl.State(rawValue: select | high))
btn.setTitleColor(.green, for: UIControl.State(rawValue: select | high))

首先来看看解决这个问题的全部条件:

  • 1.按钮类型必须为: .custom .
  • 2.设置 选中 | 高亮 状态, 配置与 选中 状态相同.
  • 3.必须禁用高亮状态: btn.adjustsImageWhenHighlighted = false.
解决问题全部条件

分析原理:

前两条禁用的高亮状态, 大家应该都知道 ,这是福利, 下面说重点.

为什么这样设置就可以了呢 ?

我们来年看看 UIControl.State 这个枚举的定义:

Swift 定义
public struct State : OptionSet {

        public init(rawValue: UInt)

        
        public static var normal: UIControl.State { get }

        public static var highlighted: UIControl.State { get } // used when UIControl isHighlighted is set

        public static var disabled: UIControl.State { get }

        public static var selected: UIControl.State { get } // flag usable by app (see below)

        @available(iOS 9.0, *)
        public static var focused: UIControl.State { get } // Applicable only when the screen supports focus

        public static var application: UIControl.State { get } // additional flags available for application use

        public static var reserved: UIControl.State { get } // flags reserved for internal framework use
    }

Swift 中的定义看的不明显, 我们通过对这个值的打印, 不难猜到这是个 位枚举.

检举值
OC的定义比较清楚.
typedef NS_OPTIONS(NSUInteger, UIControlState) {
    UIControlStateNormal       = 0,
    UIControlStateHighlighted  = 1 << 0,                  // used when UIControl isHighlighted is set
    UIControlStateDisabled     = 1 << 1,
    UIControlStateSelected     = 1 << 2,                  // flag usable by app (see below)
    UIControlStateFocused API_AVAILABLE(ios(9.0)) = 1 << 3, // Applicable only when the screen supports focus
    UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use
    UIControlStateReserved     = 0xFF000000               // flags reserved for internal framework use
};

按钮的状态是位枚举,不是普通的枚举,也就是说按钮可以有不止一个状态。所以当按钮的selectedtrue 时,再点击的时候状态应该不是 normal 状态而是其他状态。

发现了相关的说明: UIButton UIControl state

也就是说. 选中状态的不同, 按钮的状态也是不同的, 具体可以分为四种状态:

  • selected == false 的时候,分别对应 normalhighlighted
  • selected == true 的时候,分别对应 selectedselected | highlighted

由以上的说明,出现按钮在 selectedtrue 时,再次点击按钮的状态变成了normal 状态情况的原因:没有设置 selected | highlighted 的状态,系统默认会显示 normal 的状态

相关文章

网友评论

      本文标题:UIButton 的 isSelected 设置为 true 时

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