簡體   English   中英

沒有StoryBoard的情況下如何在兩個ViewController之間使用委托?

[英]How to use delegate between two ViewController without StoryBoard?

我想觸發一條消息,從viewController到另一個viewController。 而且我像下面這樣編碼,但是viewController沒有調用委托。 我想給沒有委托人的代表打電話。 我只想發送一條消息到另一個viewController。

viewController2.h

@protocol ViewController2Delegate;

@interface ViewController2 : UIViewController
@property (nonatomic, weak) id<ViewController2Delegate> delegate;
@end

@protocol ViewController2Delegate <NSObject>
- (void)showSomethingByDelegate;
@end

viewController2.m

#import "ViewController2.h"

@interface ViewController2 ()

@end

@implementation ViewController2

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}
- (IBAction)buttonPressed:(id)sender {
    [self.delegate showSomethingByDelegate];
}

@end

viewController.m

#import "ViewController.h"
#import "ViewController2.h"

@interface ViewController ()
<ViewController2Delegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    ViewController2 *vc2 = [[ViewController2 alloc] init];
    vc2.delegate = self;

}
// Below method was not called by delegate.
- (void)showSomethingByDelegate {
    NSLog(@"Button Was Pressed!!!");
}


@end
ViewController2 *vc2 = [[ViewController2 alloc] init];

這行代碼並沒有按照您的想象做,這是在創建ViewController2的新實例並將其存儲在變量vc2 (根據您的代碼)在任何時候都不會將此變量添加到導航堆棧中並顯示在屏幕上。


編輯
此外,通過Holex作為注意到,您的vc2變量將被從內存中取出后viewDidLoad ,你不持有到它的參考結束。 您可能需要創建一個屬性以將其保留,或將其推入導航堆棧中,以將navigationController保留在該屬性上。

有多種方法可以解決此問題:

  1. 無需創建新的viewController2 ,而是查找對已經顯示在屏幕上的引用(如果它在屏幕上)。
  2. 如果它不是導航堆棧上,添加vc2到導航堆棧[self.navigationController pushViewController:vc2 animated:YES]; (假設您有導航控制器)。
  3. 如果未在堆棧上,並且不希望使用一個navigationController,本vc2模態,如[self presentViewController:vc2 animated:YES completion:nil];

好吧,讓我展示一個更簡單的例子。

文件:firstVC.h

/* This define the protocol object,
 you can write methods required or optional the diference is when
 the protocol is used in a class, xcode show you a yellow warning with required methods
 like UITableViewDelegate, UITextFieldDelegate... */

@protocol firstVCDelegate <NSObject>

@required
- (void)didMessageFromOtherViewController: (NSString *)messageStr;

@optional
- (void)didOtherMessageNotRequired: (NSString *)messageStr;

@end

/* This is the definition of first UIViewController */

@interface firstViewController : UIViewController
@end


/* This is the definition of second UIViewController object with
 a property that is our protocol 'firstVCDelegate' */

@interface secondViewController : UIViewController

@property (nonatomic, weak) id <firstVCDelegate> firstVCDelegate;

- (void)executeDelegateProcess;

@end

文件:firstVC.m

#import "firstVC.h"

#pragma mark - First UIViewController with delegate

@interface firstViewController() <firstVCDelegate>
@end

@implementation firstViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Creating the 'secondViewController' object with delegate on this class
    secondViewController *svc = [secondViewController new];

    // Assign the delegate class
    [svc setFirstVCDelegate: self];

    // Run the delegate logic
    [svc executeDelegateProcess];
}

- (void)didMessageFromOtherViewController:(NSString *)messageStr
{
    // Receiving the message from the instance of our protocol in the 'secondViewController' class
    NSLog(@"MESSAGE #1: %@", messageStr);
}

- (void)didOtherMessageNotRequired:(NSString *)messageStr
{
    // Receiving the message in optional method
    NSLog(@"MESSAGE #2: %@", messageStr);
}

@end

#pragma mark - Second UIViewController

@implementation secondViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)setFirstVCDelegate:(id<firstVCDelegate>)firstVCDelegate
{
    if (firstVCDelegate)
        _firstVCDelegate = firstVCDelegate;
}

- (void)executeDelegateProcess
{
    // This method is only for demo
    // You can execute your delegate in the way you need to use

    if (_firstVCDelegate) {
        [_firstVCDelegate didMessageFromOtherViewController: @"Hello world, using the required method from secondViewController class"];

        [_firstVCDelegate didOtherMessageNotRequired: @"Hello code using the optional method"];
    }
}

@end

在您的appDelegate.m中的didFinishLaunchingWithOptions方法中,您可以放置​​此代碼,並且需要#import“ firstVC.h”

self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
        self.window.autoresizesSubviews = YES;
        [self.window makeKeyAndVisible];

        [_window setRootViewController: [firstViewController new]];

執行並查看兩條日志消息,希望對您有所幫助:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM