Подтвердить что ты не робот

Могу ли я использовать пользовательские значения UIControlState для собственного контроля?

Есть ли способ установить пользовательские состояния - не одно из существующих значений UIControlState - для UIControl?

В перечислении UIControlSate имеется 16 бит, которые могут использоваться для пользовательских состояний управления:

UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use

Проблема заключается в том, что свойство UIControl state доступно только для чтения.

Я хочу установить разные фоновые изображения для своего UIButton для пользовательских состояний.

4b9b3361

Ответ 1

Вы можете использовать пользовательские состояния в подклассе UIControl.

  • Создайте переменную с именем customState, в которой вы будете управлять своими пользовательскими состояниями.
  • Если вам нужно установить состояние, выполните действия с флагом против этой переменной и вызовите [self stateWasUpdated].
  • Отмените свойство state, чтобы вернуть [super state] побитовое ИЛИ против вашего customState
  • Отмените настройки enabled, selected и highlighted, чтобы они вызывали [self stateWasUpdated]. Это позволит вам реагировать на любые изменения состояния, а не просто на customState
  • Внедрить stateWasUpdated с логикой для реагирования на изменения состояния

В заголовке:

#define kUIControlStateCustomState (1 << 16)

@interface MyControl : UIControl {
    UIControlState customState;
}

В реализации:

@implementation MyControl

-(void)setCustomState {
    customState |= kUIControlStateCustomState;
    [self stateWasUpdated];
}

-(void)unsetCustomState {
    customState &= ~kUIControlStateCustomState;
    [self stateWasUpdated];
}

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

- (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];
}

- (void)stateWasUpdated {
    // Add your custom code here to respond to the change in state
}

@end

Ответ 2

Основываясь на ответе @Nick, я реализовал более простую версию. Этот подкласс предоставляет свойство BOOL outlined, которое аналогично функции selected, highlighted и enabled.

Выполнение таких действий, как [customButtton setImage:[UIImage imageNamed:@"MyOutlinedButton.png"] forState:UIControlStateOutlined], автоматически работает при обновлении свойства outlined.

При необходимости может быть добавлено больше этих свойств state +.


UICustomButton.h

extern const UIControlState UIControlStateOutlined;

@interface UICustomButton : UIButton
@property (nonatomic) BOOL outlined;
@end

UICustomButton.m

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

Ответ 3

Свифт 3 версии Nick отвечает:

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
            }
        }
    }
}