如何使用 Swift 协议功能,如 Android 接口监听器实现?

Posted

技术标签:

【中文标题】如何使用 Swift 协议功能,如 Android 接口监听器实现?【英文标题】:How can I use Swift protocol function like as Android interface listener implement? 【发布时间】:2019-01-11 05:48:25 【问题描述】:

我是韩国 android 开发人员,是 Swift 的新人。 我正在将我的 android 应用程序迁移到 ios,但遇到接口和侦听器问题。我不知道如何实现监听器在自定义视图和视图控制器之间进行通信。

我有一个自定义视图(即 MyView),它有两个按钮,每个按钮都有自己的功能。 在 Android(使用 Java)中,我通常在 MyView 中创建一个侦听器接口,并在内部分配两个函数,如 void func1( String val1 ) 和 func2...

public class MyView extends RelativeLayout 
private Button b1, b2;
private String val1, val2;

public interface OnButtonListener 
    void onFunc1(String val1);

    void onFunc2(String val2);


private OnButtonListener onButtonListener;

public void setOnButtonListener( OnButtonListener onButtonListener ) 
    this.onButtonListener = onButtonListener;


  public MyView( Context context, AttributeSet attrs ) 
    super( context, attrs );
    b1.setOnClickListener( view -> 
        if (onButtonListener != null)
            onButtonListener.onFunc1( val1 );
        
     );
    b2.setOnClickListener( view -> 
        if (onButtonListener != null)
            onButtonListener.onFunc1( val2 );
        
     );



 public class MyActivity extends Activity 
    MyView myView1, myView2;

@Override
protected void onCreate( @Nullable Bundle savedInstanceState ) 
    super.onCreate( savedInstanceState );
    myView1.setOnButtonListener( new MyView.OnButtonListener() 
        @Override
        public void onFunc1( String val1 ) 
            Log.d(TAG, val1);
        

        @Override
        public void onFunc2( String val2 ) 
            Log.d(TAG, val2);
        
     );
    myView2.setOnButtonListener( new MyView.OnButtonListener() 
        @Override
        public void onFunc1( String val1 ) 
            // do something1
        

        @Override
        public void onFunc2( String val2 ) 
            // do something2
        
     );


这段代码完全符合我的要求。所以我尝试将相同的模式应用到 Swift 中,但我找不到任何方法。

下面是 swift 4

import Foundation
import UIKit
import SnapKit

protocol OnButtonListener 
    func onButton1( _ val1: String )
     func onButton2( _ val2: String )


class MyView: UIView 
var onButtonListener: OnButtonListener?
var val1 = "abc"
var val2 = "123"

override init( frame: CGRect ) 
    super.init( frame: frame )
    let b1 = UIButton()
    let b2 = UIButton() // i'm using snapkit
    b1.addTarget(self, action: #selector(onB1), for: .touchUpInside)
    b2.addTarget(self, action: #selector(onB2), for: .touchUpInside)


@objc func onB1() 
    if onButtonListener != nil 
        onButtonListener!.onButton1(val1 )
    


@objc func onB2() 
    if onButtonListener != nil 
        onButtonListener!.onButton2(val2 )
    



class MyVC : UIViewController 
   override func viewDidLoad() 
    super.viewDidLoad()
    let myView1 = MyView()
    let myView2 = MyView()

    myView1.onButtonListener = 
        // ???
    
    myView2.onButtonListener = 
        // ???
    


我不知道如何在 ViewContorller 中实现监听器。我尝试过与 Kotlin 相同的方法,但我也没有工作。感谢您的阅读。

【问题讨论】:

只需声明您的viewController 符合协议OnButtonListener 并实现onButten1 和onButton2。并将带有myView.onButtonListener = self 的viewController 分配给视图的onButtonListener 属性。 【参考方案1】:

您必须在视图控制器中设置委托并在视图控制器中实现协议方法

class MyVC : UIViewController, OnButtonListener 
    override func viewDidLoad() 
         super.viewDidLoad()
         let myView1 = MyView()
           myView1. onButtonListener = self
         let myView2 = MyView()
           myView2. onButtonListener = self


      

   func onButton1( _ val1: String ) 
         print(val1)
   

   func onButton2( _ val2: String ) 
          print(val2)
   



**方法2:**也可以使用block

class MyView: UIView  
   var buttonAction : ((_ value : String) -> Void)? = nil
  //.... your code 

  @objc func onB1() 
       if let action = buttonAction 
           action("abc")
        
  

  @objc func onB2() 
    if let action = buttonAction 
           action("xyz")
        
  


在你的 ViewController 中

  override func viewDidLoad() 
     super.viewDidLoad()
     let myView1 = MyView()
       myView1.buttonAction =  value in 
         print(value)
        
  

【讨论】:

顺便说一句,命名闭包参数的推荐约定只是类型,而不是名称(_ value : String) -> (String)【参考方案2】:

如下更新您的视图控制器代码:

首先向 UIViewController 确认你的 OnButtonListener 协议,并在你的视图控制器中实现协议方法。

class MyVC : UIViewController, OnButtonListener 
    override func viewDidLoad() 
        super.viewDidLoad()

        let myView1 = MyView()

        // Confirm protocol implementation in current view controller
        myView1.onButtonListener = self 

        let myView2 = MyView()

        // Confirm protocol implementation in current view controller
        myView2.onButtonListener = self
    

    func onButton1( _ val1: String) 
        // your code
    

    func onButton2( _ val2: String) 
        // your code
    

【讨论】:

以上是关于如何使用 Swift 协议功能,如 Android 接口监听器实现?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 DataProvider 类 Alamofire 函数 swift 中设置协议函数不能正确调用

Swift学习笔记十六:协议

swift中的protocol和OC中protocol的区别

swift 学习- 24 -- 协议 01

swift3.0 扩展协议

如何在模型中使用 swift 协议 [关闭]