【问题标题】:Calling SetNeedsDisplay from other class从其他类调用 SetNeedsDisplay
【发布时间】:2013-09-25 22:32:24
【问题描述】:

今天我面临一个新问题:

我有一个 ViewController(NSView 的子类)和另一个类(NSObject 的子类),它们通过 IBAction 尝试回调 viewController 以使用 SetNeedsDisplay:YES 重绘其视图。

重绘视图(ViewController.m)的方法是:

- (void) redrawView {
[self setNeedsDisplay:YES] 
} 
// With an NSLog i see that the method is called !
// Instead of self i tried even an outlet connected to the custom view.

}

我正在通过我的其他类调用 ViewController 方法是:

1)#import "ViewController.h"

2) 在 IBAction 中,我创建了一个新的 ViewController 实例:

ViewController *newIstanceOfViewController = [[ViewController alloc] init]

3)[newIstanceOfViewController redrawView]

日志显示 setNeedsDisplay 被调用但 drawrect 没有!为什么 ?我忘记了初始化或子视图?谢谢


这里的原始代码(由于语言不同,方法名称不同,语法相同)

    //  Controller.h

#import <Cocoa/Cocoa.h>

@interface Controller : NSView {
    IBOutlet NSView *tastierinoView;
}
- (void) aggiornaTastierinoView;

@end


//  Controller.m

#import "Controller.h"

@implementation Controller

//Contatore numero volte disegno view
int contatore = 0;

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
        tastierinoView = [[NSView alloc] init];

    }
    return self;
}

- (void) aggiornaTastierinoView { //THIS IS THE METHOD TO CALL REDRAW
    [tastierinoView setNeedsDisplay:YES];
    NSLog(@"Chiamo setneedsDisplay\n\n");
}

- (void)drawRect:(NSRect)dirtyRect
{
    contatore++;
    NSLog(@"La view è stata disegnata %d volte\n\n",contatore);
    [super drawRect:dirtyRect];

    // Drawing code here.
    NSBezierPath* percorso = [NSBezierPath bezierPath];
    [[NSColor cyanColor] set];

    [percorso moveToPoint:NSMakePoint(150, 150)];
    [percorso lineToPoint:NSMakePoint(250, 150)];

    [percorso setLineWidth:5.0];
    [percorso stroke];

}

@end

//  ManipolatorePin.h

#import <Foundation/Foundation.h>

@interface ManipolatorePin : NSObject {
    IBOutlet NSWindow *finestraPrincipaleWindow;
    IBOutlet NSTextField *codiceTextField;
    NSArray *coordinate_x;
    NSArray *coordinate_y;
    //L'array sotto riportato serve, tramite un ciclo for, a salvare il codice pin spezzato in singoli numeri che corrisponderanno al punto.
    NSMutableArray *numeroAllaIndexArray;
}

- (IBAction)aggiornaTastierino:(id)sender;

@end

//  ManipolatorePin.m


#import "ManipolatorePin.h"
#import "Controller.h"

@implementation ManipolatorePin



- (void)awakeFromNib {
    coordinate_x = [[NSArray alloc] initWithObjects:@"150",@"50",@"150",@"250",@"50",@"150",@"250",@"50",@"150",@"250", nil];
    coordinate_y = [[NSArray alloc] initWithObjects:@"50",@"150",@"150",@"150",@"250",@"250",@"250",@"350",@"350",@"350", nil];


    numeroAllaIndexArray = [[NSMutableArray alloc] init];

    NSLog(@"Array coordinate iniziallizato.\nTest:(%@) -> deve risultare \"50\"\n\n",[coordinate_x objectAtIndex:4]);
}

- (IBAction)aggiornaTastierino:(id)sender {
    NSString *codiceString = [[NSString alloc] initWithFormat:[NSString stringWithFormat:@"%@",[codiceTextField stringValue]]];
    NSLog(@"codiceTextField = %@", codiceString);

    int lunghezzaCodiceString;
    NSLog(@"Il codice risulta essere composto da (%d) numeri\n\n",[codiceString length]);

    //Svuoto array
    [numeroAllaIndexArray removeAllObjects];

    for (lunghezzaCodiceString = 0; lunghezzaCodiceString < [codiceString length]; lunghezzaCodiceString++) {
        //Compilo array (Ci provo ahah)
        NSString *carattereDelCodiceStringInEsame = [[NSString alloc] init];
            carattereDelCodiceStringInEsame = [codiceString substringWithRange:NSMakeRange(lunghezzaCodiceString,1)];

        NSLog(@"Aggiungo il numero (%@) all'array 'numeroAllaIndexArray'",carattereDelCodiceStringInEsame);

            [numeroAllaIndexArray addObject:carattereDelCodiceStringInEsame];
    }

    //DEBUG - DA QUI IN POI E' CANCELLABILE
    NSLog(@"\n\nCiclo for termitato\nProcesso concluso con successo\n\n\nContenuto array:");
    int conteggioArray;
    for (conteggioArray = 0; conteggioArray < [numeroAllaIndexArray count] ; conteggioArray++ ) {
        NSLog(@"index (%d) -> (%@)",conteggioArray,[numeroAllaIndexArray objectAtIndex:conteggioArray]);
        NSLog(@"\n\n");
    }
    //FINE DEBUG

    ///////////////HERE THE INSTANCE TO CALL THE CONTROLLER
    Controller *istanzaGestionaleController = [[Controller alloc] init];
    [istanzaGestionaleController aggiornaTastierinoView];


}

@end

【问题讨论】:

    标签: objective-c macos cocoa nsview nsviewcontroller


    【解决方案1】:

    听起来您有两个不相关的 ViewController 实例。您需要在屏幕上实际有视图的实例上调用 redrawView。

    在您的类(不是 NSViewController)中,创建如下属性:

      @property (nonatomic, readwrite, weak) NSViewController *vc;
    

    当类被实例化时:

      YourClass *yourInstance = [[YourClass alloc] init];
    

    给vc赋值:

      yourInstance.vc = self; // self is your NSViewController instance
    

    然后,当您想触发重绘时,将命令传递给其他类中的 self.vc。

    【讨论】:

    • 修复它的最佳方法是什么?
    • 谢谢,这对 Cocoa 有用吗?我不在iOS上。我相信 myIstance.vc 会给我一个。错误
    猜你喜欢
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多