美文网首页
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