iOS - 使用协议和委托将数据从 Swift 传递到 ObjC VC

iOS - Pass Data from Swift to ObjC VC using protocol and delegate

提问人:DroidDev 提问时间:1/4/2022 最后编辑:Ol SenDroidDev 更新时间:1/6/2022 访问量:619

问:

我正在尝试在关闭时使用委托将数据从 Swift VC2 传递回 ObjC VC1,下面是我的代码。

VC2 (快速)

//protocol used for sending data back
@objc protocol DataEnteredDelegate: AnyObject {
    func userDidEnterInformation(info: String)
}

class VC2: UIViewController {

    weak var delegate: DataEnteredDelegate? = nil

    // **Go back to VC1**
    @IBAction func doneBtn(_ sender: Any) { 
      session.stop();
      delegate!.userDidEnterInformation(info: "sending date from Swift VC2")
      self.dismiss(animated: true, completion: nil) 
    }
}

VC1.m (objc)

#import "ProjectName-Swift.h"

@interface VC1 () <>
 
@end

@implementation VC1
// **Navigate to VC2**
-(void)goToVC2 {
    VC2 *vc2 = [[UIStoryboard storyboardWithName: @"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"VC2ID"];
    [self presentViewController: vc2 animated: YES completion: nil];
}
@end

VC1.h (objc)

@interface VC1 : UIViewController

@end

如何在移动到 VC2 之前在 VC1 中分配委托,以及如何在 VC1 (objc) 文件中实现协议,即 DataEnteredDelegate 和 func userDidEnterInformation。

我相信我已经完成了任务的快速部分,但正在寻找 Objc 实现。

iOS Swift Objective-C UIVieviceController

评论

1赞 Ol Sen 1/4/2022
OBJC 中没有 anyobject。当这样的声明不仅仅是空的,就像它上面的“<>”一样,协议在 nsobject 上起作用。应该如此,并且由于 Swift 不是在 OBJC 之前编译的,因此只要在此之前 OBJC 不知道该协议,标头就会失败。要么预先声明,要么在 OBJC 中声明,因为它要容易得多。protocol DataEnteredDelegate: AnyObjectprotocol DataEnteredDelegate: NSObject
1赞 Ol Sen 1/4/2022
最后但并非最不重要的一点是,当你的 protoc 告诉有某种方法时,你应该在协议 following 类上实现它以使其工作。
0赞 DroidDev 1/4/2022
@OlSen - 谢谢 我将 AnyObject 更改为 NSObject,您能否在 ObjC 中添加协议的实现?

答:

1赞 DonMag 1/4/2022 #1

非常基本的例子...

假设我们在 Storyboard 中:

  • 带有“Present It”按钮的 Objective-C 控制器ObjcViewController
  • 带有“完成”按钮的 Swift 控制器,带有SwiftViewControllerIdentifier: "SwiftVC"

按钮连接到方法...IBAction

ObjcViewController.h

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface ObjcViewController : UIViewController

@end

NS_ASSUME_NONNULL_END

ObjcViewController.m

#import "ObjcViewController.h"

#import "YourProject-Swift.h"

@interface ObjcViewController () <DataEnteredDelegate>

@end

@implementation ObjcViewController

- (IBAction)goToSwiftVC:(id)sender {
    
    SwiftViewController *vc = (SwiftViewController *)[self.storyboard instantiateViewControllerWithIdentifier:@"SwiftVC"];
    [vc setMyDelegate:self];
    [self presentViewController:vc animated:YES completion:nil];
    
}

- (void)userDidEnterInformationWithInfo:(NSString * _Nonnull)info {
    NSLog(@"Delegate sent back: %@", info);
}

@end

SwiftView控制器.swift

import UIKit

@objc public protocol DataEnteredDelegate {
    func userDidEnterInformation(info: String)
}

class SwiftViewController: UIViewController {

    @objc public var myDelegate: DataEnteredDelegate?
    
    @IBAction func doneBtn(_ sender: Any) {
        myDelegate?.userDidEnterInformation(info: "from SwiftVC")
        self.dismiss(animated: true, completion: nil)
    }

}

评论

0赞 Ol Sen 1/4/2022
值得注意的是,有些情况下需要 String 在协议中为 NSString 才能符合。
0赞 men 11/7/2022
应该是:vc.myDelegate = self;
0赞 DonMag 11/7/2022
@men - 嗯,是的......它可以用以下两种方式写成:或者[vc setMyDelegate:self]; vc.myDelegate = self;
0赞 Sahidul Islam 1/6/2022 #2

首先,您需要创建带有 @objc 的委托实例初始

VC2 (快速)

//protocol used for sending data back
@objc protocol DataEnteredDelegate: AnyObject {
    func userDidEnterInformation(info: String)
}

class VC2: UIViewController {

   @objc weak var delegate: DataEnteredDelegate?

    // **Go back to VC1**
    @IBAction func doneBtn(_ sender: Any) { 
      session.stop();
      delegate!.userDidEnterInformation(info: "sending date from Swift VC2")
      self.dismiss(animated: true, completion: nil) 
    }
} 

现在在 objective-c 中,VC1.m (objc)

#import "ProjectName-Swift.h"

@interface VC1 () <DataEnteredDelegate>
 
@end

@implementation VC1
// **Navigate to VC2**
-(void)goToVC2 {
    VC2 *vc2 = [[UIStoryboard storyboardWithName: @"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"VC2ID"];
    [vc2 delegate:self];
    [self presentViewController: vc2 animated: YES completion: nil];
}

//On dismiss vc2 this delegate will call
- (void)userDidEnterInformationWithInfo:(NSString *)info{
    NSLog(@"%@", info);
}
@end