2

いくつか質問した後、あるView Controllerから別のView Controllerに注文を送信する方法を学び、コードを書くことができましたが、何も起こりません...

私のプロジェクトには、 と という名前の 2 つのビュー コントローラーがsayfa1ありsayfa23ます。ボタンsayfa1がクリックされると、それが開いてsayfa23ラベルに書き込みます (ランダムこんにちは、以下のコードを参照してください) が、それは起こりません。シミュレーターでは、そのボタンは開くだけでsayfa23、ラベルには何も起こりません。コードを見ると、よりよく理解できます。

sayfa1.h

#import <UIKit/UIKit.h>

@protocol sayfa1Delegate <NSObject>

- (void)dealWithButton1;

@end


@interface sayfa1 : UIViewController

@property(nonatomic,assign) id<sayfa1Delegate> delegate;

@end

sayfa1.m

#import "sayfa1.h"

@interface sayfa1 ()

@end

@implementation sayfa1

@synthesize delegate;

-(IBAction)button
{
    [delegate dealWithButton1];
}

@end

sayfa23.h

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

@interface sayfa23 : UIViewController <sayfa1Delegate> 
{
    IBOutlet UILabel *label;
    sayfa1 *vc1 ;
}

@end

sayfa23.m

#import "sayfa23.h"
#import "sayfa1.h"

@interface sayfa23 ()

@end

@implementation sayfa23

- (void)dealWithButton1
{
    vc1.delegate = self;    
    int random_num;
    random_num = (arc4random() % 5 - 1) + 1;
    if (random_num == 1)
    { 
        label.text = @"hello1";    
    }
    else if (random_num == 2)
        label.text = @"hello2";
    else if (random_num == 3)
        label.text = @"hello3";
    else if (random_num == 4)
        label.text = @"hello4";
}

@end

このコードを書いた後sayfa23、新しいページが開くようにボタンを に接続し、そのボタンを に接続してsayfa1ボタン アクションを受信し、ラベル (on sayfa23) を接続してsayfa23ラベルの注文を受け取りました。しかし、私が言うように、エラーは発生せず、こんにちは、私が間違っていることはありませんか? いくつかの h ファイルをインポートしsayfa1.hたりsayfa23.h、先頭に置いたりすると、Xcode が定義されていないというエラーを表示し、その問題を解決しましたが、それは私の間違いか何かでしょうか。

私が欲しいの例.

  • ユーザーがアプリを開く

  • sayfa1画面に表示される

  • ユーザーがボタンをクリックすると、ランダムな hello1..2..3 などを書き込むボタンによって変更されsayfa23たラベル テキストが表示されます。sayfa23sayfa1

私が間違っていることは何ですか?

4

3 に答える 3

2

あなたの質問を読み直して、最初のView Controllerが2番目のView Controllerを開いてテキストボックスを設定する方法を尋ねます。それが実際にあなたがやろうとしていることである場合、それははるかに単純な質問であり、デリゲート プロトコルやデリゲートはまったく必要ありません。

前の 2 つの回答は、デリゲートの議論によって通知されましたが、それは別の問題を解決するように設計されています。デリゲートは、2 番目のコントローラーが最初のコントローラーに何かを返す必要がある場合にのみ必要です。ただし、2 番目のコントローラーが最初のコントローラーから何かを受信するようにしたい場合は、次のように簡単です。

//  FirstViewController.h

#import <UIKit/UIKit.h>

@interface FirstViewController : UIViewController

@end

次のような実装を使用します。

//  FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@implementation FirstViewController

- (NSString *)generateRandomText
{
    NSString *result;

    int random_num;
    random_num = (arc4random() % 5 - 1) + 1;
    if (random_num == 1)
        result = @"hello1";    
    else if (random_num == 2)
        result = @"hello2";
    else if (random_num == 3)
        result = @"hello3";
    else if (random_num == 4)
        result = @"hello4";

    return result;
}

// if you're using NIBs, it might be something like...
// you only need this method if you're using NIBs and you've manually hooked a button up to this
// if you're using segues, get rid of `goToNextViewController` and just use the following `prepareForSegue

- (IBAction)goToNextViewController:(id)sender
{
    SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
    secondController.textFromParent = [self generateRandomText];
    [self.navigationController pushViewController:secondController animated:YES];
}

// if you're using segues, give your segue an identifier, e.g. toSecondViewSegue, in Interface Builder and reference the exact same identifier here
// if you're not using segues, you don't need this prepareForSegue method

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"toSecondViewSegue"])
    {
        SecondViewController *destinationController = segue.destinationViewController;

        destinationController.textFromParent = [self generateRandomText];
    }
}

@end

2 番目のコントローラーは次のようになります。

//  SecondViewController.h

#import <UIKit/UIKit.h>

@interface SecondViewController : UIViewController

@property (strong, nonatomic) NSString *textFromParent;
@property (weak, nonatomic) IBOutlet UILabel *label;

@end

次のような実装を使用します。

//  SecondViewController.m

#import "SecondViewController.h"

@implementation SecondViewController

@synthesize textFromParent = _textFromParent;
@synthesize label = _label;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.label.text = self.textFromParent;
}

@end
于 2012-07-24T17:25:56.610 に答える
1

最初のコントローラは、2 番目のコントローラをインスタンス化するときに、2 番目のデリゲートが最初のビュー コントローラを指すように設定する必要があります。したがって、最初のビュー コントローラーは次のようになります。

//  FirstViewController.h

#import <UIKit/UIKit.h>

@protocol FirstViewControllerDelegate <NSObject>

- (void)dealWithButton;

@end

@interface FirstViewController : UIViewController <FirstViewControllerDelegate>

@end

次のような実装を使用します。

//  FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@implementation FirstViewController

- (IBAction)goToNextViewController:(id)sender
{
    SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
    secondController.delegate = self;
    [self.navigationController pushViewController:secondController animated:YES];
}

- (void)dealWithButton
{
    NSLog(@"Dealt with button from second controller");
}

@end

2 番目のコントローラーは次のようになります。

//  SecondViewController.h

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

@class FirstViewController;

@interface SecondViewController : UIViewController

@property (weak, nonatomic) id<FirstViewControllerDelegate> delegate;
@property (weak, nonatomic) IBOutlet UILabel *label;

- (IBAction)buttonPressed:(id)sender;

@end

次のような実装を使用します。

//  SecondViewController.m

#import "SecondViewController.h"

@implementation SecondViewController

@synthesize delegate = _delegate;
@synthesize label = _label;

- (IBAction)buttonPressed:(id)sender
{
    int random_num;
    random_num = (arc4random() % 5 - 1) + 1;
    if (random_num == 1)
        self.label.text = @"hello1";    
    else if (random_num == 2)
        self.label.text = @"hello2";
    else if (random_num == 3)
        self.label.text = @"hello3";
    else if (random_num == 4)
        self.label.text = @"hello4";

    [self.delegate dealWithButton];
}
@end

アップデート:

最初の質問では、ラベルを最初のコントローラーに配置するか、2 番目のコントローラーに配置するかが明確ではありませんでした。上記の私の回答では、2 番目のコントローラーでそれが必要であると想定していましたが、振り返ってみると、最初のコントローラー (デリゲート) でそれが必要だった可能性があります。もしそうなら、次のコードはそれを行います。ビューdealWithButtonが表示されているかどうかがわからないため危険です ( を受け取った場合はアンロードされている可能性がありますdidReceiveMemoryWarning)。だから私は待っていviewWillAppearます。繰り返しますが、最初のView Controllerは次のとおりです。

//  FirstViewController.h

#import <UIKit/UIKit.h>

@protocol FirstViewControllerDelegate <NSObject>

- (void)dealWithButton;

@end

@interface FirstViewController : UIViewController <FirstViewControllerDelegate>

@property (weak, nonatomic) IBOutlet UILabel *label;

@end

そしてその実装:

//  FirstViewController.m

#import "FirstViewController.h"
#import "SecondViewController.h"

@interface FirstViewController ()
{
    NSString *_labelText;
}
@end

@implementation FirstViewController

@synthesize label = _label;

// if you're using storyboards, it would be like:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"delegateSegue"])
    {
        SecondViewController *destinationController = segue.destinationViewController;
        FirstViewController *sourceController = segue.sourceViewController;

        destinationController.delegate = sourceController;
    }
}

// if not using storyboards, you probably have a button like:

- (IBAction)goToNextViewController:(id)sender
{
    SecondViewController *secondController = [[SecondViewController alloc] initWithNibName:@"SecondView" bundle:nil];
    secondController.delegate = self;
    [self.navigationController pushViewController:secondController animated:YES];
}

- (void)dealWithButton
{
    // note, because this is being called by the second view controller, you should *not* update the UI
    // directly, because you can't be assured this view controller's view is still in memory (if you got
    // a didReceiveMemoryWarning while on the second view controller, this first view controller will 
    // stay in memory, but its view could have been released). So save what you want the label to be,
    // and update it on viewWillAppear (and if the view was released, it will be reloaded by the time
    // you hit viewWillAppear.
    //
    // clearly, if you were doing view controller containment and this was the parent view, you wouldn't
    // want to do this. But I assume you're dealing with a simple push/present view controller situation.

    int random_num;
    random_num = (arc4random() % 5 - 1) + 1;
    if (random_num == 1)
        _labelText = @"hello1";    
    else if (random_num == 2)
        _labelText = @"hello2";
    else if (random_num == 3)
        _labelText = @"hello3";
    else if (random_num == 4)
        _labelText = @"hello4";

    NSLog(@"Dealt with button from second controller");
}

- (void)viewWillAppear:(BOOL)animated
{
    self.label.text = _labelText;
}

@end

そして2番目のView Controller:

//  SecondViewController.h

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

@class FirstViewController;

@interface SecondViewController : UIViewController

@property (weak, nonatomic) id<FirstViewControllerDelegate> delegate;

- (IBAction)buttonPressed:(id)sender;

@end

そしてその実装:

//  SecondViewController.m

#import "SecondViewController.h"

@interface SecondViewController ()

@end

@implementation SecondViewController

@synthesize delegate = _delegate;

- (IBAction)buttonPressed:(id)sender
{
    [self.delegate dealWithButton];
}
@end
于 2012-07-24T14:25:08.287 に答える
0

次のメソッドを sayfa23 の実装に追加してみてください。

- (void)viewDidLoad
{
    vc1 = [[sayfa1 alloc] init];
    vc1.delegate = self;
}

vc1.delegate = self; を削除します。dealWithButton1 メソッドから。

編集: オブジェクトにメッセージを送信していないため、メソッド dealWithButton1 が呼び出されないことを理解する必要があります。したがって、vc1 のデリゲートを設定することはありません。ビューがロードされたときに呼び出される viewDidLoad メソッドを使用してセットアップを行うことをお勧めします。そこで、sayfa1 クラスを init (インスタンスを作成) し、プロパティ vc1 に割り当てることができます。オブジェクトを割り当てた後、メッセージを送信できます。その後、デリゲートを設定できます。

sayfa23.h

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

@interface sayfa23 : UIViewController <sayfa1Delegate> 



{

    IBOutlet UILabel *label;
}
    @property (nonatomic, strong) sayfa1 *vc1 ;



@end

sayfa23.m

#import "sayfa23.h"
#import "sayfa1.h"

@interface sayfa23 ()

@end

@implementation sayfa23
@synthesize vc1;


- (void)viewDidLoad
{
    vc1 = [[sayfa1 alloc] init];
    vc1.delegate = self;
}

- (void)dealWithButton1

{
    int random_num;
    random_num = (arc4random() % 5 - 1) + 1;
    if (random_num == 1)
    { 
        label.text = @"hello1";    
    }
    else if (random_num == 2)
        label.text = @"hello2";
    else if (random_num == 3)
        label.text = @"hello3";
    else if (random_num == 4)
        label.text = @"hello4";
}


@end
于 2012-07-24T13:58:18.333 に答える