【问题标题】:Swift callback from Objective-C来自 Objective-C 的 Swift 回调
【发布时间】:2018-12-13 15:57:39
【问题描述】:

在 Swift 应用程序中,我有一个 ViewController,它调用了一个新的 modal。这个modal 具有ViewController Objective-C 实现为ViewController_obj_c

这个modal 是从Swift 代码中显示出来的,我想在Objective-C 代码完成后调用回调属性(带有UIImage 参数)。

我的回调属性 "signCompleteCallback" 不起作用。如何从Swift 填充回调属性并在Objective-C 中调用它?

SwiftViewController.swift:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "showModalSegue" {
        if let nextVC = segue.destination as? ViewController_obj_c {

            nextVC.signCompleteCallback = #selector(self.Test)
        }
    }
}

@objc func Test(image: UIImage)
{
    debugPrint("Test method was called as callback with image parameter")
}

ViewController_obj_c.h:

@interface ViewController_obj_c : UIViewController <UIPopoverPresentationControllerDelegate>


@property SEL signCompleteCallback;

- (IBAction)Done_Clicked:(id)sender;

ViewController_obj_c.m:

- (IBAction)Done_Clicked:(UIButton *)sender
{
    UIGraphicsBeginImageContext(_dV.bounds.size);
    [_dV.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

   [self signCompleteCallback]; // Here is the point when I want to call me callback and as a parameter i want to send image
}

【问题讨论】:

    标签: objective-c swift callback delegates


    【解决方案1】:

    你为什么不使用 Objective-C block

    SwiftViewController.swift:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showModalSegue" {
            if let nextVC = segue.destination as? ViewController_obj_c {
    
                nextVC.signCompleteCallback = testMethod(image:) //`(image:)` is not needed when not ambiguous
            }
        }
    }
    
    func testMethod(image: UIImage) {
        debugPrint("Test method was called as callback with image parameter")
    }
    

    ViewController_obj_c.h:

    @interface ViewController_obj_c : UIViewController<UIPopoverPresentationControllerDelegate>
    
    typedef void (^signCompleteCallbackType)(UIImage * _Nonnull image); //Declare the block type
    
    @property signCompleteCallbackType signCompleteCallback; //Declare the block property using the block type
    
    - (IBAction)Done_Clicked:(id)sender;
    
    @end
    

    ViewController_obj_c.m:

    - (IBAction)Done_Clicked:(UIButton *)sender
    {
        UIGraphicsBeginImageContext(_dV.bounds.size);
        [_dV.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        self.signCompleteCallback(image);    //Use the block just like a normal function
    }
    

    【讨论】:

      【解决方案2】:

      我找到了一个解决方案,但我对他不满意。

      如果有人提供更好的解决方案,我会很高兴。在这个解决方案中,我不喜欢创建一个必须在 Swift 部件中继承的新协议(创建一个新类或在现有的 SwiftViewcontroller 中继承它,没关系)

      一种方法是在 Objective-C 中创建 @protocol

      @protocol ObjC_ManagerDelegate 
      -(void) signCallBack: (UIImage *)image;
      @end
      

      ViewController_obj_c.h:

      @interface ViewController_obj_c : UIViewController <UIPopoverPresentationControllerDelegate>
      
          @property (nonatomic, strong) id <ObjC_ManagerDelegate>delegate;
      
          - (IBAction)Done_Clicked:(id)sender;
      @end
      

      ViewController_obj_c.m:

      - (IBAction)Done_Clicked:(UIButton *)sender
      {
          UIGraphicsBeginImageContext(_dV.bounds.size);
          [_dV.layer renderInContext:UIGraphicsGetCurrentContext()];
          UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
          UIGraphicsEndImageContext();
      
          [self.delegate signCallBack:image];
      }
      

      Swift 部分看起来像这样。创建一个新类并从ObjC_ManagerDelegate继承它:

      class SwiftmanagerDelegate: ObjC_ManagerDelegate {
          func signCallBack(_ image: UIImage!) {
              // do something
          } 
      }
      

      最后以代表的身份填写新班级

      SwiftViewController.swift:

      override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
          if segue.identifier == "showModalSegue" {
              if let nextVC = segue.destination as? ViewController_obj_c {
      
                  nextVC.delegate = SwiftmanagerDelegate()
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多