[英]Unable to call an Objective C class delegate from a Swift class
My issue here is that I need the "protocolMethod" in the OldViewController.m to be called from the NewViewController.swift in a delegate fashion.我的问题是我需要以委托方式从 NewViewController.swift 调用 OldViewController.m 中的“protocolMethod”。
The project I'm working on was completely written in Objective C, and there's a new View Controller that was written in Swift.我正在做的项目完全是用Objective C编写的,还有一个用Swift编写的新视图Controller。
The new View Controller is supposed to call a delegate method, conformed by the Objective C caller object, so the Objective C View Controller can process that call. The new View Controller is supposed to call a delegate method, conformed by the Objective C caller object, so the Objective C View Controller can process that call.
The app runs and the delegate is called from Swift, but never actually executed in the Objective C View Controller.应用程序运行并从 Swift 调用委托,但从未在目标 C 视图 Controller 中实际执行。
I've tried including all the sample files and the code that's supposed to be called, so here it is:我已经尝试包含所有示例文件和应该调用的代码,所以这里是:
MyProtocol.h我的协议.h
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
- (void)protocolMethod:(NSString*)input;
@end
My-Bridging-Header.h我的桥接Header.h
#ifndef My_Bridging_Header_h
#define My_Bridging_Header_h
#import <UIKit/UIKit.h>
#import "OldViewController.h"
#import "MyProtocol.h"
#endif
OldViewController.h OldViewController.h
#import <UIKit/UIKit.h>
@interface OldViewController : UIViewController
@end
OldViewController.m旧视图控制器.m
@interface OldViewController ()<MyProtocol>
@end
@implementation OldViewController
//THIS IS THE PROBLEM: NEVER GETS CALLED
- (void)protocolMethod:(NSString *)input {
NSLog(@"protocolMethod:%@", input);
}
- (IBAction)myButtonClicked:(UIButton *)sender {
NewViewController *newViewController =[self.storyboard instantiateViewControllerWithIdentifier:@"NewViewController"];
[newViewController setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self presentViewController:newViewController animated:YES completion:nil];
}
@end
NewViewController.swift NewViewController.swift
import UIKit
class NewViewController: UIViewController {
@objc weak var myProtocol: MyProtocol?
override func viewWillAppear(_ animated: Bool) {
self.myProtocol?.protocolMethod("testing 123")
}
}
Thank you for your help!谢谢您的帮助!
objective-C
protocol method in Objective-C class from Swift调用 Objective-C class 中的objective-C
协议方法从 ZAE832E9B5BDA2699DB45F3FA6AA8C556 define the protocol in Objective-c MyProtocol.h
在 Objective-c MyProtocol.h
中定义协议
#ifndef MyProtocol_h
#define MyProtocol_h
#import <Foundation/Foundation.h>
@protocol MyProtocol <NSObject>
@optional
- (void)protoMethod:(NSString *)input;
@end
#endif
define interface of LoginViewController.h
定义LoginViewController.h
的接口
#import <UIKit/UIKit.h>
#import "MyProtocol.h"
@class NewViewController; //declare knowledge of swift class
@interface LoginViewController : UIViewController <MyProtocol>
// method to trigger testing manual
-(void)haveFun;
@end
define implementation of LoginViewController.m
定义LoginViewController.m
的实现
#import "LoginViewController.h"
#import "YourProductModulName-Swift.h" // will bridge exposed swift class to objc
@implementation LoginViewController
-(void)protoMethod:(NSString*)input {
NSLog(@"protocolMethod:%@", input);
}
- (void)haveFun {
// did not use the storyboard to make testing simple
// this is an @objc exposed swift class
NewViewController *newViewController = [[NewViewController alloc] init];
// now trigger predefined method that checks for protocol
[newViewController fun:self];
}
@end
now let us write a swift class that is subclassing an NSObject, here UIViewController and expose it to objc现在让我们编写一个 swift class 是 NSObject 的子类,这里是 UIViewController 并将其公开给 objc
import Foundation
import UIKit
@objc //expose class when you need to use it from Objective-C
class NewViewController: UIViewController {
// as objc bridging is working with NSObjects,
// we can use it instead of Any, which can't be exposed.
@objc(foo) weak var foo : NSObject?
override func viewWillAppear(_ animated: Bool) {
// question was: how to call (id<MyProtocol>)-(void)protoMethod:
// as we dont use storyboard for testing here..
// nothing in here
}
// no autonaming, defined -(void)fun: instead
@objc(fun:) func fun(protocolObj: MyProtocol) {
let bar = protocolObj
bar.protoMethod!("direct invokation of protoMethod")
// ah why not, lets remember the object for later.
foo = bar as? NSObject
testme()
}
@objc func testme() {
// as foo is NSObject here, check if exist
if (foo != nil) {
// cast foo and check for protocol
if let loginview = foo as? MyProtocol {
loginview.protoMethod!("PROTOCOL-LOL!")
} else {
print("i will allways love youuu!")
}
}
}
}
now lets have some fun and use the back and forth bridged stuff.现在让我们玩得开心,并使用来回桥接的东西。 This will allocate a Objective-c class LoginViewController
following <MyProtocol>
and invoke -(void)haveFun
method.这将在<MyProtocol>
之后分配一个 Objective-c class LoginViewController
并调用-(void)haveFun
方法。 This method will allocate a Swift Class NewViewController
(important! based on NSObject) that will invoke @objc exposed swift func fun:
and give self
as parameter that must follow the MyProtocol.此方法将分配一个 Swift Class NewViewController
(重要!基于 NSObject),它将调用 @objc 暴露的self
func fun:
并给出 my 作为必须遵循的参数。 It will then invoke the protocol method of LoginViewController with a parameter NSString
and store the LoginViewController object in weak var foo
as NSObject
.然后它将使用参数NSString
调用 LoginViewController 的协议方法,并将 LoginViewController object 作为NSObject
存储在weak var foo
中。 Then it will trigger internal swift testme()
and use the stored foo
to check again if it exists and conforms to protocol MyProtocol and invokes the protocolMethod -(void)protoMethod:(NSString*)string;
然后它将触发内部 swift testme()
并使用存储的foo
再次检查它是否存在并符合协议 MyProtocol 并调用 protocolMethod -(void)protoMethod:(NSString*)string;
again or print something if not conforming.再次打印或打印不符合要求的内容。
LoginViewController *login = [[LoginViewController alloc] init];
[login haveFun];
Don't forget the example here needs Swift bridging to Objective-C and Objective-C bridging to Swift.不要忘记这里的示例需要 Swift 桥接到 Objective-C 和 Objective-C 桥接到 ZAE832E9B5BDA26996ZDB4。 If that is a perfect design pattern is another talk.如果这是一个完美的设计模式,那就另当别论了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.