Làm cách nào để thiết lập một đại biểu đơn giản để liên lạc giữa hai bộ điều khiển xem?


136

Tôi có hai UITableViewControllersvà cần truyền giá trị từ trình điều khiển khung nhìn con cho cha mẹ bằng cách sử dụng một đại biểu. Tôi biết các đại biểu là gì và chỉ muốn xem một ví dụ đơn giản để làm theo.

Cảm ơn bạn


1
Nếu bạn thử mẫu Xcode "Tiện ích", có một mẫu đại biểu đã được triển khai. Bạn có cần giúp đỡ nhiều hơn có thể?
phi

Đây là một hướng dẫn rất đơn giản. guidespoint.com/ios/ios_delegates.htmlm
Muhammad_Awaab

Câu trả lời:


304

Ví dụ đơn giản ...

Giả sử bộ điều khiển xem con có một UISlidervà chúng tôi muốn chuyển giá trị của thanh trượt trở lại cho cha mẹ thông qua một đại biểu.

Trong tệp tiêu đề của trình điều khiển khung nhìn con, khai báo kiểu đại biểu và các phương thức của nó:

ChildViewControll.h

#import <UIKit/UIKit.h>

// 1. Forward declaration of ChildViewControllerDelegate - this just declares
// that a ChildViewControllerDelegate type exists so that we can use it
// later.
@protocol ChildViewControllerDelegate;

// 2. Declaration of the view controller class, as usual
@interface ChildViewController : UIViewController

// Delegate properties should always be weak references
// See http://stackoverflow.com/a/4796131/263871 for the rationale
// (Tip: If you're not using ARC, use `assign` instead of `weak`)
@property (nonatomic, weak) id<ChildViewControllerDelegate> delegate;

// A simple IBAction method that I'll associate with a close button in
// the UI. We'll call the delegate's childViewController:didChooseValue: 
// method inside this handler.
- (IBAction)handleCloseButton:(id)sender;

@end

// 3. Definition of the delegate's interface
@protocol ChildViewControllerDelegate <NSObject>

- (void)childViewController:(ChildViewController*)viewController 
             didChooseValue:(CGFloat)value;

@end

Trong triển khai của trình điều khiển khung nhìn con, hãy gọi các phương thức ủy nhiệm theo yêu cầu.

ChildViewControll.m

#import "ChildViewController.h"

@implementation ChildViewController

- (void)handleCloseButton:(id)sender {
    // Xcode will complain if we access a weak property more than 
    // once here, since it could in theory be nilled between accesses
    // leading to unpredictable results. So we'll start by taking
    // a local, strong reference to the delegate.
    id<ChildViewControllerDelegate> strongDelegate = self.delegate;

    // Our delegate method is optional, so we should 
    // check that the delegate implements it
    if ([strongDelegate respondsToSelector:@selector(childViewController:didChooseValue:)]) {
        [strongDelegate childViewController:self didChooseValue:self.slider.value];
    }
}

@end

Trong tệp tiêu đề của trình điều khiển xem cha, hãy khai báo rằng nó thực hiện ChildViewControllerDelegategiao thức.

RootViewControll.h

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

@interface RootViewController : UITableViewController <ChildViewControllerDelegate>

@end

Trong phần triển khai của trình điều khiển xem cha, hãy thực hiện các phương thức ủy nhiệm một cách thích hợp.

RootViewControll.m

#import "RootViewController.h"

@implementation RootViewController

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    ChildViewController *detailViewController = [[ChildViewController alloc] init];
    // Assign self as the delegate for the child view controller
    detailViewController.delegate = self;
    [self.navigationController pushViewController:detailViewController animated:YES];
}

// Implement the delegate methods for ChildViewControllerDelegate
- (void)childViewController:(ChildViewController *)viewController didChooseValue:(CGFloat)value {

    // Do something with value...

    // ...then dismiss the child view controller
    [self.navigationController popViewControllerAnimated:YES];
}

@end

Hi vọng điêu nay co ich!


1
Làm thế nào mặc dù cha mẹ đăng ký là đại biểu của đứa trẻ?
Madbreaks

2
Bằng cách gọi detailViewController.delegate = self;(nó nằm -tableView:didSelectRowAtIndexPath:trong đoạn mã trên.
Simon Whitaker

Cảm ơn. Nếu ChildViewControll được ủy quyền cho UITableView, thì các phương thức UITableView nên ở đâu? Ở trẻ hay cha mẹ?
Dejell

Ví dụ / giải thích tuyệt vời! Thật không may, tôi gặp phải lỗi "Không thể tìm thấy khai báo giao thức cho lỗi 'MyProtocol'" khi tôi cố gắng biên dịch. Tuy nhiên, như bạn đã mô tả: trình điều khiển khung nhìn được sinh ra có định nghĩa Procotol trong tệp .h của nó và gọi phương thức giao thức trong tệp .m của nó. Trình điều khiển khung nhìn lưu trữ có <MyProtocol> trong khai báo .h @interface của nó - đó là nơi xảy ra lỗi. Câu trả lời của bạn có vẻ giống nhau, mặc dù ... có ý tưởng nào không?
Danny

Cảm ơn bạn. Tôi đã xem ít nhất một tá tài nguyên và đây là lần đầu tiên tôi có thể theo dõi. Tôi nghĩ rằng các bình luận mã được đánh số hoạt động tuyệt vời để giúp giải thích trình tự của nó.
JaseC

32

Đoạn mã dưới đây chỉ cho thấy việc sử dụng khái niệm đại biểu rất cơ bản .. bạn đặt tên cho biến và lớp theo yêu cầu của bạn.

Đầu tiên bạn cần khai báo một giao thức:

Hãy gọi nó là MyFirstControllDelegate.h

@protocol MyFirstControllerDelegate
- (void) FunctionOne: (MyDataOne*) dataOne;
- (void) FunctionTwo: (MyDatatwo*) dataTwo;
@end

Nhập tệp MyFirstControllDelegate.h và xác nhận FirstContoder của bạn với giao thức MyFirstControllDelegate

#import "MyFirstControllerDelegate.h"

@interface FirstController : UIViewController<MyFirstControllerDelegate>
{

}

@end

Trong tệp thực hiện, bạn cần thực hiện cả hai chức năng của giao thức:

@implementation FirstController 


    - (void) FunctionOne: (MyDataOne*) dataOne
      {
          //Put your finction code here
      }
    - (void) FunctionTwo: (MyDatatwo*) dataTwo
      {
          //Put your finction code here
      }

     //Call below function from your code
    -(void) CreateSecondController
     {
             SecondController *mySecondController = [SecondController alloc] initWithSomeData:.];
           //..... push second controller into navigation stack 
            mySecondController.delegate = self ;
            [mySecondController release];
     }

@end

trong bạn SecondController :

@interface SecondController:<UIViewController>
{
   id <MyFirstControllerDelegate> delegate;
}

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

@end

Trong tệp thực hiện của SecondContoder .

@implementation SecondController

@synthesize delegate;
//Call below two function on self.
-(void) SendOneDataToFirstController
{
   [delegate FunctionOne:myDataOne];
}
-(void) SendSecondDataToFirstController
{
   [delegate FunctionTwo:myDataSecond];
}

@end

Đây là bài viết wiki về đại biểu.


Trong khi điều này bao gồm cách thiết lập một giao thức Delegate hoạt động. Tôi nghĩ đó là một vài điểm chính. Đầu tiên, khi gọi các phương thức trên đại biểu, trước tiên bạn nên kiểm tra xem đại biểu có trả lời cho bộ chọn đó không. Nếu nó không ứng dụng của bạn sẽ sụp đổ. Thứ hai, bạn cần đặt "@protatio MyFirstControllDelegate" thành @protatio MyFirstControllDelegate <NSObject>
CW0007007

6

Giải pháp sau đây là cách tiếp cận rất cơ bản và đơn giản để gửi dữ liệu từ VC2 đến VC1 bằng cách sử dụng đại biểu.

PS: Giải pháp này được thực hiện trong Xcode 9.X và Swift 4

Khai báo một giao thức và tạo một var ủy nhiệm vào ViewContoderB

    import UIKit

    //Declare the Protocol into your SecondVC
    protocol DataDelegate {
        func sendData(data : String)
    }

    class ViewControllerB : UIViewController {

    //Declare the delegate property in your SecondVC
        var delegate : DataDelegate?
        var data : String = "Send data to ViewControllerA."
        override func viewDidLoad() {
            super.viewDidLoad()
        }

        @IBAction func btnSendDataPushed(_ sender: UIButton) {
                // Call the delegate method from SecondVC
                self.delegate?.sendData(data:self.data)
                dismiss(animated: true, completion: nil)
            }
        }

ViewControllA xác nhận giao thức và dự kiến ​​sẽ nhận dữ liệu thông qua phương thức ủy nhiệm sendData

    import UIKit
        // Conform the  DataDelegate protocol in ViewControllerA
        class ViewControllerA : UIViewController , DataDelegate {
        @IBOutlet weak var dataLabel: UILabel!

        override func viewDidLoad() {
            super.viewDidLoad()
        }

        @IBAction func presentToChild(_ sender: UIButton) {
            let childVC =  UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier:"ViewControllerB") as! ViewControllerB
            //Registered delegate
            childVC.delegate = self
            self.present(childVC, animated: true, completion: nil)
        }

        // Implement the delegate method in ViewControllerA
        func sendData(data : String) {
            if data != "" {
                self.dataLabel.text = data
            }
        }
    }

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.