You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift iOS应用:监听画中画模式左右滑动以关闭相机的方法

监听画中画滑动最小化并关闭相机的解决方案

你遇到的问题核心在于:用户滑动PiP视图到屏幕边缘最小化的操作,并不会触发AVPictureInPictureControllerDelegate的终止类代理方法(比如pictureInPictureControllerDidStopPictureInPicture:),这类操作仅会改变PiP视图的位置。要检测该行为,需要结合通知监听和位置判断来实现。

以下是具体实现步骤:

1. 初始化PiP控制器并添加通知监听

在你的视频通话视图控制器中,初始化AVPictureInPictureController时,同时注册两个关键通知,覆盖位置变化和状态变化场景:

import AVKit

class VideoCallVC: UIViewController, AVPictureInPictureControllerDelegate {
    private var pipController: AVPictureInPictureController?
    private var captureSession: AVCaptureSession? // 你的相机捕获会话实例
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 假设你已完成用于PiP的AVPlayerLayer初始化
        guard let playerLayer = yourVideoPlayerLayer else { return }
        
        pipController = AVPictureInPictureController(playerLayer: playerLayer)
        pipController?.delegate = self
        
        // 注册PiP位置变化通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handlePiPFrameChange),
            name: AVPictureInPictureController.pictureInPictureFrameDidChangeNotification,
            object: pipController
        )
        
        // 注册PiP状态变化通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handlePiPStateChange),
            name: AVPictureInPictureController.pictureInPictureStateDidChangeNotification,
            object: pipController
        )
    }

2. 检测PiP滑动到边缘的操作

在handlePiPFrameChange方法中,通过判断PiP视图的frame是否接近屏幕左右边缘,识别用户的最小化操作:

@objc private func handlePiPFrameChange(_ notification: Notification) {
        guard let pipController = notification.object as? AVPictureInPictureController else { return }
        let pipFrame = pipController.pictureInPictureFrame
        let screenBounds = UIScreen.main.bounds
        
        // 设置边缘检测阈值(可根据UI需求调整)
        let edgeThreshold: CGFloat = 20
        let isNearLeftEdge = pipFrame.origin.x <= edgeThreshold
        let isNearRightEdge = pipFrame.origin.x + pipFrame.width >= screenBounds.width - edgeThreshold
        
        if isNearLeftEdge || isNearRightEdge {
            // 用户将PiP滑动至边缘,执行关闭相机操作
            stopCamera()
        }
    }

3. 处理PiP主动关闭的情况

保留代理方法和状态变化通知,覆盖用户主动关闭PiP的场景:

@objc private func handlePiPStateChange(_ notification: Notification) {
        guard let pipController = notification.object as? AVPictureInPictureController else { return }
        if !pipController.isPictureInPictureActive {
            stopCamera()
        }
    }
    
    func pictureInPictureControllerDidStopPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
        stopCamera()
    }
    
    // 关闭相机的核心逻辑
    private func stopCamera() {
        if captureSession?.isRunning == true {
            captureSession?.stopRunning()
            // 可添加其他清理操作,比如释放捕获设备资源、置空相关实例
        }
    }

4. 清理通知监听

在控制器销毁时移除通知监听,避免内存泄漏:

deinit {
        NotificationCenter.default.removeObserver(self)
    }
}

补充说明

  • 边缘阈值可根据你的UI需求调整,阈值越小对滑动操作的检测越敏感;
  • 如果需要在用户将PiP从边缘滑回时重新开启相机,可在handlePiPFrameChange中增加反向位置判断逻辑;
  • 该方案兼容iOS 14及以上版本,若需支持更低版本,可提前检查通知的可用性。

内容的提问来源于stack exchange,提问作者bozkurt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 00:26:21