无法更改辅助 window 面板中的标签

Can't change labels in secondary window panel

我有一个辅助 window(面板),带有一个按钮和一个包含一些标签的框。我需要能够更改框标题和标签文本,但只能在 AwakeFromNIB 中这样做。如果我在 WindowDidLoad 中检查标签的文本,它是零。 Init 正在触发 3 次。

//  ExtendedCal.h
#import <Cocoa/Cocoa.h>
@interface ExtendedCal : NSWindowController
@property (retain) IBOutlet NSTextField *lblCCW;
@property (retain) IBOutlet NSTextField *lblCW;
@property (nonatomic, retain) IBOutlet NSTextField *lblDegrees;
@property (nonatomic, retain) IBOutlet NSBox *boxExtCal;
@property (nonatomic, retain) IBOutlet NSButton *btnOK;
@property (nonatomic, retain) NSString *maxSteps;
@property (nonatomic) NSInteger arrayCtr;
@property (nonatomic) NSInteger steps;

- (IBAction)btnOKClicked:(id)sender;
- (void)resetUI;
@end

//  ExtendedCal.m
#import "ExtendedCal.h"
NSString * const myExtendedCalChangedNotification = @"MyExtCalKey";
NSString *const myExtendedCalEndedNotification = @"myExtCalEndedKey";
NSMutableArray *pointArray;
NSInteger extCalStep;
NSInteger extCalAxis;
NSInteger extCalMin;
NSInteger extCalMax;

/*
@interface ExtendedCal ()
@end
*/

@implementation ExtendedCal

@synthesize lblDegrees;
@synthesize lblCCW;
@synthesize lblCW;
@synthesize btnOK;
@synthesize boxExtCal;
@synthesize maxSteps;
@synthesize arrayCtr;
@synthesize steps;

- (id)init
{
      self = [super initWithWindowNibName:@"ExtendedCal"];
      return self;      
}

- (void)windowWillLoad
{
    [lblDegrees setStringValue:@"MMM"]; /// does nothing
}
- (void)windowDidLoad
{
    [super windowDidLoad];
    NSInteger var1, ec, tmpI = 0;
    steps = 0;
    [self resetUI];  //does nothing when called from here
    maxSteps = @"16";
    ec = 0;
    pointArray = [NSMutableArray array];
    var1 = 0;       
    while (var1 <= extCalStep*25)
    {
        if (extCalMin == var1)
        {
            ec = 1;
            [pointArray addObject:[NSNumber numberWithInteger:var1]];
        }
        var1 = var1 + extCalStep;
    }
    if(ec==0)
    {
        ec = 1;
        [pointArray addObject:[NSNumber numberWithInteger:extCalMin]];
    }
    var1 = extCalStep;
    tmpI = [pointArray count];
    while (var1 < extCalMax)
    {
        if (var1 > [[pointArray objectAtIndex:ec - 1]integerValue])
        {
            ec +=1;
            [pointArray addObject:[NSNumber numberWithInteger:var1]];
        }
        var1 += extCalStep;
    }
    if(extCalMax > [[pointArray objectAtIndex:ec-1]integerValue])
    {
        ec +=1;
        [pointArray addObject:[NSNumber numberWithInteger:extCalMax]];
    }
    tmpI = [pointArray count];
    arrayCtr = 0;
    NSString *str = [[pointArray objectAtIndex:0]stringValue];

    [lblDegrees setStringValue:str];           //does nothing
    NSString *s2 = [lblDegrees stringValue];   //s2 is nil
}

- (void)awakeFromNib
{
    [lblDegrees setStringValue:@"888"];  //works from here
    [self resetUI];                      //works from here
}

- (void)btnOKClicked:(id)sender
{
    extCalStep +=1;
    NSMutableString *tmp;
    NSString *option = @"160";
    tmp = [NSMutableString string];
    [tmp setString:@"Calibration-step "];
    [tmp appendFormat:@"%ld",extCalStep];
    [tmp appendString:@" of "];
    [tmp appendString:maxSteps];
    [boxExtCal setTitle:tmp];         //does nothing
    option = [[pointArray objectAtIndex:arrayCtr] stringValue];
    option = [NSString stringWithFormat:@"0%ld", extCalStep];
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
    NSDictionary *userInfo = [NSDictionary 
                 dictionaryWithObject:optionforKey:@"myExtCalKey"];
    [nc postNotificationName:myExtendedCalChangedNotification
                                        object:self
                                userInfo:userInfo];
    steps++;    
}

- (void)resetUI
{
    NSMutableString *boxStr = [[NSMutableString alloc] init];
    [boxExtCal setTitle:@"Calibration step 1 of 16"];
    lblCW.hidden = NO;
    lblCCW.hidden = YES;
    [boxStr setString:@""];
    [boxStr appendString:@"999"];
    //[boxStr appendString:@"\u00B0"];
    [lblDegrees setStringValue:boxStr];
    steps = 0;
}

布线

window被

打开
//  ORSSerialPortDemoController.m

#import "Calibrate.h"
#import "ExtendedCal.h"

Calibrate *calibrate;
ExtendedCal *extCal;
@interface ORSSerialPortDemoController () {
}   
@end
.
.
.
[extendedcal showWindow:self]; 

将所有出口从 Extended Cal 更改为 File's Owner,window 除外。

我认为您的问题是您有两个 window 控制器实例 class、ExtendedCal。您正在通过分配和初始化 class 在代码中创建一个。我怀疑你也在 NIB 本身中实例化了一个。您在自己的回答中几乎证实了这一点,您在 NIB 中提到了 Extended Cal。

在代码中创建的实例是加载 NIB 的实例。当您的 -init 方法调用 super 的 -initWithWindowNibName: 方法时,它会获取传递给它的 NIB 名称。它在第一次请求 window 属性 时加载 NIB,这隐含在对 -showWindow:.

的调用中

NSWindowController(或子class)加载NIB 时,它会将自己传递为所有者。因此,NIB 中的文件所有者占位符解析为该对象。此外,在该实例上调用了 -windowDidLoad 方法。

由于您的 NIB 包含 ExtendedCal 的另一个实例,因此在加载 NIB 时也会创建该实例。但是,它不是 NIB 的所有者,也没有加载 NIB。所以,它的 -windowDidLoad 方法没有被调用。并且与它的任何连接(插座、绑定等)都不会连接到第一个实例。

这两个实例具有不同的角色,其中一个调用了特定的方法,另一个具有各种重要的联系,这是混淆的根源。

您说得对,更改此类连接以连接到文件所有者是解决方案的一部分。其余的解决方案是简单地从 NIB 中完全删除 ExtendedCal 的实例。它不应该在那里。 window 控制器在笔尖之外。它是在加载 NIB 之前创建的,实际上是加载 NIB 的内容。因此,不应在 NIB 中对其进行实例化。

为了进一步讨论,我推荐这篇文章:https://www.mikeash.com/pyblog/friday-qa-2013-04-05-windows-and-window-controllers.html


哦,还有一些事情:

调用 -windowWillLoad 时未加载笔尖。因此,还没有连接任何网点,并且 lblDegrees 应该是 nil.

我建议避免在 window 控制器上实施 -awakeFromNib-windowDidLoad 是更好的选择。 -awakeFromNib 的问题在于它在某些情况下可以被多次调用(例如,如果您的 window 控制器是基于视图的 table 视图的委托)。 -windowDidLoad 的语义和时间更简单。