Dou*_*ugW 20 iphone cocoa-touch objective-c key-value-observing uibutton
我正在扩展UIButton
通用功能,以根据显示的标题更改某些外观属性.
为此,我需要检测并响应"state"属性的变化.这样,如果用户为不同的状态设置了不同的标题,我确保正确调整外观.我以为我需要使用某种KVO,如下所示:
[self addObserver:self
forKeyPath:@"state"
options:NSKeyValueObservingOptionNew
context:nil];
Run Code Online (Sandbox Code Playgroud)
但这似乎没有触发@"state"或@"currentTitle"的observeValueForKeyPath:...方法.我假设这是因为UIButton没有为这些属性实现KVO模式.
我不想只听点击.这些事件导致状态改变,但不是唯一的潜在原因.
有没有人知道如何倾听和回应UIButton的状态变化?
谢谢
因为我在过去几年中学到了一些东西,所以只是一个注释;).
我已经和一些知道的苹果人谈过了,而且KVO没有在国家财产上工作的原因是因为UIKit的NONE肯定是符合KVO的.在这里值得重复的思考 - 如果你试图听取UIKit框架类的任何属性,请注意它可能有效,但是没有得到官方支持,可能会在不同的iOS版本上中断.
Dou*_*ugW 11
好吧,我找到了一个有效的解决方案.您可以收听按钮titleLabel的text属性.
[self.titleLabel addObserver:self
forKeyPath:@"text"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
Run Code Online (Sandbox Code Playgroud)
似乎每变化两次被炒鱿鱼,所以你应该检查,以确保@在通过改变字典中的值"老" @"新"是不同的.
注意:不要直接使用@"old"和@"new".常量分别是NSKeyValueChangeOldKey和NSKeyValueChangeNewKey.
我今天需要这个,所以我写了这个完成工作的课:
MyButton.h
#import <UIKit/UIKit.h>
// UIControlEventStateChanged uses the first bit from the UIControlEventApplicationReserved group
#define UIControlEventStateChanged (1 << 24)
@interface MyButton : UIButton
@end
Run Code Online (Sandbox Code Playgroud)
MyButton.m
#import "MyButton.h"
#pragma mark - Private interface
@interface MyButton ()
- (void)checkStateChangedAndSendActions;
@end
#pragma mark - Main class
@implementation MyButton
{
// Prior state is used to compare the state before
// and after calls that are likely to change the
// state. It is an ivar rather than a local in each
// method so that if one of the methods calls another,
// the state-changed actions only get called once.
UIControlState _priorState;
}
- (void)setEnabled:(BOOL)enabled
{
_priorState = self.state;
[super setEnabled:enabled];
[self checkStateChangedAndSendActions];
}
- (void)setSelected:(BOOL)selected
{
_priorState = self.state;
[super setSelected:selected];
[self checkStateChangedAndSendActions];
}
- (void)setHighlighted:(BOOL)highlighted
{
_priorState = self.state;
[super setHighlighted:highlighted];
[self checkStateChangedAndSendActions];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
_priorState = self.state;
[super touchesBegan:touches withEvent:event];
[self checkStateChangedAndSendActions];
}
- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
_priorState = self.state;
[super touchesMoved:touches withEvent:event];
[self checkStateChangedAndSendActions];
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
_priorState = self.state;
[super touchesEnded:touches withEvent:event];
[self checkStateChangedAndSendActions];
}
- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event
{
_priorState = self.state;
[super touchesCancelled:touches withEvent:event];
[self checkStateChangedAndSendActions];
}
#pragma mark - Private interface implementation
- (void)checkStateChangedAndSendActions
{
if(self.state != _priorState)
{
_priorState = self.state;
[self sendActionsForControlEvents:UIControlEventStateChanged];
}
}
@end
Run Code Online (Sandbox Code Playgroud)
您可以使用UIButton
init
方法以编程方式创建它,或者通过向UIButton
视图添加法线并将类更改为MyButton
,从Interface Builder中使用它,但您必须以UIControlEventStateChanged
编程方式侦听事件.例如,viewDidLoad
在您的控制器类中,如下所示:
[self.myButton addTarget:self
action:@selector(myButtonStateChanged:)
forControlEvents:UIControlEventStateChanged];
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
21120 次 |
最近记录: |