像 WhatsApp 一样取消语音留言 Swift

Canceling a Voice Note Like WhatsApp Swift

希望你们一切都好。我正在开发一个聊天模块,我可以在其中录制语音 memo/note。我的录音功能运行良好,但我想添加像 WhatsApp 这样的滑动手势。我想在按住按钮的同时向右滑动来停止录制。我正在寻找这样的东西:

Video of WhatsApp

谢谢

我自己想出来了。通过以下代码,您可以录制语音备忘录并可以通过滑动取消它

我已经使用这段代码实现了我想做的事情。

protocol SPKRecordViewDelegate: class {

    func SPKRecordViewDidSelectRecord(sender : SPKRecordView, button: UIView)
    func SPKRecordViewDidStopRecord(sender : SPKRecordView, button: UIView)
    func SPKRecordViewDidCancelRecord(sender : SPKRecordView, button: UIView)

}

class SPKRecordView: UIView {

    enum SPKRecordViewState {

        case Recording
        case None

    }

    var state : SPKRecordViewState = .None {

        didSet {

            UIView.animate(withDuration: 0.3) { () -> Void in

                self.slideToCancel.alpha = 1.0
                self.invalidateIntrinsicContentSize()
                self.setNeedsLayout()
                self.layoutIfNeeded()

            }

        }
    }

    let recordButton : UIButton = UIButton(type: .custom)
    let slideToCancel : UILabel = UILabel(frame: CGRect.zero)

    weak var delegate : SPKRecordViewDelegate?

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.translatesAutoresizingMaskIntoConstraints = false

        setupRecordButton()
        setupLabel()
    }

    func setupRecordButton() {

        recordButton.translatesAutoresizingMaskIntoConstraints = false
        addSubview(recordButton)
        let hConsts = NSLayoutConstraint.constraints(withVisualFormat: "H:[recordButton]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["recordButton":recordButton])
        self.addConstraints(hConsts)

        let vConsts = NSLayoutConstraint.constraints(withVisualFormat: "V:|[recordButton]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["recordButton":recordButton])
        self.addConstraints(vConsts)

        recordButton.setImage(UIImage(named: "mike")!, for: .normal)
        let longPress = UILongPressGestureRecognizer(target: self, action: #selector(userDidTapRecord(_:)))
        longPress.cancelsTouchesInView = false
        longPress.allowableMovement = 10
        longPress.minimumPressDuration = 0.2
        recordButton.addGestureRecognizer(longPress)

    }

    func setupLabel() {

        slideToCancel.translatesAutoresizingMaskIntoConstraints = false
        addSubview(slideToCancel)
        backgroundColor = UIColor.clear

        let hConsts = NSLayoutConstraint.constraints(withVisualFormat: "H:|[slideToCancel][bt]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["slideToCancel":slideToCancel,"bt":recordButton])
        self.addConstraints(hConsts)

        let vConsts = NSLayoutConstraint.constraints(withVisualFormat: "V:|[slideToCancel]|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["slideToCancel":slideToCancel])
        self.addConstraints(vConsts)

        slideToCancel.alpha = 0.0
        slideToCancel.font = UIFont(name: "Lato-Bold", size: 17)
        slideToCancel.textAlignment = .center
        slideToCancel.textColor = UIColor.black
    }


    override public var intrinsicContentSize: CGSize {
        if state == .none {
            return recordButton.intrinsicContentSize
        } else {

            return CGSize(width: recordButton.intrinsicContentSize.width * 3, height: recordButton.intrinsicContentSize.height)
        }
    }

    func userDidTapRecordThenSwipe(sender: UIButton) {
        slideToCancel.text = nil
        delegate?.SPKRecordViewDidCancelRecord(sender: self, button: sender)


    }

    func userDidStopRecording(sender: UIButton) {
        slideToCancel.text = nil
        delegate?.SPKRecordViewDidStopRecord(sender: self, button: sender)
    }

    func userDidBeginRecord(sender : UIButton) {
        slideToCancel.text = "check"
        delegate?.SPKRecordViewDidSelectRecord(sender: self, button: sender)

    }

    @objc func userDidTapRecord(_ sender: UIGestureRecognizer) {

        print("Long Tap")

        let button = sender.view as! UIButton

        let location = sender.location(in: button)

        print("Swipe location",location.x)


        var startLocation = CGPoint.zero

        switch sender.state {

        case .began:
            startLocation = location
            userDidBeginRecord(sender: button)
        case .changed:

            let translate = CGPoint(x: location.x - startLocation.x, y: location.y - startLocation.y)
            print("Swipe location new", translate)
            if translate.x <= -150 {

                if state == .Recording {
                    userDidTapRecordThenSwipe(sender: button)
                }
            }

        case .ended:

            if state == .None { return }

            let translate = CGPoint(x: location.x - startLocation.x, y: location.y - startLocation.y)



                userDidStopRecording(sender: button)



        case .failed, .possible ,.cancelled :

            if state == .Recording {
                userDidStopRecording(sender: button)
            }
            else {
                userDidTapRecordThenSwipe(sender: button)
            }
        }


    }


    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension IndividualChatViewController : SPKRecordViewDelegate {



    func SPKRecordViewDidCancelRecord(sender: SPKRecordView, button: UIView) {
        UIView.animate(withDuration: 2.0) {
              sender.state = .None
                  self.audioRecorder.stop()
                  self.customView.slideView.isHidden = true
                  self.CountTimer?.invalidate()
                  self.counter = 0
                  self.customView.timeCountLabel.text = "00:00"
                  self.CountTimer = nil
        }

    }

    func SPKRecordViewDidSelectRecord(sender: SPKRecordView, button: UIView) {
        sender.state = .Recording
        self.startRecordingVoice()



    }

    func SPKRecordViewDidStopRecord(sender : SPKRecordView, button: UIView) {

        sender.state = .None
        self.sendRecording()
        print("Done")
    }
}

然后调用一个全局变量

let myrecording = SPKRecordView(frame: CGRect.zero)

调用委托方法

 myrecording.delegate = self
        self.customView.recordButton.addSubview(rec)

            let hConsts = NSLayoutConstraint.constraints(withVisualFormat: "H:[bt(30)]-(5)-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["bt":rec])
            view.addConstraints(hConsts)

            let vConsts = NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[bt(30)]", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: ["bt":rec])
            view.addConstraints(vConsts)
        rec.recordButton.addTarget(self, action: #selector(stopRecording(_:)), for: .touchDragExit)

添加touchDragExit功能

@objc func stopRecording(_ sender : UIButton)
{


    self.audioRecorder.stop()
    self.recordingView.isHidden = true

    // Simply set the amplitude to whatever you need and the view will update itself.

}