2017-08-13 3 views
0

myViewControllerに接続されているNSTextViewの内容を、サブクラスのmyViewControllerであるファイル所有者の参照コンセントとして更新しようとしています。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"];

は再び、彼らは仕事使用:

は私もちょうど楽しみのために試してみましたすでに作業しているセクションでのみ有効です。

これは単純なはずですが、私には論理的ではありません。迅速で、私がする必要があるすべては、私はシングルトンクラスmyViewControllerを作り、sharedInstanceを使用して解決策を見つけたように見える self.outText.string = "I update whenever I'm called!"

+0

既存のビューコントローラに 'updateTextViewWithoutArg'を送る必要があります。 '[[myViewController alloc] init]'は、新しいView Controllerを作成します。 – Willeke

+0

@Willekeこれは最終的に私が思ったものです。しかし、研究と試練の欠如ではなく、私はこれを行う方法を見つけていない。不思議なことに、私が得た最も近いものは、未回答の類似の質問を見つけることです。私はmyViewControllerをシングルトンにしようとしましたが、最初はsegueからトリガされていたので、これは動作しないと思います。また、私はmybuttonを '@ synthesize'しようとしてNSOnStateに状態を設定しようとしましたが、もう一度このインスタンスを作成するだけです。 – hmedia1

+0

ここで最終結果を達成するにはいくつかの方法があることを認識しています(myViewControllerを素早く作成し、ブリッジヘッダーを追加するだけで済むような方法があります)。しかし、私は問題は同じです既存のインスタンスを修正しようとしているのですが、それを回避しています。おそらく私のプログラムは間違っているかもしれませんが、これを行う方法があれば、このランタイムインスタンスコントロールを最終的に把握したいだけです。 – hmedia1

答えて

0

です。この特定のアプリケーションの場合、myViewControllerはデバッグ出力ウィンドウであり、決して別のビューに配置する必要はありません。

私は確信している最高のものではないので、私はまだこの答えを受け入れません。 という適切な解決策があり、適用可能なmyViewControllerインスタンスを見つけて、それに接続されているoutTextプロパティを変更することができます。このシングルトンを使用すると、サブクラス化が面倒なものになります。なぜなら、10個のView Controllerを扱うためには、すべてのインスタンスに対して新しいクラスを作成する必要があるからです。とにかく

- 私は私の簡単な要件を満たすことができました方法:

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。M:私はanotherViewController.m内からこのコードを使用する場合

#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 

は、今では右のインスタンスを更新します:あなたがInterface Builderで作成

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

ビューが遅延して作成され、あなたのアクセスので、もしそれらの前にはと呼ばれています。それはnilです。

あなたのケースであれば、あなたは

[viewtask updateTextViewWithoutArg]; 

self.outTextnilで呼び出したときにビューがそう作成されません

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

を呼び出します。

あなたは、これは以下のようにコードを更新することで何が起こっているかであることがわかります。

- (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

情報ありがとうございます。私の場合は、ビュー(デバッグ出力ウィンドウ)は最初に( "ショー"セグ)で作成されています。**その後** *他のビューのボタンをクリックしてそのビューを更新します。すでに作成されたビューにメッセージを送信する方法を知っていますか? – hmedia1

+0

関連するすべてのコードを見ることができなければ、特定の答えを出すのは少し難しいですが、主な2つの方法があります:(1)デバッグビューコントローラが作成されたとき、 'prepareForSegue'で' segue destinationViewController] '(2)NSNotificationCenterを使用します。あなたは、あなたが多くのビューコントローラ(2)からアクセスすることができます言及しているので、行く方法かもしれません。 – idz

関連する問題