Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 我希望通过1.5秒长的点击来启动实时流,但我的代码要求用户按住整个流的按钮_Ios_Swift_Uigesturerecognizer - Fatal编程技术网

Ios 我希望通过1.5秒长的点击来启动实时流,但我的代码要求用户按住整个流的按钮

Ios 我希望通过1.5秒长的点击来启动实时流,但我的代码要求用户按住整个流的按钮,ios,swift,uigesturerecognizer,Ios,Swift,Uigesturerecognizer,我需要允许用户通过按下额外的摄像头按钮约1.5秒,开始向朋友直播流媒体视频。然而,目前他们必须一直按住它,当他们从额外的摄像机按钮上取下手指时,摄像机视图被取消 我正在使用某人的旧代码,我刚刚将其从Swift 2.2转换为Swift 3,我看到了他们所做的,但是当我稍微修改它以获得长距离动作的最小持续时间时,我会出现致命错误 你们中的任何一个人会如何修改代码以允许1.5秒的长距离跳投,而不是无限期地按住它?在第58行,我有代码为长时间跳转添加最小持续时间,但添加它会导致各种错误,因为一旦松开按钮

我需要允许用户通过按下额外的摄像头按钮约1.5秒,开始向朋友直播流媒体视频。然而,目前他们必须一直按住它,当他们从额外的摄像机按钮上取下手指时,摄像机视图被取消

我正在使用某人的旧代码,我刚刚将其从Swift 2.2转换为Swift 3,我看到了他们所做的,但是当我稍微修改它以获得长距离动作的最小持续时间时,我会出现致命错误

你们中的任何一个人会如何修改代码以允许1.5秒的长距离跳投,而不是无限期地按住它?在第58行,我有代码为长时间跳转添加最小持续时间,但添加它会导致各种错误,因为一旦松开按钮,即使实时流已经开始,摄像仍然会被取消

import UIKit
import AVFoundation

protocol CameraViewDelegate {
func startStopRecordingVideo(_ isStart: Bool)
func startStopStream(_ isStart: Bool)
func cancelCameraView()
func changeCamera()
func chooseVideo()
}

class CameraView: UIView, UIGestureRecognizerDelegate {

@IBOutlet weak var flashBtn: UIButton!
@IBOutlet weak var screenView: UIView!
@IBOutlet weak var shootBtn: UIButton!
@IBOutlet weak var changeCameraBtn: UIButton!
@IBOutlet weak var cancelBtn: UIButton!
@IBOutlet weak var alphaView: UIView!
@IBOutlet weak var shootBtnContainerView: UIView!

var delegate : CameraViewDelegate?
var isRecording : Bool = false
var isStreaming: Bool = false

var circleLayer: CAShapeLayer?
var timer: Timer?

//MARK: SYSTEMS METHODS

class func instanceFromNib() -> CameraView {
    return UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil,     options: nil)[0] as! CameraView
}

override func awakeFromNib() {
    layoutIfNeeded()
    shootBtnContainerView.layer.cornerRadius =     shootBtnContainerView.frame.size.width/2
    shootBtn.layer.cornerRadius = shootBtn.frame.size.width/2

    let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
    tap.numberOfTapsRequired = 2
    shootBtn.addGestureRecognizer(tap)

    let hideTap = UITapGestureRecognizer(target: self, action: #selector(hideTapped))
    hideTap.delegate = self
    alphaView.addGestureRecognizer(hideTap)

    let hold = UILongPressGestureRecognizer(target: self, action: #selector(longTap))
    shootBtn.addGestureRecognizer(hold)
    //hold.minimumPressDuration = 1.5

    if Defaults.sharedDefaults.userKnowAboutCamera {
        alphaView.isHidden = true
    }

    let alert = UIAlertController(title: "Testing!", message: nil, preferredStyle: .alert)
    let action = UIAlertAction(title: "Thank You", style: .default, handler: nil)
    alert.addAction(action)

}

//MARK: - CIRcLE ANIMATION

func createCirclePath() {
    let circlePath = UIBezierPath(arcCenter: shootBtnContainerView.center, radius: shootBtnContainerView.frame.size.width/2, startAngle: 0.0, endAngle: CGFloat(.pi * 2.0), clockwise: true)

    circleLayer = CAShapeLayer()
    circleLayer!.path = circlePath.cgPath
    circleLayer!.fillColor = UIColor.clear.cgColor
    circleLayer!.strokeColor = UIColor.red.cgColor
    circleLayer!.lineWidth = 3.0;

    circleLayer!.strokeEnd = 0.0

    layer.addSublayer(circleLayer!)
}

func animateCircle(_ duration: TimeInterval) {
    circleLayer?.removeFromSuperlayer()
    createCirclePath()
    circleLayer!.strokeEnd = 0.0
    let animation = CABasicAnimation(keyPath: "strokeEnd")
    animation.duration = duration
    animation.fromValue = 0
    animation.toValue = 1
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    circleLayer!.strokeEnd = 1.0
    circleLayer!.add(animation, forKey: "animateCircle")
}


// SHOW HIDE ALPHA VIEW

func showHideAlphaView(_ isHide: Bool){
    Defaults.sharedDefaults.userKnowAboutCamera = true
    var alpha: Float = 0.0
    if isHide { alpha = 0.0 } else { alpha = 0.6 }

    UIView.animate(withDuration: 1.5, animations: {
        self.alphaView.alpha = CGFloat(alpha)
        }, completion: nil)
}

// ACTIONS

func hideTapped(){
    showHideAlphaView(true)
}

func doubleTapped() {
    delegate?.chooseVideo()
}

func longTap(_ sender: UILongPressGestureRecognizer) {
    print("tapping")
    if sender.state == .began {
        SSContact.shared.isStreaming(public: true, to: nil, verification: { (error) in
            if error != nil {
                print(error!.localizedDescription)
            }
        }, live: { (live, views) in
            print("Live: \(live) :: With \(views) Views!")
        })
        isRecording = !isRecording
        delegate?.startStopRecordingVideo(isRecording)
        isStreaming = !isStreaming
        delegate?.startStopStream(isStreaming)
    } else if sender.state == .ended {
        SSContact.shared.stopStreaming()
        isRecording = !isRecording
        delegate?.startStopRecordingVideo(isRecording)
        isStreaming = !isStreaming
        delegate?.startStopStream(isStreaming)
        delegate?.cancelCameraView()
    }
}

func updateTimer() {
    isRecording = !isRecording
    delegate?.startStopRecordingVideo(isRecording)
    timer?.invalidate()
}

@IBAction func shootVideo(_ sender: AnyObject) {
    if !isRecording{
        timer = Timer.scheduledTimer(timeInterval: 20.0, target: self, selector: #selector(CameraView.updateTimer), userInfo: nil, repeats: true)
        animateCircle(20)
    } else {
        timer?.invalidate()
        circleLayer?.removeAnimation(forKey: "animateCircle")
        circleLayer!.strokeEnd = 0.0
    }
    isRecording = !isRecording
    delegate?.startStopRecordingVideo(isRecording)
}

@IBAction func cancelPressed(_ sender: AnyObject) {
    delegate?.cancelCameraView()
}

@IBAction func changeCameraPressed(_ sender: AnyObject) {
    delegate?.changeCamera()
}

@IBAction func flashBtnPressed(_ sender: AnyObject) {
    let device = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeVideo)!
    if (device.hasTorch) {
        do {
            try device.lockForConfiguration()
            if device.torchMode == .on {
                device.torchMode = .off
                flashBtn.setImage(UIImage(named: "Flash"), for: UIControlState())
            } else {
                flashBtn.setImage(UIImage(named: "NoFlash"), for: UIControlState())
                do {
                    try device.setTorchModeOnWithLevel(1.0)
                } catch {
                    print(error.localizedDescription)
                }
            }
            device.unlockForConfiguration()
        } catch {
            print(error.localizedDescription)
        }
    }
}

@IBAction func loadVideoPressed(_ sender: AnyObject) {

}
}

您的
UILongPressGestureRegonizer
s目标是
longTap(:)
。每当手势识别器触发事件时,将执行此方法。让我们看看您对该方法的实现,然后:

func longTap(_ sender: UILongPressGestureRecognizer) {
    print("tapping")
    if sender.state == .began {
        // ...
        delegate?.startStopStream(isStreaming)
    } else if sender.state == .ended {
        SSContact.shared.stopStreaming()
        // ...
    }
}
我用
/…
替换了一些代码,以关注这里的重点。如您所见,
UILongPressGestureReconizer
可以有多个状态(另请参阅)。在您的代码中,您正在处理其中两个:
开始
结束

一旦您的手势被识别(即,用户已执行长按),手势识别器状态将为
.start
。在此
if
分支中,您将开始您的相机录制和流。另一方面,在
.end
分支中,您正在停止流。当手势结束时(即当用户抬起手指时,因为长按已结束),状态将为
.end


如果您希望流在长按后继续,只需删除
.ended
分支。

查看
UILongPressGestureRecognitor
LongPress方法,您可以说
If sender.state==.ended
基本上停止流,因此每当用户释放触摸键时,它就会停止:

func longTap(_ sender: UILongPressGestureRecognizer) {

    if sender.state == .began {
        // Start the stream
    } else if sender.state == .ended {
        SSContact.shared.stopStreaming()
        isRecording = !isRecording
        delegate?.startStopRecordingVideo(isRecording)
        isStreaming = !isStreaming
        delegate?.startStopStream(isStreaming)
        delegate?.cancelCameraView()
    }

}
我建议使用一种方法,根据
isRecording
布尔值管理流的启动和停止,并更改
isRecording
声明使用
didSet
的方式:

var isRecording: Bool = false {
    didSet{
        // Manage the stream based on how the variable is set
        self.manageStream(start: isRecording)
    }
}


func manageStream(start: Bool) {

    if start {
        // Start the stream
        SSContact.shared.isStreaming(public: true, to: nil, verification: { (error) in
            if error != nil {
                print(error!.localizedDescription)
            }
        }, live: { (live, views) in
            print("Live: \(live) :: With \(views) Views!")
        })
        isRecording = !isRecording
        delegate?.startStopRecordingVideo(isRecording)
        isStreaming = !isStreaming
        delegate?.startStopStream(isStreaming)
    }
    else {
        // Stop the stream
        SSContact.shared.stopStreaming()
        isRecording = !isRecording
        delegate?.startStopRecordingVideo(isRecording)
        isStreaming = !isStreaming
        delegate?.startStopStream(isStreaming)
        delegate?.cancelCameraView()
    }

}
现在,您可以使用longPress识别器启动和停止流媒体:

func longTap(_ sender: UILongPressGestureRecognizer) {

    isRecording = !isRecording

}
您甚至可以更改媒体的持续时间,比如说您希望最小的媒体持续时间远小于关闭流而不是打开流:

func longTap(_ sender: UILongPressGestureRecognizer) {

    isRecording = !isRecording
    if isRecording {
        // Make the minimum duration zero so they just need to tap to turn it off
        sender.minimumPressDuration = 0
    } else {
        // Make the minimum duration back to 1.5 seconds so they have to hold to turn it on
        sender.minimumPressDuration = 1.5
    }

}

查看您的
UILongPressGestureRecognitor
longTap
方法,您可以说
如果sender.state==.end
基本上停止流媒体,因此每当用户释放触摸时,它都会停止:我让它工作了!不得不对代码做一些细微的调整以适应一切,但现在一切都很顺利。谢谢@贾斯汀·霍奇斯-当然!祝你好运