禁用按钮循环(NStimer或MouseMove)XCode Objective-C MacOS

我只是尝试在XCode MacOS(不是iOS)可可Objective-C上使用各种方法来禁用按钮。

在这种情况下,我有一个帮助按钮(m_btHelp),当g_bEnableHelpButton = NO时,该按钮被禁用;但是只有在鼠标移动时才会被检查。

-(void)mouseMoved:(NSEvent *)theEvent
{
    
    if(g_bEnableHelpButton) {
        [m_btHelp setEnabled:YES];
    } else {
        [m_btHelp setEnabled:NO];
    }

我宁愿对此进行连续检查,而不是仅在鼠标移动时进行检查。我已经用类似的方法尝试过NSTimer,但是它似乎不起作用(当g_bEnableHelpButton = NO时,m_btHelp不会被禁用;就像在mouseMoved事件中那样:

- (void)applicationDidFinishlaunching:(Nsnotification *)aNotification
{
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(Timerloop) userInfo:nil repeats:YES];
}

- (void)Timerloop
{
     if(g_bEnableHelpButton) {
         [m_btHelp setEnabled:YES];
     } else {
         [m_btHelp setEnabled:NO];
     }
}
iCMS 回答:禁用按钮循环(NStimer或MouseMove)XCode Objective-C MacOS

g_bEnableHelpButton是全局变量,对吗?不要使用全局变量。最好创建一个保存状态的类(可以是视图模型,...)。我将在下面的所有示例中跳过状态类,并在同一视图控制器上使用BOOL helpButtonEnabled属性(这不是强制性的,它只是使所有这些示例都更短)。您可以将此属性移到其他位置,它可以是状态类,基本上可以是任何对象。

另一件事是NSTimerNSTrackingArea,...所有这些事情都在浪费CPU周期,电池寿命...... Cocoa和Objective-C提供了多种方法来监控属性值并对其做出反应。您可以覆盖属性设置器,可以使用KVO或绑定。下面的示例介绍了这三种方法。

还有其他确定方法(例如ReactiveCocoa),但我想展示三种方法来实现它而无需依赖。

初始状态

想象一下您有这种看法:

enter image description here

具有以下实现方式:

#import "ViewController.h"

@interface ViewController ()

// Help button from the Main.storyboard
// Imagine it's your m_btHelp
@property (nonatomic,strong) IBOutlet NSButton *helpButton;

// Property driving helpButton enabled/disabled state
// Imagine it's your g_bEnableHelpButton
@property (nonatomic,getter=isHelpButtonEnabled) BOOL helpButtonEnabled;

@end

@implementation ViewController

// Just another button action coming from the Main.storyboard which toggles
// our helpButtonEnabled property value
- (IBAction)toggleHelpButtonEnabled:(id)sender {
    self.helpButtonEnabled = !self.helpButtonEnabled;
}

@end

有一个帮助按钮和一个切换按钮,它们仅切换helpButtonEnabled值(YES-> NONO-> YES)。

如何在没有计时器,跟踪区域,...的情况下监视它,以更新帮助按钮的状态?

覆盖设置器

Encapsulating Data

@implementation ViewController

// This is setter for the helpButtonEnabled property.
- (void)setHelpButtonEnabled:(BOOL)helpButtonEnabled {
    // If the new value equals,do nothing
    if (helpButtonEnabled == _helpButtonEnabled) {
        return;
    }

    // Update instance variable
    _helpButtonEnabled = helpButtonEnabled;
    // Update button state
    _helpButton.enabled = helpButtonEnabled;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // When the view loads update button state to the initial value
    _helpButton.enabled = _helpButtonEnabled;
}

// Just another button action coming from the Main.storyboard which toggles
// our helpButtonEnabled property value
- (IBAction)toggleHelpButtonEnabled:(id)sender {
    self.helpButtonEnabled = !self.helpButtonEnabled;
}

@end

KVO

Introduction to Key-Value Observing Programming Guide

static void * const ViewControllerHelpButtonEnabledContext = (void*)&ViewControllerHelpButtonEnabledContext;

@implementation ViewController

- (void)dealloc {
    // Remove previously registered observer when the view controller goes away
    [self removeObserver:self forKeyPath:@"helpButtonEnabled" context:ViewControllerHelpButtonEnabledContext];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // Register observer for the helpButtonEnabled key path
    //  - it fires immeditately with the current value (NSKeyValueObservingOptionInitial)
    //  - it fires later every single time new value is assigned (NSKeyValueObservingOptionNew)
    //  - context is used to quickly distinguish why the observeValueForKeyPath:... was called
    [self addObserver:self
           forKeyPath:@"helpButtonEnabled"
              options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
              context:ViewControllerHelpButtonEnabledContext];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if (context == ViewControllerHelpButtonEnabledContext) {
        // It's our observer,let's update button state
        _helpButton.enabled = _helpButtonEnabled;
    } else {
        // It's not our observer,just forward it to super implementation
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

// Just another button action coming from the Main.storyboard which toggles
// our helpButtonEnabled property value
- (IBAction)toggleHelpButtonEnabled:(id)sender {
    self.helpButtonEnabled = !self.helpButtonEnabled;
}

@end

绑定

Introduction to Cocoa Bindings Programming Topics

@implementation ViewController

- (void)dealloc {
    // Remove binding when the view controller goes away
    [self.helpButton unbind:NSEnabledBinding];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // self.helpButton.enabled is binded to self.helpButtonEnabled
    [self.helpButton bind:NSEnabledBinding
                 toObject:self
              withKeyPath:@"helpButtonEnabled"
                  options:nil];
}

// Just another button action coming from the Main.storyboard which toggles
// our helpButtonEnabled property value
- (IBAction)toggleHelpButtonEnabled:(id)sender {
    self.helpButtonEnabled = !self.helpButtonEnabled;
}

@end
本文链接:https://www.f2er.com/2010688.html

大家都在问