3

作業中のアプリでストーリーボードでデリゲートを使用するコツをつかむのに問題があります。データを返すなど、他のいくつかの検索を確認しました:呼び出されていないデリゲートメソッドですが、役に立ちません。この時点で、2つのビューの基本を除いて、アプリ内のすべてを削除しました。最初のビューは、ボタンを押すとモーダルビューに移行する基本的なビューコントローラーであり、データの1つがテキストフィールドに入力されます。保存ボタンはそのモーダルビューにあり、押すと最初のビューに戻ります。もちろん、入力したデータを最初のビューにも送り返したいと思います。簡単に聞こえますか?もちろんですが、どこかで動作させることができません。私の代理人の電話は決してかけられないようです。コードは次のとおりです。

MyDayViewController.h-これは最初のビューコントローラです

#import <UIKit/UIKit.h>
#import "AddRatingModalViewController.h"

@interface MyDayViewController : UIViewController <AddRatingDelegate>

@property (strong, nonatomic) IBOutlet UIButton *addRatingBtn;
@property (strong, nonatomic) IBOutlet UIButton *addAccompBtn;
@property (strong, nonatomic) IBOutlet UILabel *ratingLabel;

@end

MyDayViewController.m

#import "MyDayViewController.h"

@implementation MyDayViewController
@synthesize addRatingBtn;
@synthesize addAccompBtn;
@synthesize ratingLabel;

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:@"ToRatingVC"])
{
    NSLog(@"Setting MyDayVC as a delegate of AddRatingMVC");

    AddRatingModalViewController *addRatingController = segue.destinationViewController;
    addRatingController.delegate = self;
}
}

- (void)theSaveButtonTapped:(AddRatingModalViewController *)controller withRating:(NSNumber*) rating
{
NSLog(@"In theSaveButtonTapped method of MyDayVC");
ratingLabel.text = [[NSString alloc]initWithFormat:@"%@", rating];

[self dismissModalViewControllerAnimated:YES];
}

- (void)viewDidUnload
{
[self setAddRatingBtn:nil];
[self setAddAccompBtn:nil];
[self setRatingLabel:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

@end

AddRatingModalViewController.h-これはモーダルビューコントローラーです

#import <UIKit/UIKit.h>

@class AddRatingModalViewController;

@protocol AddRatingDelegate
- (void)theSaveButtonTapped:(AddRatingModalViewController *)controller withRating:(NSNumber*) rating;
@end

@interface AddRatingModalViewController : UIViewController

@property (nonatomic, weak) id <AddRatingDelegate> delegate;
@property (strong, nonatomic) IBOutlet UITextField *addRatingTextField;

- (IBAction)cancelBtnPressed:(id)sender;
- (IBAction)saveBtnPressed:(id)sender;

@end

AddRatingModalViewController.m

#import "AddRatingModalViewController.h"

@implementation AddRatingModalViewController
@synthesize addRatingTextField;
@synthesize delegate;

- (IBAction)cancelBtnPressed:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

- (IBAction)saveBtnPressed:(id)sender {
NSNumber *ratingARMVC = [NSNumber numberWithInteger:[addRatingTextField.text integerValue]];
NSLog(@"The entered Rating in ARMVC is %@", ratingARMVC);

NSLog(@"Telling the MyDayVC Delegate that Save was tapped on the AddRatingTVC");
[self.delegate theSaveButtonTapped:self withRating:ratingARMVC];

}

- (void)viewDidUnload
{
[self setAddRatingTextField:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}

@end

コンソールからの出力は次のとおりです。

2012-07-16 16:49:16.384 MyDayDelTest[4695:f803] Setting MyDayVC as a delegate of AddRatingMVC
2012-07-16 16:49:39.274 MyDayDelTest[4695:f803] The entered Rating in ARMVC is 7
2012-07-16 16:49:39.275 MyDayDelTest[4695:f803] Telling the MyDayVC Delegate that Save was tapped on the AddRatingTVC

これは、Saveメソッドでデリゲート呼び出しが行われることになっている直前です。どんな助けでも大歓迎です!ストーリーボードを使用しない場合はテストが機能すると言うべきですが、アプリの他の部分でストーリーボードを使用するため、ストーリーボードを使用するにはこれが必要です。前もって感謝します。

4

1 に答える 1

0

@ pina0004 がここで答えを見つけました。要約すると、プッシュされた VC が実際に UINavigationController のルート VC である場合、セグエの destinationViewController はプッシュされた VC を指すのではなく、(あまり直感的ではありませんが) ルートである nav コントローラーを指します。

それは解決しましたが、これはデリゲート パターンの乱用の例だと思います。この場合、プッシュされた VC は文字列を元に報告する必要があり、質問は元へのデリゲート ポインターを使用します。「委任された」作業は、文字列を保存してモーダル VC を閉じることだけです。より良い代替手段があると思います:

  • モデルを渡す: プッシュされた VC が誰であるかをプッシュされた VC に伝える代わりに、そのモデルへのポインター (この場合は文字列) を渡します。プッシュされた VC にモデルを変更させてから、プッシャーがモデルが変更されたことを検出するためのいくつかの手法のいずれかを使用します。
  • 自分自身を閉じる: メソッドの命名方法からはあまり明らかではありませんが、モーダルに提示された VC は自分自身を閉じることができます。プッシュする VC は、その viewWillAppear メソッドでモデルの状態を確認できます。このメソッドは、プッシュされた VC が消えようとしているときに実行されます。
  • KVO : 元の VC は、特定のモデル プロパティが変更されたときに通知を受け取るように依頼できます。これにより、プッシュはモデルの状態の変化を認識し、必要に応じてモーダル VC を却下できます。
  • 通知: プッシュされた VC またはモデルのいずれかが、状態変化の通知を投稿できます。プッシュする VC は、これにサブスクライブして応答できます。これは、アプリにとってより一般的な関心のある状態の変化に特に役立ちます。
  • ブロック: VC はブロックを使用して、何か重要なことが起こったときに実行するコードを引き渡すことができます。ブロックは、プッシュする VC のコンテキストで実行されます。これは、同じ変数名を共有していても、コードの原因と結果のブロックを互いに近くに保つための非常に読みやすい方法です。
于 2012-07-19T17:41:00.723 に答える