首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何侦听UIButton状态更改?

如何侦听UIButton状态更改?
EN

Stack Overflow用户
提问于 2010-03-24 05:21:29
回答 4查看 24.3K关注 0票数 24

我正在使用通用功能扩展UIButton,以根据显示的标题更改某些外观属性。

为此,我需要检测并响应"state“属性中的更改。这是为了确保如果用户为不同的状态设置了不同的标题,则可以适当地调整外观。我假设我需要使用某种KVO,如下所示:

代码语言:javascript
复制
[self addObserver:self 
       forKeyPath:@"state" 
          options:NSKeyValueObservingOptionNew 
          context:nil];

但这似乎不会触发observeValueForKeyPath:...@“状态”或@"currentTitle“的方法。我认为这是因为UIButton没有为这些属性实现KVO模式。

我不想只听点击。这些事件会导致状态更改,但不是唯一的潜在原因。

有没有人知道如何监听和响应UIButton的状态变化?

谢谢

更新

由于我在过去的几年中学到了一些东西,所以只是一个注释;)。

自那以后,我与一些苹果人交谈过,他们知道,KVO在国家财产上不起作用的原因是,UIKit的NONE被保证是符合KVO的。如果您正在尝试侦听UIKit框架类的任何属性,请注意它可能会工作,但不是官方支持的,并且可能会在不同的iOS版本上崩溃。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-03-24 05:58:29

好了,我想出了一个可行的解决方案。您可以监听按钮titleLabel的text属性。

代码语言:javascript
复制
[self.titleLabel addObserver:self 
                  forKeyPath:@"text" 
                     options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld 
                     context:nil];

它似乎每次更改都会被触发两次,因此您应该检查以确保所传递的更改字典中的@"old“和@"new”的值不同。

注意:不要直接使用@"old“和@"new”。常量分别为NSKeyValueChangeOldKey和NSKeyValueChangeNewKey。

票数 11
EN

Stack Overflow用户

发布于 2012-06-23 06:08:59

我今天需要这个,所以我写了这个类来做这项工作:

MyButton.h

代码语言:javascript
复制
#import <UIKit/UIKit.h>

// UIControlEventStateChanged uses the first bit from the UIControlEventApplicationReserved group
#define UIControlEventStateChanged  (1 << 24)

@interface MyButton : UIButton
@end

MyButton.m

代码语言:javascript
复制
#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,如下所示:

代码语言:javascript
复制
[self.myButton addTarget:self 
                  action:@selector(myButtonStateChanged:) 
        forControlEvents:UIControlEventStateChanged];
票数 9
EN

Stack Overflow用户

发布于 2013-12-06 01:53:55

代码语言:javascript
复制
[self addObserver:self 
       forKeyPath:@"state" 
          options:NSKeyValueObservingOptionNew 
          context:nil];

如果您检查观察者内部的“selected”属性,则工作正常

代码语言:javascript
复制
-(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];
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2503721

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档