Swift 4:以编程方式创建的按钮addTarget在委托类中崩溃

时间:2018-08-22 02:20:13

标签: ios swift delegates protocols

我已经创建了一个委托协议,该协议创建一个UIButton并将其添加到父视图中。

protocol ButtonInputFactoryDelegate {
    func buttonAction(in formFactory: SubmitInputFactory)
}

在委托类中,我有两种方法,一种用于创建按钮,第二种用于实现委托的按钮动作。

class myButtonClass {

    (...)

    func setupButton() {
        guard let delegate = self.delegate else { return }

        // Button creation and setup

        submitButton.addTarget(self.parentViewController, action: #selector(internalButtonAction(_:)), for: .touchUpInside)

        self.parentViewController.view.addSubview(submitButton)
    }

    @objc func internalButtonAction(_ sender: UIButton) {
        guard let delegate = self.delegate else { return }

        delegate.buttonAction(in: self)
    }
}

在viewController中,我有以下内容

class TestViewController: UIViewController, ButtonInputFactoryDelegate {
    override func viewDidLoad() {
        (...)
        myButtonClass.delegate = self
        myButtonClass.setupButton()
    }

    func buttonAction(in formFactory: SubmitInputFactory) {
        print("Test")
    }
}

然后,当单击按钮时,它应被命名为internalButtonAction并在delegate.buttonAction内部执行

Xcode编译时没有错误,但是点击按钮时会出现以下错误

(...) unrecognized selector sent to instance 0x102139200

有什么想法会发生什么? 谢谢!

2 个答案:

答案 0 :(得分:0)

如果您的<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/topLayout" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.mattdonders.android.wppcalculator.barcode.CameraSourcePreview android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_barcode_scanner); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); mPreview = (CameraSourcePreview) findViewById(R.id.camera_preview); // Check for the camera permission before accessing the camera. If the // permission is not granted yet, request permission. int rc = ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (rc == PackageManager.PERMISSION_GRANTED) { createCameraSource(); } else { requestCameraPermission(); } } 方法在同一类中,则应将public CameraSourcePreview(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mStartRequested = false; mSurfaceAvailable = false; mSurfaceView = new SurfaceView(context); mSurfaceView.getHolder().addCallback(new SurfaceCallback()); addView(mSurfaceView); } 更改为setupButton

答案 1 :(得分:0)

在按钮类中,将操作添加到按钮:

class MyButtonClass {

    var submitButton: UIButton = UIButton()

    (...)

    func setSubmitAction(_ target: Any, action: Selector) {
        self.submitButton.addTarget(target, action: action, for: .touchUpInside)
    }
}

在ViewController上使用它时,必须采用这种方式:

myButtonClassInstance().setSubmitAction(self, action: #selector(self.submitButtonAction(_:)))

在ViewController中定义的动作如下:

@objc func submitButtonAction(_ sender: UIButton) {

    print("Test")
}

需要@objc才能将函数作为选择器传递。