Ios 我可以为自己的控件使用uicontrol状态的自定义值吗?

Ios 我可以为自己的控件使用uicontrol状态的自定义值吗?,ios,objective-c,cocoa-touch,uicontrol,Ios,Objective C,Cocoa Touch,Uicontrol,是否有方法为UIControl设置自定义状态-而不是现有的UIControl状态值之一 在uicontrolState枚举中,有16位可用于自定义控件状态: UIControlStateApplication = 0x00FF0000, // additional flags available for application use 问题是UIControl的状态属性是只读的 我想为自定义状态设置不同的背景图像到我的ui按钮。您可以在UIControl子类中使用自

是否有方法为
UIControl
设置自定义状态-而不是现有的
UIControl状态值之一

uicontrolState
枚举中,有16位可用于自定义控件状态:

UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use
问题是
UIControl
状态
属性是只读的


我想为自定义状态设置不同的背景图像到我的
ui按钮。

您可以在UIControl子类中使用自定义状态

  • 创建一个名为
    customState
    的变量,用于管理自定义状态
  • 如果需要设置状态,请对该变量执行标记操作,并调用
    [self stateWasUpdated]
  • 覆盖
    state
    属性,以针对
    customState
  • 覆盖
    已启用
    选定
    突出显示的
    设置程序,以便它们调用
    [自状态更新]
    。这将允许您响应状态的任何更改,而不仅仅是对
    customState
  • 使用逻辑来响应状态更改,实现状态更新
在标题中:

#define kUIControlStateCustomState (1 << 16)

@interface MyControl : UIControl {
    UIControlState customState;
}

基于@Nick answer,我实现了一个更简单的版本。此子类公开了一个
BOOL-outlined
属性,该属性在功能上类似于
selected
高亮显示的
和启用的

执行类似于
[CustomButton setImage:[UIImage ImageName:@“MyOutlinedButton.png”]forState:UIControlStateOutlined]
的操作可以在更新
outlined
属性时自动工作

如果需要,可以添加更多这些state+属性


UICustomButton.h


UICustomButton.m


const uicontrol状态uicontrol状态概述=(1Nick答案的Swift 3版本:

extension UIControlState {
    static let myState = UIControlState(rawValue: 1 << 16)
}

class CustomControl: UIControl {

    private var _customState: UInt = 0

    override var state: UIControlState {
       return UIControlState(rawValue: super.state.rawValue | self._customState)
    }

    var isMyCustomState: Bool {
        get { 
            return self._customState & UIControlState.myState.rawValue == UIControlState.myState.rawValue 
        } set {
            if newValue == true {
                self._customState |= UIControlState.myState.rawValue
            } else {
                self._customState &= ~UIControlState.myState.rawValue
            }
        }
    }
}
扩展uicontrol状态{
静态let myState=uicontrol状态(rawValue:1我想对此策略稍加改进。请参阅此stackoverflow问题:

事实证明,苹果的
状态
实现实际上是一个基于其他属性的计算属性,
被选中
被点亮
被启用
,等等

因此,实际上不需要在uicontrol状态之上使用自定义状态位掩码(好吧,不是没有必要,只是它在需要/不应该的地方增加了复杂性)

如果希望与Apple的实现一致,只需重写state属性并在getter中检查自定义状态

extension UIControlState {
     static let myState = UIControlState(rawValue: 1 << 16)
} 

class MyControl: UIControl {

      override var state: UIControlState {
          var state = super.state
          if self.isMyCustomState {
               state.insert(UIControlState.myState)
          }
          return state
      }

      var isMyCustomState: Bool = false
 }
扩展uicontrol状态{
静态let myState=uicontrol状态(rawValue:1 uicontrol状态枚举指定应用程序控制状态使用掩码0x00FF0000。这意味着1还应注意;如果计划使用自定义状态控制UIButton中的自定义资源,如标题、背景图像、图像、标题阴影或attributedTitle。更改自定义状态后必须调用setNeedsLayout。O因此,该按钮只会在再次点击后更新其外观。绝对不要使用1。另一个问题是一个很好的支持性解释:我认为将自己作为一个额外的位注入现有的
状态
位掩码是没有意义的。它具有“脆弱性”上面写满了。推导出一种完全不同的表达状态的方式是一回事,但假设苹果自己的
状态的第16位是并且永远是免费的,这是错误的。在某种程度上,我同意,所以我投了更高的票。然而,我认为称之为错误有点过分。我们都是基于假设编写代码的,而我我想这可能没问题(或者至少以后可以通过一个简单的小改变来改变)。这种方法很有效,而且它为我省去了很多痛苦。例如,当根据状态指定一种自定义颜色时,它可以避免你创建一个巨大的如果/否则金字塔。例如,
if(isSelected&&isHighlighted)&(!isEnabled | isMyCustomState)
。我希望您能给我提供管理这种情况的其他策略的链接。我会自己选择。我在本页上没有看到任何策略能做到这一点。
const UIControlState UIControlStateOutlined = (1 << 16);

@interface OEButton ()
@property UIControlState customState;
@end

@implementation OEButton

- (void)setOutlined:(BOOL)outlined
{
    if (outlined)
    {
        self.customState |= UIControlStateOutlined;
    }
    else
    {
        self.customState &= ~UIControlStateOutlined;
    }
    [self stateWasUpdated];
}

- (BOOL)outlined
{
    return ( self.customState & UIControlStateOutlined ) == UIControlStateOutlined;
}

- (UIControlState)state {
    return [super state] | self.customState;
}

- (void)stateWasUpdated
{
    [self setNeedsLayout];
}

// These are only needed if you have additional code on -(void)stateWasUpdated
// - (void)setSelected:(BOOL)newSelected
// {
//     [super setSelected:newSelected];
//     [self stateWasUpdated];
// }
//
// - (void)setHighlighted:(BOOL)newHighlighted
// {
//     [super setHighlighted:newHighlighted];
//     [self stateWasUpdated];
// }
//
// - (void)setEnabled:(BOOL)newEnabled
// {
//     [super setEnabled:newEnabled];
//     [self stateWasUpdated];
// }

@end
extension UIControlState {
    static let myState = UIControlState(rawValue: 1 << 16)
}

class CustomControl: UIControl {

    private var _customState: UInt = 0

    override var state: UIControlState {
       return UIControlState(rawValue: super.state.rawValue | self._customState)
    }

    var isMyCustomState: Bool {
        get { 
            return self._customState & UIControlState.myState.rawValue == UIControlState.myState.rawValue 
        } set {
            if newValue == true {
                self._customState |= UIControlState.myState.rawValue
            } else {
                self._customState &= ~UIControlState.myState.rawValue
            }
        }
    }
}
extension UIControlState {
     static let myState = UIControlState(rawValue: 1 << 16)
} 

class MyControl: UIControl {

      override var state: UIControlState {
          var state = super.state
          if self.isMyCustomState {
               state.insert(UIControlState.myState)
          }
          return state
      }

      var isMyCustomState: Bool = false
 }