Skip to content

Commit

Permalink
Merge pull request #6 from asim1mehta/onStartAfterAudioPlay
Browse files Browse the repository at this point in the history
OnStart called after audio finished playing and making 'touchDownAndUpGesture' work after 'moveGesture' has began
  • Loading branch information
3llomi authored May 23, 2021
2 parents 5a81480 + 50d1b5d commit f5f8e9c
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 59 deletions.
2 changes: 1 addition & 1 deletion Example/iRecordView/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ViewController: UIViewController,RecordViewDelegate {

recordView.trailingAnchor.constraint(equalTo: recordButton.leadingAnchor, constant: -20).isActive = true
recordView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10).isActive = true
recordView.bottomAnchor.constraint(equalTo: recordButton.bottomAnchor).isActive = true
recordView.centerYAnchor.constraint(equalTo: recordButton.centerYAnchor).isActive = true
recordButton.recordView = recordView

recordView.delegate = self
Expand Down
24 changes: 19 additions & 5 deletions Source/AudioPlayer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,18 @@ enum AudioPlayerSounds {
case start, end, error
}

class AudioPlayer {
class AudioPlayer: NSObject {

private var player: AVAudioPlayer!

var didFinishPlaying: ((Bool) -> Void)?

init() {
override init() {
player = AVAudioPlayer()
}

public func playAudioFile(soundType: AudioPlayerSounds) {

didFinishPlaying = nil

let bundle = Bundle(identifier: "org.cocoapods.iRecordView")

Expand All @@ -32,9 +34,14 @@ enum AudioPlayerSounds {
}

do {
player = try AVAudioPlayer(contentsOf: url)
try AVAudioSession.sharedInstance().setCategory(.playAndRecord)
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
try AVAudioSession.sharedInstance().setActive(true, options: .notifyOthersOnDeactivation)

player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.wav.rawValue)
player.delegate = self
player.prepareToPlay()
player.play()

} catch {

print("could not play audio file!")
Expand All @@ -57,3 +64,10 @@ enum AudioPlayerSounds {
}

}

extension AudioPlayer: AVAudioPlayerDelegate {
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
didFinishPlaying?(flag)
didFinishPlaying = nil
}
}
22 changes: 10 additions & 12 deletions Source/RecordButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ open class RecordButton: UIButton, UIGestureRecognizerDelegate {
setTitle("", for: .normal)

if image(for: .normal) == nil {
let image = UIImage.fromPod("mic_blue")
let image = UIImage.fromPod("mic_blue").withRenderingMode(.alwaysTemplate)
setImage(image, for: .normal)

tintColor = .blue
Expand All @@ -54,7 +54,7 @@ open class RecordButton: UIButton, UIGestureRecognizerDelegate {


touchDownAndUpGesture = iGesutreRecognizer(target: self, action: #selector(handleUpAndDown(_:)))
touchDownAndUpGesture.gestureDelegate = self
touchDownAndUpGesture.delegate = self


addGestureRecognizer(moveGesture)
Expand Down Expand Up @@ -89,7 +89,6 @@ open class RecordButton: UIButton, UIGestureRecognizerDelegate {
recordView.onTouchUp(recordButton: self)
}


@objc private func touchMoved(_ sender: UIPanGestureRecognizer) {
recordView.touchMoved(recordButton: self, sender: sender)
}
Expand All @@ -101,24 +100,23 @@ open class RecordButton: UIButton, UIGestureRecognizerDelegate {

case .ended:
recordView.onTouchUp(recordButton: self)

case .cancelled:
recordView.onTouchCancelled(recordButton: self)

default:
break
}
}

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return (gestureRecognizer == touchDownAndUpGesture && otherGestureRecognizer == moveGesture) || (gestureRecognizer == moveGesture && otherGestureRecognizer == touchDownAndUpGesture)
}


}

extension RecordButton: GesutreDelegate {
func onStart() {
recordView.onTouchDown(recordButton: self)
}

func onEnd() {
recordView.onTouchUp(recordButton: self)
}

extension RecordButton {
open override func layoutSubviews() {
super.layoutSubviews()
superview?.bringSubviewToFront(self)
Expand Down
90 changes: 59 additions & 31 deletions Source/RecordView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public class RecordView: UIView, CAAnimationDelegate {
public weak var delegate: RecordViewDelegate?
public var offset: CGFloat = 20
public var isSoundEnabled = true
public var buttonTransformScale: CGFloat = 2

public var slideToCancelText: String! {
didSet {
Expand Down Expand Up @@ -80,10 +81,6 @@ public class RecordView: UIView, CAAnimationDelegate {
return label
}()





private func setup() {
bucketImageView = BucketImageView(frame: frame)
bucketImageView.animationDelegate = self
Expand Down Expand Up @@ -111,14 +108,14 @@ public class RecordView: UIView, CAAnimationDelegate {
arrow.heightAnchor.constraint(equalToConstant: 15).isActive = true

slideToCancelStackVIew.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
slideToCancelStackVIew.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
slideToCancelStackVIew.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true


timerStackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
timerStackView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
timerStackView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true


mTransform = CGAffineTransform(scaleX: 2.0, y: 2.0)
mTransform = CGAffineTransform(scaleX: buttonTransformScale, y: buttonTransformScale)

audioPlayer = AudioPlayer()
}
Expand All @@ -134,8 +131,15 @@ public class RecordView: UIView, CAAnimationDelegate {
}

func onTouchUp(recordButton: RecordButton) {
guard !isSwiped else {
return
}
onFinish(recordButton: recordButton)
}

func onTouchCancelled(recordButton: RecordButton) {
onTouchCancel(recordButton: recordButton)
}


required public init?(coder aDecoder: NSCoder) {
Expand All @@ -151,9 +155,23 @@ public class RecordView: UIView, CAAnimationDelegate {

//this will be called when user starts tapping the button
private func onStart(recordButton: RecordButton) {
isSwiped = false

self.prepareToStartRecording(recordButton: recordButton)

if isSoundEnabled {
audioPlayer.playAudioFile(soundType: .start)
audioPlayer.didFinishPlaying = { [weak self] _ in
self?.delegate?.onStart()
}
} else {
delegate?.onStart()
}
}

private func prepareToStartRecording(recordButton: RecordButton) {
resetTimer()

isSwiped = false
//start timer
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateDuration), userInfo: nil, repeats: true)

Expand All @@ -174,26 +192,27 @@ public class RecordView: UIView, CAAnimationDelegate {
bucketImageView.isHidden = false
bucketImageView.resetAnimations()
bucketImageView.animateAlpha()

if isSoundEnabled {
audioPlayer.playAudioFile(soundType: .start)
}

delegate?.onStart()

}

//this will be called when user swipes to the left and cancel the record
private func onSwipe(recordButton: RecordButton) {
isSwiped = true

fileprivate func animateRecordButtonToIdentity(_ recordButton: RecordButton) {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
recordButton.transform = .identity
})


}

//this will be called when user swipes to the left and cancel the record
fileprivate func hideCancelStackViewAndTimeLabel() {
slideToCancelStackVIew.isHidden = true
timerLabel.isHidden = true
}

private func onSwipe(recordButton: RecordButton) {
isSwiped = true
audioPlayer.didFinishPlaying = nil

animateRecordButtonToIdentity(recordButton)

hideCancelStackViewAndTimeLabel()

if !isLessThanOneSecond() {
bucketImageView.animateBucketAndMic()
Expand All @@ -207,6 +226,23 @@ public class RecordView: UIView, CAAnimationDelegate {

delegate?.onCancel()
}

private func onTouchCancel(recordButton: RecordButton) {
isSwiped = false

audioPlayer.didFinishPlaying = nil

animateRecordButtonToIdentity(recordButton)

hideCancelStackViewAndTimeLabel()

bucketImageView.isHidden = true
delegate?.onAnimationEnd?()

resetTimer()

delegate?.onCancel()
}

private func resetTimer() {
timer?.invalidate()
Expand All @@ -217,7 +253,7 @@ public class RecordView: UIView, CAAnimationDelegate {
//this will be called when user lift his finger
private func onFinish(recordButton: RecordButton) {
isSwiped = false

audioPlayer.didFinishPlaying = nil
UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {
recordButton.transform = .identity
})
Expand All @@ -235,7 +271,6 @@ public class RecordView: UIView, CAAnimationDelegate {
}
} else {
if isSoundEnabled {

audioPlayer.playAudioFile(soundType: .end)
}
}
Expand All @@ -246,11 +281,10 @@ public class RecordView: UIView, CAAnimationDelegate {

}


//this will be called when user starts to move his finger
func touchMoved(recordButton: RecordButton, sender: UIPanGestureRecognizer) {

if isSwiped {
guard !isSwiped else {
return
}

Expand All @@ -273,18 +307,12 @@ public class RecordView: UIView, CAAnimationDelegate {
}

}

case .ended:
onFinish(recordButton: recordButton)


default:
break
}

}


}


Expand Down
19 changes: 9 additions & 10 deletions Source/iGesutreRecognizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,21 @@

import UIKit

protocol GesutreDelegate {
func onStart()
func onEnd()
}


class iGesutreRecognizer: UIGestureRecognizer {
var gestureDelegate: GesutreDelegate?


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
gestureDelegate?.onStart()
guard state != .began else {
return
}
state = .began
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
gestureDelegate?.onEnd()
state = .ended
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
state = .cancelled
}

}

0 comments on commit f5f8e9c

Please sign in to comment.