2017-08-13 15 views
0

我試圖更新作爲myViewController子類的文件所有者的引用出口連接到myViewController的NSTextView的內容。在NSTextView中修改字符串內容在viewDidLoad方法下工作,但不在myMethod下

當我從按鈕使用IBAction,或者使用控制器的viewDidLoad方法時,我可以更新文本。但是,當我嘗試從另一個類(在本例中稱爲anotherViewController)運行該方法時,它會運行該方法,但textview不會更改。

myViewController.h:

#import <Cocoa/Cocoa.h> 
#import "anotherViewController.h" 


@interface myViewController : NSViewController { } 
@property (unsafe_unretained) IBOutlet NSTextView *outText; 
@property (weak) IBOutlet NSButton *updateMeButton; 

- (void)updateTextView:(NSString *)argText; 
- (void)updateTextViewWithoutArg; 

@end 

myViewController.m:

#import "myViewController.h" 

@interface myViewController() 
@end 

@implementation myViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.outText.string = @"I work successfully"; 
} 

- (IBAction)updateMeButton:(id)sender { 
    self.outText.string = @"I am updated text! I also work!"; 
} 

- (void)updateTextView:(NSString *)argText { 
    self.outText.string = @"I don't make it to the NSTextView :("; 
    NSLog(@"Should have updated text view"); 
} 

- (void)updateTextViewWithoutArg { 
    self.outText.string = @"I don't make it to the NSTextView :("; 
    NSLog(@"Should have updated text view"); 
} 

@end 

anotherViewController.m,裏面有所有相關的進口,我稱之爲:

myViewController *viewtask = [[myViewController alloc] init]; 
[viewtask updateTextViewWithoutArg]; 

沒有任何反應。該方法運行並記錄它應該更新,但沒有文本更新。我已經嘗試了許多不同的方法,包括textstorage和scrollrange方法,它們都可以工作在已經工作的部分,但是在不工作的部分沒有區別。

我也嘗試只是爲了好玩:

myViewController *viewtask; 
[viewtask updateTextViewWithoutArg]; 
  • 還使用實例變量_outText
  • 還使用[self.outText setString:@"string"];
  • 還使用[_outText setString:@"string"];

同樣,他們的工作但只限於已經在工作的部分。

這應該很簡單,但對我來說不合邏輯。在迅速所有我需要做的是 self.outText.string = "I update whenever I'm called!"

+0

你必須發送'updateTextViewWithoutArg'到現有的視圖控制器。 '[[myViewController alloc] init]'創建一個新的視圖控制器。 – Willeke

+0

@Willeke這最終是我認爲的情況。但不是因爲缺乏研究和嘗試,我還沒有找到辦法做到這一點。奇怪的是,我得到的最接近的是找到沒有答案的類似問題。我試圖使myViewController單身,但由於它最初是從一個segue觸發的,我不認爲這可以工作。此外,我試圖'@ synthesize' mybutton並將其狀態設置爲NSOnState,但我認爲這只是創建另一個實例。 – hmedia1

+0

我意識到有很多方法可以實現最終結果(我知道這樣做的一個方法就是快速創建myViewController並添加橋接標頭),但是我遇到的問題是我一直在運行問題,試圖修改現有的實例,我一直在解決它。也許我的程序是錯誤的,但是,如果有辦法做到這一點,我只想最終掌握這個運行時實例控制。 – hmedia1

回答

0

我似乎通過使myViewController一個單獨的類,並使用sharedInstance已經找到了解決方案。對於這個特殊的應用程序,myViewController是一個調試輸出窗口,永遠不需要放在另一個視圖中。

我不會接受這個答案,因爲它不是我確定的最好的答案。 可能仍然存在適當的解決方案,它允許查找適用的myViewController實例,並修改附加到它的outText屬性。使用這個單例使得子類繁瑣,因爲如果我想要解決10個視圖控制器的問題,我將不得不爲每個實例創建一個新類。

反正 - 我已經能夠滿足我的要求,簡單的方式:

myViewController.h:

#import <Cocoa/Cocoa.h> 
#import "anotherViewController.h" 


@interface myViewController : NSViewController { } 
@property (unsafe_unretained) IBOutlet NSTextView *outText; 
@property (weak) IBOutlet NSButton *updateMeButton; 

- (void)updateTextView:(NSString *)argText; 
- (void)updateTextViewWithoutArg; 

+ (id)sharedInstance; 
@end 

myViewController。L:

#import "myViewController.h" 

@interface myViewController() 
@end 

@implementation myViewController 

static myViewController *sharedInstance = nil; 

+ (myViewController *)sharedInstance { 
    static myViewController *sharedInstance = nil; 
    static dispatch_once_t onceToken; 

    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[myViewController alloc] init]; 
    }); 
    return sharedInstance; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    sharedInstance = self; 
} 

- (void)viewDidUnload { 
    sharedInstance = nil; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.outText.string = @"I work successfully"; 
} 

- (IBAction)updateMeButton:(id)sender { 
    sharedInstance.outText.string = @"Button Pressed"; 
} 

- (void)updateTextView:(NSString *)argText { 
    sharedInstance.outText.string = argText; 
} 

- (void)updateTextViewWithoutArg { 
    sharedInstance.outText.string = @"I make it to the TextView now"; 
} 

@end 

現在,當我使用這個代碼內anotherViewController.m它更新正確的實例:

[myViewController.sharedInstance updateTextView:@"Updating with this string"]; 
0

查看你在Interface Builder創建懶洋洋地創建的,所以如果你訪問他們之前viewDidLoad被稱爲他們是nil

如果你的情況下,調用

myViewController *viewtask = [[myViewController alloc] init]; 

不會導致意見要創建這樣當你打電話

[viewtask updateTextViewWithoutArg]; 

self.outTextnil

你可以看到,這是由如下更新您的代碼發生:

- (void)updateTextView:(NSString *)argText { 
    NSAssert(self.outText != nil, @"self.outText must not be nil"); 
    self.outText.string = @"I don't make it to the NSTextView :("; 
    NSLog(@"Should have updated text view"); 
} 

你應該看到斷言火。

+0

感謝您的信息。在我的情況下,視圖(這是一個調試輸出窗口)首先被創建(通過「show」segue),然後**我將通過單擊* other *視圖中的按鈕來更新該視圖。你知道我可以如何發送消息到已經創建的視圖嗎? – hmedia1

+0

如果不能看到所有涉及到的代碼,但給出特定的答案有點難,但主要有兩種方法:(1)當創建調試視圖控制器時,可以在'prepareForSegue'中使用'[ (2)使用'NSNotificationCenter'來實現更加鬆散耦合的解決方案。既然你提到你可能想從許多視圖控制器訪問它(2)可能是要走的路。 – idz

相關問題