Могу ли я использовать пользовательские значения UIControlState для собственного контроля?
Есть ли способ установить пользовательские состояния - не одно из существующих значений UIControlState
- для UIControl
?
В перечислении UIControlSate
имеется 16 бит, которые могут использоваться для пользовательских состояний управления:
UIControlStateApplication = 0x00FF0000, // additional flags available for application use
Проблема заключается в том, что свойство UIControl
state
доступно только для чтения.
Я хочу установить разные фоновые изображения для своего UIButton
для пользовательских состояний.
Ответы
Ответ 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
}
}
}
}