跳转到内容
View in the app

A better way to browse. Learn more.

彼岸论坛

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.
欢迎抵达彼岸 彼岸花开 此处谁在 -彼岸论坛

[Swift] Swift 中系统 API delegate 参数一定要在当前类实现传 self 吗

发表于

因为要写原生插件,swift 刚接触,语法比 objc 好看多了。

在开发相机组件时遇到一个问题,AVCapturePhotoCaptureDelegate 契约用自定义 UIView/UIViewController 实现没问题, 换成独立的类实现就回调不了,不是什么原因。

上代码:

TakePhotoDelegate.swift

import Foundation
import AVFoundation
import UIKit

public typealias TakePhotoCallback = ((String, String) -> Void)?;

class TakePhotoWithCompletion : NSObject, AVCapturePhotoCaptureDelegate {

    // ...
    var completion: TakePhotoCallback;
    
    init(callback: TakePhotoCallback) {

        self.completion = callback;
        super.init();
    }

    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    
        // todo sth
    
        self.completion!("{file path}", "{error}");
        
    }
}


CameraxView.swift

import AVFoundation
import UIKit

class CameraxView: UIView {

    // ...

    @objc
    func takePhoto(options: Dictionary<String, String>, completion: TakePhotoCallback) {
        
        let photoSettings = AVCapturePhotoSettings.init(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])
        let delegate = TakePhotoWithCompletion.init(callback: completion)
        
        imageOutPut?.capturePhoto(with:photoSettings, delegate: delegate)

    }

  // ...
}

点击拍照按钮能听到快门声,但是 photoOutput 没有回调

如果换成如下自定义 UIView 实现 AVCapturePhotoCaptureDelegate 没有问题,能正常回调

import AVFoundation
import UIKit

class CameraxView: UIView, AVCapturePhotoCaptureDelegate {

    // ...
    var completion: TakePhotoCallback = nil;

    @objc
    func takePhoto(options: Dictionary<String, String>) {
        
        let photoSettings = AVCapturePhotoSettings.init(format:[AVVideoCodecKey:AVVideoCodecType.jpeg])

        self.completion = completion
        
        imageOutPut?.capturePhoto(with:photoSettings, delegate: self)

    }

    @objc
    func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
    
        // todo sth
    
        self.completion!("{file path}", "{error}");
        
    }

    // ...

}

有这个差异的原因是因为系统 API 的限制吗还是 swift 语言层面问题, 如果 takePhoto 方法希望传闭包参数回调拍照结果,正确应该怎么写。

(回调参数赋值给实例对象, 个人感觉是个很奇怪的做法)

Featured Replies

No posts to show

创建帐户或登录来提出意见

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.