如何在使用Swift 4的Objective-C类中符合Swift类委托?

8
假设在同一个项目中有两个类,一个是Swift类,另一个是Objective-C类。
在Swift类中,我声明了委托,并希望在Objective-C类中设置该委托。
我按照以下方式完成了这个操作...
import UIKit

@objc public protocol SwiftLoginVCDelegate: class {

}

@objc public class SwiftLoginViewController: UIViewController {

    @IBOutlet var txtUserName: UITextField!
    @IBOutlet var txtPassword: UITextField!
    @IBOutlet var btnLogin: UIButton!
    var delegate: SwiftLoginVCDelegate?

    override public func viewDidLoad() {
        super.viewDidLoad()
        self.txtPassword.text = "XYZ"
        self.txtPassword.text = "123"
        self.btnLogin.backgroundColor = UIColor.blue

    }
 @objc public func testObjective(){
        print("Swift class is integrated in objective c project")
    }

Objective-C类是什么?

#import "Mediator.h"

@class    SwiftLoginViewController;
@protocol SwiftLoginVCDelegate;

@interface LoginMediator : Mediator

@end

实现类是

#import "xyz-Swift.h"

@class SwiftLoginViewController;

@implementation LoginMediator 


-(void)onRegister
{
// line 1:   [(XYZController*)self.viewComponent setDelegate:self];

   line 2 :  [(SwiftLoginViewController*)self.viewComponent setDelegate:self];

       [objectVC testObjective];
}

如果您检查onRegister方法,第1行使用Objective-C设置了委托,这已被注释掉,但我想在第2行使用Swift 4设置相同的委托,当我尝试在Swift 4中设置委托时,出现以下错误:

“No visible @interface for 'SwiftLoginViewController' declares the selector 'setdelegate';”

注意:

我能够访问Swift类中定义的所有变量和函数,但无法在Objective-C类中设置在Swift类中声明的委托。

有没有人知道我在上面的代码中做错了什么? 欢迎任何意见。

@objc weak public var delegate: SwiftLoginVCDelegate? - Antony Raphel
5个回答

9

好的,我用Objective-C创建了一个样例项目,并安装了我的Swift框架GPKit,一切运作正常后,我发现你没有使用Cocoapod。因此,我创建了一个Swift类样例,然后在我的Objective-C类中使用它。

首先,你需要学会如何在Objective-C类中正确使用Swift文件/类,请参考这里:无法在Objective-C中使用Swift类

然后,一旦你把它搞定了,在Swift委托中进行确认并实现该委托中的函数将变得很容易。

从你的实现中,我可以看到你正在创建一个新的classprotocol

@class    SwiftLoginViewController;
@protocol SwiftLoginVCDelegate;

这是我为了这个问题制作的示例代码:
ViewController.m
#import "TestObjcUsingGPKit-Swift.h"
#import "ViewController.h"

@interface ViewController () <CuteDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    CuteClass *newCutie = [[CuteClass alloc] init];
    newCutie.delegate = self;
}

- (void)myCuteFunc {
    // --- the delegate function
}

@end

CuteClass.swift

import UIKit

@objc public protocol CuteDelegate: NSObjectProtocol {
    @objc func myCuteFunc()
}

public class CuteClass: NSObject {
    weak var delegate: CuteDelegate?
}

在GitHub上有完整的示例项目可供您使用:https://github.com/glennposadas/UsingSwift-In-ObjectiveC


我已经尝试过了,但仍然出现相同的错误:“SwiftLoginViewController没有声明'setdelegate'选择器的可见@interface”。我能够访问Swift类的变量和方法,但是我无法在Objective-C类中设置在Swift类中声明的委托。 - Shubham JAin
一切都已经为你准备好了!我甚至在这个答案中提供了一个示例项目。你需要学习如何在Objective-C项目中使用Swift类。祝你好运。 - Glenn Posadas

2
我和你遇到了完全一样的问题。我注意到生成的-Swift.h文件没有将我的Swift文件中的弱委托成员暴露给Objective-C运行时。您可以通过在#import -Swift.h文件上执行command + click并搜索您的Swift类名来验证此操作,以查看公开的方法/成员。

最终解决该问题的方法是,我最终为我的委托添加了@objc标签。在您的情况下,应该是:

@objc weak var delegate: SwiftLoginVCDelegate?

在我完成这个步骤后,我再次查看了-Swift.h文件,惊喜地发现我的代理已经暴露出来了,我可以像预期的那样在我的Objective-C文件中使用它。

希望这可以帮助到你。


2

最初的回答: "Gleen response is fine but you must add @objc to var delegate too"
weak var delegate: CuteDelegate?

0

我在这个问题上卡住了,直到我发现了另一个问题:我在Swift类定义中使用了@objcMembers,但是协议定义位于类定义之外,需要自己的@objc注释。


0
问题出在使用了 setdelegate 而不是 setDelegate(请注意小写的 delegate)。
尝试:
[(SwiftLoginViewController*)self.viewComponent setDelegate:self];
// or 
((SwiftLoginViewController*)self.viewComponent).delegate = self;

仍然出现错误,"在类型为'SwiftLoginViewController *'的对象上找不到属性'delegate'"。 - Shubham JAin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接