后退按钮启动 UIViewPropertyAnimator?
Back button starts a UIViewPropertyAnimator?
我有一个 ViewController 带摄像头的摄像头用于录制视频。顶部有一个旋转的圆圈,表示正在录制视频。这是这样设置的:
class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
private var animator: UIViewPropertyAnimator?
@objc func handleTap(_ gesture:UITapGestureRecognizer) {
if animator == nil {
createAnimation()
}
startRecording()
}
private func createAnimation() {
animator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 4, delay: 0, options: [.curveLinear,.allowUserInteraction], animations: {
UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .init(rotationAngle: .pi * 2 * 1 / 3)
}
UIView.addKeyframe(withRelativeStartTime: 1.0 / 3.0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .init(rotationAngle: .pi * 2 * 2 / 3)
}
UIView.addKeyframe(withRelativeStartTime: 2.0 / 3.0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .identity
}
})
}, completion: { [weak self] _ in
self?.createAnimation()
})
}
func startRecording() {
if movieOutput.isRecording == false {
animator?.startAnimation()
let connection = movieOutput.connection(with: AVMediaType.video)
if (connection?.isVideoOrientationSupported)! {
connection?.videoOrientation = currentVideoOrientation()
}
if (connection?.isVideoStabilizationSupported)! {
connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
}
let device = activeInput.device
if (device.isSmoothAutoFocusSupported) {
do {
try device.lockForConfiguration()
device.isSmoothAutoFocusEnabled = false
device.unlockForConfiguration()
} catch {
print("Error setting configuration: \(error)")
}
}
let outputFileName = NSUUID().uuidString
let outputFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent((outputFileName as NSString).appendingPathExtension("mov")!)
movieOutput.startRecording(to: URL(fileURLWithPath: outputFilePath), recordingDelegate: self)
}
else {
stopRecording()
}
}
func stopRecording() {
if movieOutput.isRecording == true {
animator?.pauseAnimation()
movieOutput.stopRecording()
}
}
@IBAction func unwindToCamera(sender: UIStoryboardSegue) {
}
...
}
extension CameraViewController: AVCaptureFileOutputRecordingDelegate{
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if (error != nil) {
print("Error recording movie: \(error!.localizedDescription)")
} else {
self.footageURL = outputFileURL as URL
//print(self.videoRecorded!)
self.performSegue(withIdentifier: "TrimFootage_Segue", sender: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "TrimFootage_Segue" {
let controller = segue.destination as! TrimFootageViewController
controller.footageURL = self.footageURL
}
}
}
所以它创建一个动画师,如果它不存在,然后调用启动动画的 startRecording。然后 stopRecording 停止它。然后,当视频完成录制到输出文件时,它会转到一个新的视图控制器。当我按回那个视图控制器时,它使用一个展开的 segue - unwindToCameraWithSender:
当我放松并回到相机时,视频没有录制,但动画正在播放。是什么导致这个动画重新开始?我怎样才能防止这种情况发生?
我认为只是动画暂停是原因。在 stopRecording()
方法中尝试
animator?.stopAnimation(true)
而不是
animator?.pauseAnimation()
所以我做了一件事来解决这个问题,但没有解决它,就是像这样使用 UIDynamicAnimator:
@objc func handleTap(_ gesture:UITapGestureRecognizer) {
startRecording()
if let rotate = rotate{
animator.removeBehavior(rotate)
self.rotate = nil
} else {
rotate = UIDynamicItemBehavior(items: [self.recordingSpinner])
rotate?.allowsRotation = true
rotate?.angularResistance = 0
rotate?.addAngularVelocity(1, for: self.recordingSpinner)
animator.addBehavior(rotate!)
}
}
取自这个答案:
有趣的是,当我执行 segue 时似乎没有开始旋转,尽管我不确定为什么。如果有人想知道我为什么愿意听他们说
我有一个 ViewController 带摄像头的摄像头用于录制视频。顶部有一个旋转的圆圈,表示正在录制视频。这是这样设置的:
class CameraViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
private var animator: UIViewPropertyAnimator?
@objc func handleTap(_ gesture:UITapGestureRecognizer) {
if animator == nil {
createAnimation()
}
startRecording()
}
private func createAnimation() {
animator = UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 4, delay: 0, options: [.curveLinear,.allowUserInteraction], animations: {
UIView.animateKeyframes(withDuration: 4, delay: 0, animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .init(rotationAngle: .pi * 2 * 1 / 3)
}
UIView.addKeyframe(withRelativeStartTime: 1.0 / 3.0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .init(rotationAngle: .pi * 2 * 2 / 3)
}
UIView.addKeyframe(withRelativeStartTime: 2.0 / 3.0, relativeDuration: 1.0 / 3.0) {
self.recordingSpinner.transform = .identity
}
})
}, completion: { [weak self] _ in
self?.createAnimation()
})
}
func startRecording() {
if movieOutput.isRecording == false {
animator?.startAnimation()
let connection = movieOutput.connection(with: AVMediaType.video)
if (connection?.isVideoOrientationSupported)! {
connection?.videoOrientation = currentVideoOrientation()
}
if (connection?.isVideoStabilizationSupported)! {
connection?.preferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.auto
}
let device = activeInput.device
if (device.isSmoothAutoFocusSupported) {
do {
try device.lockForConfiguration()
device.isSmoothAutoFocusEnabled = false
device.unlockForConfiguration()
} catch {
print("Error setting configuration: \(error)")
}
}
let outputFileName = NSUUID().uuidString
let outputFilePath = (NSTemporaryDirectory() as NSString).appendingPathComponent((outputFileName as NSString).appendingPathExtension("mov")!)
movieOutput.startRecording(to: URL(fileURLWithPath: outputFilePath), recordingDelegate: self)
}
else {
stopRecording()
}
}
func stopRecording() {
if movieOutput.isRecording == true {
animator?.pauseAnimation()
movieOutput.stopRecording()
}
}
@IBAction func unwindToCamera(sender: UIStoryboardSegue) {
}
...
}
extension CameraViewController: AVCaptureFileOutputRecordingDelegate{
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if (error != nil) {
print("Error recording movie: \(error!.localizedDescription)")
} else {
self.footageURL = outputFileURL as URL
//print(self.videoRecorded!)
self.performSegue(withIdentifier: "TrimFootage_Segue", sender: nil)
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?){
if segue.identifier == "TrimFootage_Segue" {
let controller = segue.destination as! TrimFootageViewController
controller.footageURL = self.footageURL
}
}
}
所以它创建一个动画师,如果它不存在,然后调用启动动画的 startRecording。然后 stopRecording 停止它。然后,当视频完成录制到输出文件时,它会转到一个新的视图控制器。当我按回那个视图控制器时,它使用一个展开的 segue - unwindToCameraWithSender:
当我放松并回到相机时,视频没有录制,但动画正在播放。是什么导致这个动画重新开始?我怎样才能防止这种情况发生?
我认为只是动画暂停是原因。在 stopRecording()
方法中尝试
animator?.stopAnimation(true)
而不是
animator?.pauseAnimation()
所以我做了一件事来解决这个问题,但没有解决它,就是像这样使用 UIDynamicAnimator:
@objc func handleTap(_ gesture:UITapGestureRecognizer) {
startRecording()
if let rotate = rotate{
animator.removeBehavior(rotate)
self.rotate = nil
} else {
rotate = UIDynamicItemBehavior(items: [self.recordingSpinner])
rotate?.allowsRotation = true
rotate?.angularResistance = 0
rotate?.addAngularVelocity(1, for: self.recordingSpinner)
animator.addBehavior(rotate!)
}
}
取自这个答案:
有趣的是,当我执行 segue 时似乎没有开始旋转,尽管我不确定为什么。如果有人想知道我为什么愿意听他们说