未调用 IBAction,但 UI 正在更新?

Posted

技术标签:

【中文标题】未调用 IBAction,但 UI 正在更新?【英文标题】:IBAction not being called, but UI is updating? 【发布时间】:2014-02-11 20:04:57 【问题描述】:

所以问题是我没有编写代码,只是尝试编辑一些代码。它是属于某个电气 I/O 板的代码,它是工厂系统的输入/输出控制板,由各种 ios 设备运行。

我似乎不太明白以前的编码员在这个课程中做了什么:

    //

//  AnalogVC.m 
//



#import "AnalogVC.h"

#import "AppDelegate.h"



@interface InputItem : NSObject

@property (weak,nonatomic) UISwitch *onSwitch;

@property (weak,nonatomic) UIProgressView *progressView;

@property (weak,nonatomic) UILabel *valueLabel;

@end



@implementation InputItem

AppDelegate *appDelegate;

+ (id)itemWithSwitch:(id)temp progress:(id)progress label:(id)label




    InputItem *item = [[InputItem alloc] init];

    item.onSwitch = temp;

    item.progressView = progress;

    item.valueLabel = label;

    return item;





- (void)setDisconnected




    self.onSwitch.on = NO;

    self.onSwitch.enabled = NO;

    self.valueLabel.text = @"0.000 v";

    self.progressView.progress = 0;







- (void)setOn





self.onSwitch.on = YES;

    self.onSwitch.enabled = YES;

    self.valueLabel.text = @"0.000 v";

    self.progressView.progress = 0;

[appDelegate watchPins:@"testing ON"];





- (void)setOff




    self.onSwitch.on = NO;

    self.onSwitch.enabled = YES;

    self.valueLabel.text = @"0.000 v";

    self.progressView.progress = 0;

[appDelegate watchPins:@"testing OFF"];





- (void)setValue:(double)value



    if (self.onSwitch.on)

    

        self.valueLabel.text = [NSString stringWithFormat:@"%0.3f v",value];

        self.progressView.progress = value/5.0;

if(value > 0.8)

[appDelegate watchPins:@"testing VALUE"];



    



@end



@interface AnalogVC ()




    NSArray *_inputItems;

    AppDelegate *appDelegate;

    NSMutableArray *channel0Values;



    UIColor *custom1;

    UIColor *custom2;

    UIColor *custom3;

    UIColor *custom4;





@property (nonatomic) NCBoardManager *manager;



@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch0;

@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch1;

@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch2;

@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch3;

@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch4;

@property (weak,nonatomic) IBOutlet UISwitch *inputSwitch5;



@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress0;

@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress1;

@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress2;

@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress3;

@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress4;

@property (weak,nonatomic) IBOutlet UIProgressView *inputProgress5;



@property (weak,nonatomic) IBOutlet UILabel *inputValue0;

@property (weak,nonatomic) IBOutlet UILabel *inputValue1;

@property (weak,nonatomic) IBOutlet UILabel *inputValue2;

@property (weak,nonatomic) IBOutlet UILabel *inputValue3;

@property (weak,nonatomic) IBOutlet UILabel *inputValue4;

@property (weak,nonatomic) IBOutlet UILabel *inputValue5;



@property (weak,nonatomic) IBOutlet UISlider *outputSlider0;

@property (weak,nonatomic) IBOutlet UISlider *outputSlider1;



@property (weak,nonatomic) IBOutlet UIStepper *outputStepper0;

@property (weak,nonatomic) IBOutlet UIStepper *outputStepper1;



@property (weak,nonatomic) IBOutlet UILabel *outputValue0;

@property (weak,nonatomic) IBOutlet UILabel *outputValue1;





- (IBAction)inputChannelChanged:(UISwitch *)sender;

- (IBAction)outputSliderMoved:(UISlider *)sender;

- (IBAction)outputSliderStopped:(UISlider *)sender;

- (IBAction)outputStepperChanged:(UIStepper *)sender;

@end



@implementation AnalogVC





//////////////////////////////

#pragma mark View Lifecycle

//////////////////////////////





- (void)viewDidLoad



    [super viewDidLoad];

        NSLog(@"Analog VC loaded");

    _inputItems = @[[InputItem itemWithSwitch:_inputSwitch0 progress:_inputProgress0 label:_inputValue0],

                    [InputItem itemWithSwitch:_inputSwitch1 progress:_inputProgress1 label:_inputValue1],

                    [InputItem itemWithSwitch:_inputSwitch2 progress:_inputProgress2 label:_inputValue2],

                    [InputItem itemWithSwitch:_inputSwitch3 progress:_inputProgress3 label:_inputValue3],

                    [InputItem itemWithSwitch:_inputSwitch4 progress:_inputProgress4 label:_inputValue4],

                    [InputItem itemWithSwitch:_inputSwitch5 progress:_inputProgress5 label:_inputValue5]];



    _manager = [NCBoardManager sharedBoardManager];



    __unsafe_unretained AnalogVC *vc = self;

    [_manager setAnalogInputHandling:dispatch_get_main_queue()

                              filter:^(NCAnalogInputs *inputs) return YES; 

                             handler:^(NCAnalogInputs *inputs) [vc setAnalogInputs:inputs]; ];





    //  Register for notifications

    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(boardConnected:)

                                                 name:CONNECTED_NOTIFICATION

                                               object:nil];



    [[NSNotificationCenter defaultCenter] addObserver:self

                                             selector:@selector(boardDisconnected:)

                                                 name:DISCONNECTED_NOTIFICATION

                                               object:nil];





- (void)viewWillAppear:(BOOL)animated



    [super viewWillAppear:animated];

    [self updateAnalogInputs];

    [self updateAnalogOutputs];



    custom1 = [UIColor whiteColor];

    custom2 = [UIColor darkGrayColor];

    custom3 = [UIColor blackColor];

    custom4 = [UIColor colorWithRed:.97 green:.97 blue:.588 alpha:1.0];



    CAGradientLayer *gradient = [CAGradientLayer layer];

    gradient.frame = self.view.bounds;

    gradient.colors = [NSArray arrayWithObjects:(id)[custom2 CGColor], (id)[custom1 CGColor], (id)[custom2 CGColor], nil];

    gradient.startPoint = CGPointMake(0.5, 0);

    gradient.endPoint = CGPointMake(0.5, 1.0);

    gradient.locations = [NSArray arrayWithObjects: [NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:0.5], [NSNumber numberWithFloat:1.0], nil];

    [self.view.layer insertSublayer:gradient atIndex:0];



    [self.inputSwitch0 setOnTintColor:custom4];

    [self.inputSwitch1 setOnTintColor:custom4];

    [self.inputSwitch2 setOnTintColor:custom4];

    [self.inputSwitch3 setOnTintColor:custom4];

    [self.inputSwitch4 setOnTintColor:custom4];

    [self.inputSwitch5 setOnTintColor:custom4];



    [self.inputSwitch0 setTintColor:custom3];

    [self.inputSwitch1 setTintColor:custom3];

    [self.inputSwitch2 setTintColor:custom3];

    [self.inputSwitch3 setTintColor:custom3];

    [self.inputSwitch4 setTintColor:custom3];

    [self.inputSwitch5 setTintColor:custom3];



    self.inputProgress0.trackTintColor = custom3;

    self.inputProgress1.trackTintColor = custom3;

    self.inputProgress2.trackTintColor = custom3;

    self.inputProgress3.trackTintColor = custom3;

    self.inputProgress4.trackTintColor = custom3;

    self.inputProgress5.trackTintColor = custom3;



    self.inputProgress0.progressTintColor = custom4;

    self.inputProgress1.progressTintColor = custom4;

    self.inputProgress2.progressTintColor = custom4;

    self.inputProgress3.progressTintColor = custom4;

    self.inputProgress4.progressTintColor = custom4;

    self.inputProgress5.progressTintColor = custom4;



    self.outputSlider0.minimumTrackTintColor = custom4;

    self.outputSlider1.minimumTrackTintColor = custom4;

    self.outputSlider0.maximumTrackTintColor = custom3;

    self.outputSlider1.maximumTrackTintColor = custom3;



    self.outputSlider0.thumbTintColor = custom3;

    self.outputSlider1.thumbTintColor = custom3;



    if(_manager.isBoardConnected)

    

        self.outputStepper0.tintColor = custom4;

        self.outputStepper1.tintColor = custom4;

        self.outputStepper0.enabled = TRUE;

        self.outputStepper1.enabled = TRUE;

        self.outputSlider0.enabled = TRUE;

        self.outputSlider1.enabled = TRUE;

    

    else

    

        self.outputStepper0.tintColor = custom2;

        self.outputStepper1.tintColor = custom2;

        self.outputStepper0.enabled = FALSE;

        self.outputStepper1.enabled = FALSE;

        self.outputSlider0.enabled = FALSE;

        self.outputSlider1.enabled = FALSE;

    







//////////////////////////////

#pragma mark Rotation Calls

//////////////////////////////





- (NSUInteger)supportedInterfaceOrientations



    return UIInterfaceOrientationPortrait;





- (BOOL)shouldAutorotate



    return FALSE;







//////////////////////////

#pragma mark Board Calls

//////////////////////////





- (void)boardConnected:(NSNotification *)notification



    [self updateAnalogInputs];

    [self updateAnalogOutputs];



    self.outputStepper0.enabled = TRUE;

    self.outputStepper1.enabled = TRUE;

    self.outputSlider0.enabled = TRUE;

    self.outputSlider1.enabled = TRUE;



    self.outputStepper0.tintColor = custom4;

    self.outputStepper1.tintColor = custom4;





- (void)boardDisconnected:(NSNotification *)notification



    [self updateAnalogInputs];

    [self updateAnalogOutputs];



    self.outputStepper0.enabled = FALSE;

    self.outputStepper1.enabled = FALSE;

    self.outputSlider0.enabled = FALSE;

    self.outputSlider1.enabled = FALSE;



    self.outputStepper0.tintColor = custom2;

    self.outputStepper1.tintColor = custom2;





- (void)updateAnalogInputs




    uint8_t channel = self.manager.analogInputChannels;

    switch (self.manager.analogInputStatus)

    

        case NCInputConnected:

            //  Check if channels we left on

            if (channel) self.manager.analogInputChannels = 0;

            [_inputItems makeObjectsPerformSelector:@selector(setOff)];

            break;

        case NCInputDisconnected:

            [_inputItems makeObjectsPerformSelector:@selector(setDisconnected)];

            break;

        case NCInputLiveUpdating:

            for (InputItem *item in _inputItems)

            

                //if (channel & 1) [item setOn];

                //else             [item setOff];

                channel >>= 1;

            

            break;

        case NCInputSampling:

            [_inputItems makeObjectsPerformSelector:@selector(setDisconnected)];

            break;

        case NCInputTransfering:

            [_inputItems makeObjectsPerformSelector:@selector(setDisconnected)];

            break;

    









- (void)setAnalogInputs:(NCAnalogInputs *)inputs




    int i = 0;

    uint8_t channels = inputs.channels;

    for (InputItem *item in _inputItems)

    

        if (channels & 1)

        

            [item setValue:[inputs valueForChannel:i]];


        

        channels >>= 1;

        i++;

    





- (void)updateAnalogOutputs



    BOOL connected = [self.manager isBoardConnected];



    self.outputSlider0.value = self.manager.analogOutput0;

    self.outputSlider0.enabled = connected;

    self.outputStepper0.value = self.outputSlider0.value * 1000;

    self.outputStepper0.enabled = connected;

    self.outputValue0.text = [NSString stringWithFormat:@"%0.3f v",self.outputSlider0.value];



    self.outputSlider1.value = self.manager.analogOutput1;

    self.outputSlider1.enabled = connected;

    self.outputStepper1.value = self.outputSlider1.value * 1000;

    self.outputStepper1.enabled = connected;

    self.outputValue1.text = [NSString stringWithFormat:@"%0.3f v",self.outputSlider1.value];







///////////////////////////////

#pragma mark IBAction Methods

///////////////////////////////



- (IBAction)inputChannelChanged:(UISwitch *)sender



NSLog(@"TEST");

InputItem *item = [_inputItems objectAtIndex:sender.tag];

    uint8_t channels = self.manager.analogInputChannels;

    if (sender.on)

    

        channels  |= (1 << sender.tag);

        [item setOn];



    

    else

    

        channels &= ~(1 << sender.tag);

        [item setOff];

    

    if (!self.manager.analogInputChannels) [self.manager startAnalogLiveUpdating];

    else if(!channels) [self.manager stopAnalogLiveUpdating];



    self.manager.analogInputChannels = channels;





- (IBAction)outputSliderMoved:(UISlider *)sender



    if (!sender.tag)

    

        self.manager.analogOutput0 = sender.value;

        self.outputValue0.text = [NSString stringWithFormat:@"%0.3f v",sender.value];

    

    else

    

        self.manager.analogOutput1 = sender.value;

        self.outputValue1.text = [NSString stringWithFormat:@"%0.3f v",sender.value];

    





- (IBAction)outputSliderStopped:(UISlider *)sender



    if (!sender.tag)

    

        self.manager.analogOutput0 = sender.value;

        self.outputStepper0.value = round(sender.value * 1000.0);

        self.outputValue0.text = [NSString stringWithFormat:@"%0.3f v",self.outputStepper0.value/1000.0];

    

    else

    

        self.manager.analogOutput1 = sender.value;

        self.outputStepper1.value = round(sender.value * 1000.0);

        self.outputValue1.text = [NSString stringWithFormat:@"%0.3f v",self.outputStepper1.value/1000.0];

    





- (IBAction)outputStepperChanged:(UIStepper *)sender



    float value = sender.value/1000.0;



    if (!sender.tag)

    

        self.manager.analogOutput0 = value;

        self.outputSlider0.value = value;

        self.outputValue0.text = [NSString stringWithFormat:@"%0.3f v",value];

    

    else

    

        self.manager.analogOutput1 = sender.value/1000.0;

        self.outputSlider1.value = value;

        self.outputValue1.text = [NSString stringWithFormat:@"%0.3f v",value];

    





@end

我遇到的问题是我无法弄清楚如何从情节提要上的 UIProgressViews 获取值(就像你说的那样,这是一个微不足道的概念)。然而,这种设置是相当复杂的。

第二个问题是;我不确定是否有办法调试它,因为应用程序仅在外部设备(nanospark 控制器板)连接到 iPod 时运行。

我遇到的最后一个也是最后一个问题是我假设正在调用 IBAction InputChannelChanged(不能使用上述断点定期调试它,因为它需要外部设备来运行应用程序),但是当我运行应用程序时它做了它应该做的一切,并且按钮对原始软件开发人员的编码做出正确的反应。

这意味着,如果我将我的发短信方法添加到 IBAction(通过添加 [appDelegate watchPins@"TEST"]),它不会将文本发送给用户,但按钮仍然会执行它们应该按照一致性执行的操作对以前的开发人员的愿望....这意味着确实正在调用 IBAction 方法...但是为什么我的文本没有通过呢?我知道 [appDelegate watchPins:@"TEST"];应该像我在他的其他几个课程中使用过的那样工作。

这是显示 AnalogVC.m 的 UI 的屏幕截图:

http://i.stack.imgur.com/NNpZk.png

不必回答所有这些问题,只是我觉得有必要提供所有三个问题以更好地了解问题的背景。感谢和抱歉 TL;DR。

我会上传图片,但我没有所需的最低声望。

我尝试添加另一个 IBAction 只是为了查看按钮是否对此做出反应;即使我从其他工作类中复制了确切的代码,仍然一无所获。

【问题讨论】:

【参考方案1】:

通常的规则是在 IB (Interface Builder) 中检查您的出口和操作。通常情况下,它是一个断开的链接。

如果不是这样,您将需要找到一种调试方法。如果原始开发者没有办法模拟专用硬件,他们是如何编写应用程序的?

SO 上的读者不可能知道是什么阻止了应用程序正常运行。

一种选择是将日志语句添加到您的 IBAction 方法中,在现场运行开发构建程序,然后将 iPad 连接到 Xcode 并查看控制台日志以查看日志语句的输出。

顺便说一句,您发布了数百行代码,其中大部分是 Xcode 添加的样板代码,其余大部分与您要解决的问题无关。减少您发布到相关部分的代码是个好主意,这样您的读者就可以了解重要的内容。否则,他们可能会失去耐心,因为滚动浏览大量不相关的代码以试图找到与您的帖子相关的部分。

【讨论】:

我随身携带硬件。对不起,我也会简明代码。我将尝试日志并在完成时进行编辑。我添加这么多内容的原因甚至是我自己在课堂上跋涉,我无法真正理解它,并认为整个课堂对于其他人的清晰理解都是必要的。 嗯...如果您,在 Xcode 中拥有该项目的人,无法分辨哪些类与您遇到的问题相关,那么那些阅读您粘贴的代码的人不太可能将能够说出问题的原因。 我从未说过我无法理解与问题相关或不相关的内容,不需要态度;我们在这里是成年人。我意识到它的代码有点多,但我有我的理由认为这对于有更多经验的人来说是有用的,可以看到在哪里声明了东西或者实现和方法之间是如何通信的。我显然接受了您的建议,并且会在未来改进帖子 讽刺和讽刺的语气并不是真正必要的。

以上是关于未调用 IBAction,但 UI 正在更新?的主要内容,如果未能解决你的问题,请参考以下文章

IBAction 方法未在 viewDidLoad 方法中调用?

在 Mac Catalyst 项目中未调用 IBAction

在代码中调用 IBAction 并发送标签

为啥使用@IBAction func时UI没有及时更新?

为啥将 IB Action 设置为作为对象退出?

调用 prepareForSegue 而不是 ib 按钮