我正在使用通用功能扩展UIButton
,以根据显示的标题更改某些外观属性。
为此,我需要检测并响应"state“属性中的更改。这是为了确保如果用户为不同的状态设置了不同的标题,则可以适当地调整外观。我假设我需要使用某种KVO,如下所示:
[self addObserver:self
forKeyPath:@"state"
options:NSKeyValueObservingOptionNew
context:nil];
但这似乎不会触发observeValueForKeyPath:...@“状态”或@"currentTitle“的方法。我认为这是因为UIButton没有为这些属性实现KVO模式。
我不想只听点击。这些事件会导致状态更改,但不是唯一的潜在原因。
有没有人知道如何监听和响应UIButton的状态变化?
谢谢
更新
由于我在过去的几年中学到了一些东西,所以只是一个注释;)。
自那以后,我与一些苹果人交谈过,他们知道,KVO在国家财产上不起作用的原因是,UIKit的NONE被保证是符合KVO的。如果您正在尝试侦听UIKit框架类的任何属性,请注意它可能会工作,但不是官方支持的,并且可能会在不同的iOS版本上崩溃。
发布于 2010-03-24 05:58:29
好了,我想出了一个可行的解决方案。您可以监听按钮titleLabel的text属性。
[self.titleLabel addObserver:self
forKeyPath:@"text"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:nil];
它似乎每次更改都会被触发两次,因此您应该检查以确保所传递的更改字典中的@"old“和@"new”的值不同。
注意:不要直接使用@"old“和@"new”。常量分别为NSKeyValueChangeOldKey和NSKeyValueChangeNewKey。
发布于 2012-06-23 06:08:59
我今天需要这个,所以我写了这个类来做这项工作:
MyButton.h
#import <UIKit/UIKit.h>
// UIControlEventStateChanged uses the first bit from the UIControlEventApplicationReserved group
#define UIControlEventStateChanged (1 << 24)
@interface MyButton : UIButton
@end
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
您可以使用UIButton
init
方法以编程方式创建它,也可以通过将普通UIButton
添加到视图并将类更改为MyButton
来从接口生成器中使用它,但您必须以编程方式侦听UIControlEventStateChanged
事件。例如来自控制器类中的viewDidLoad
,如下所示:
[self.myButton addTarget:self
action:@selector(myButtonStateChanged:)
forControlEvents:UIControlEventStateChanged];
发布于 2013-12-06 01:53:55
[self addObserver:self
forKeyPath:@"state"
options:NSKeyValueObservingOptionNew
context:nil];
如果您检查观察者内部的“selected”属性,则工作正常
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqualToString:@"selected"])
{
[self.img setImage:self.selected ? self.activeImg : self.inactiveImg];
}
else
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
https://stackoverflow.com/questions/2503721
复制相似问题