你如何实现与 ReplayKit 的共享?
How do you implement sharing with ReplayKit?
我正在尝试使用 ReplayKit 来录制我的应用程序,然后让用户选择共享或删除录音。删除工作正常,但我无法让共享部分正常工作。我尝试将 RPPreviewViewControllerMode 与 .shared 一起使用,但 XCode 无法识别它。我还尝试了 UIActivityViewController,它会弹出共享菜单 - 但是,如果我尝试访问录音,它就不起作用。最后,我尝试了 previewControllerDelegate,它允许用户编辑和保存视频,但不能分享。
我已经在下面发布了我的代码。请指教,谢谢!
import UIKit
import ReplayKit
class ViewController: UIViewController, RPPreviewViewControllerDelegate {
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var imagePicker: UISegmentedControl!
@IBOutlet weak var selectedImageView: UIImageView!
@IBOutlet weak var micToggle: UISwitch!
@IBOutlet weak var recordButton: UIButton!
var recorder = RPScreenRecorder.shared()
private var isRecording = false
@IBAction func imagePicked(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
selectedImageView.image = UIImage(named: "skate")
case 1:
selectedImageView.image = UIImage(named: "food")
case 2:
selectedImageView.image = UIImage(named: "cat")
case 3:
selectedImageView.image = UIImage(named: "nature")
default:
selectedImageView.image = UIImage(named: "skate")
}
}
@IBAction func recordButtonPressed(_ sender: Any) {
if !isRecording {
startRecording()
} else {
stopRecording()
}
}
func startRecording() {
guard recorder.isAvailable else {
print("Recording not available at this time")
return
}
if micToggle.isOn {
recorder.isMicrophoneEnabled = true
} else {
recorder.isMicrophoneEnabled = false
}
recorder.startRecording { (error) in
guard error == nil else {
print("There was an error startng the recording.")
return
}
//Call DispatchQueue to update UI in the main thread rather than background
DispatchQueue.main.async {
self.micToggle.isEnabled = false
self.recordButton.setTitleColor(#colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1), for: .normal)
self.recordButton.setTitle("Stop", for: .normal)
self.statusLabel.textColor = #colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1)
self.statusLabel.text = "Recording..."
self.isRecording = true
print("Started Recording")
}
}
}
func stopRecording() {
recorder.stopRecording { (preview, error) in
guard preview != nil else {
print("Preview controller not available")
return
}
let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
)
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
self.recorder.discardRecording {
print("Recording discarded successfully.")
}
})
//First try:
let recordedVideo = "Video goes here!" //I don't know how to modify this to get the video content.
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [recordedVideo], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
//Second try:
//This allows me to edit and save the video, but not share it.
let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
preview?.previewControllerDelegate = self
self.present(preview!, animated: true, completion: nil)
})
// //Third try: not working!
// var mode: RPPreviewViewControllerMode
// let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
// preview?.mode = .share // The error is: 'mode' has been explicitly marked unavailable here (ReplayKit.RPPreviewViewController)
// preview?.previewControllerDelegate = self
// self.present(preview!, animated: true, completion: nil)
// })
alert.addAction(deleteAction)
alert.addAction(shareAction)
self.present(alert, animated: true, completion: nil)
self.isRecording = false
self.viewReset()
}
}
func viewReset() {
micToggle.isEnabled = true
statusLabel.text = "Ready to Record"
statusLabel.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
recordButton.setTitle("Record", for: .normal)
recordButton.setTitleColor(#colorLiteral(red: 0.2994912565, green: 0.7500386834, blue: 0.3387371898, alpha: 1), for: .normal)
}
func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
dismiss(animated: true, completion: nil)
}
}
可能是因为 .automatic
模态显示,因为在 iOS 13 中,当您弹出控制器时,它不会覆盖全屏。所以,试试 .fullScreen
,它对我有帮助:
func stopRecording() {
recorder.stopRecording { (preview, error) in
guard preview != nil else {
print("Preview controller not available")
return
}
let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
)
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
self.recorder.discardRecording {
print("Recording discarded successfully.")
}
})
let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
// Try .fullScreen
preview?.modalPresentationStyle = .fullScreen
preview?.previewControllerDelegate = self
self.present(preview!, animated: true, completion: nil)
})
alert.addAction(deleteAction)
alert.addAction(shareAction)
self.present(alert, animated: true, completion: nil)
self.isRecording = false
self.viewReset()
}
}
我正在尝试使用 ReplayKit 来录制我的应用程序,然后让用户选择共享或删除录音。删除工作正常,但我无法让共享部分正常工作。我尝试将 RPPreviewViewControllerMode 与 .shared 一起使用,但 XCode 无法识别它。我还尝试了 UIActivityViewController,它会弹出共享菜单 - 但是,如果我尝试访问录音,它就不起作用。最后,我尝试了 previewControllerDelegate,它允许用户编辑和保存视频,但不能分享。
我已经在下面发布了我的代码。请指教,谢谢!
import UIKit
import ReplayKit
class ViewController: UIViewController, RPPreviewViewControllerDelegate {
@IBOutlet weak var statusLabel: UILabel!
@IBOutlet weak var imagePicker: UISegmentedControl!
@IBOutlet weak var selectedImageView: UIImageView!
@IBOutlet weak var micToggle: UISwitch!
@IBOutlet weak var recordButton: UIButton!
var recorder = RPScreenRecorder.shared()
private var isRecording = false
@IBAction func imagePicked(_ sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
selectedImageView.image = UIImage(named: "skate")
case 1:
selectedImageView.image = UIImage(named: "food")
case 2:
selectedImageView.image = UIImage(named: "cat")
case 3:
selectedImageView.image = UIImage(named: "nature")
default:
selectedImageView.image = UIImage(named: "skate")
}
}
@IBAction func recordButtonPressed(_ sender: Any) {
if !isRecording {
startRecording()
} else {
stopRecording()
}
}
func startRecording() {
guard recorder.isAvailable else {
print("Recording not available at this time")
return
}
if micToggle.isOn {
recorder.isMicrophoneEnabled = true
} else {
recorder.isMicrophoneEnabled = false
}
recorder.startRecording { (error) in
guard error == nil else {
print("There was an error startng the recording.")
return
}
//Call DispatchQueue to update UI in the main thread rather than background
DispatchQueue.main.async {
self.micToggle.isEnabled = false
self.recordButton.setTitleColor(#colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1), for: .normal)
self.recordButton.setTitle("Stop", for: .normal)
self.statusLabel.textColor = #colorLiteral(red: 0.521568656, green: 0.1098039225, blue: 0.05098039284, alpha: 1)
self.statusLabel.text = "Recording..."
self.isRecording = true
print("Started Recording")
}
}
}
func stopRecording() {
recorder.stopRecording { (preview, error) in
guard preview != nil else {
print("Preview controller not available")
return
}
let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
)
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
self.recorder.discardRecording {
print("Recording discarded successfully.")
}
})
//First try:
let recordedVideo = "Video goes here!" //I don't know how to modify this to get the video content.
let activityViewController : UIActivityViewController = UIActivityViewController(
activityItems: [recordedVideo], applicationActivities: nil)
self.present(activityViewController, animated: true, completion: nil)
//Second try:
//This allows me to edit and save the video, but not share it.
let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
preview?.previewControllerDelegate = self
self.present(preview!, animated: true, completion: nil)
})
// //Third try: not working!
// var mode: RPPreviewViewControllerMode
// let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
// preview?.mode = .share // The error is: 'mode' has been explicitly marked unavailable here (ReplayKit.RPPreviewViewController)
// preview?.previewControllerDelegate = self
// self.present(preview!, animated: true, completion: nil)
// })
alert.addAction(deleteAction)
alert.addAction(shareAction)
self.present(alert, animated: true, completion: nil)
self.isRecording = false
self.viewReset()
}
}
func viewReset() {
micToggle.isEnabled = true
statusLabel.text = "Ready to Record"
statusLabel.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
recordButton.setTitle("Record", for: .normal)
recordButton.setTitleColor(#colorLiteral(red: 0.2994912565, green: 0.7500386834, blue: 0.3387371898, alpha: 1), for: .normal)
}
func previewControllerDidFinish(_ previewController: RPPreviewViewController) {
dismiss(animated: true, completion: nil)
}
}
可能是因为 .automatic
模态显示,因为在 iOS 13 中,当您弹出控制器时,它不会覆盖全屏。所以,试试 .fullScreen
,它对我有帮助:
func stopRecording() {
recorder.stopRecording { (preview, error) in
guard preview != nil else {
print("Preview controller not available")
return
}
let alert = UIAlertController(title: "Recording finished", message: "Would you like to share or delete your recording?", preferredStyle: .alert
)
let deleteAction = UIAlertAction(title: "Delete", style: .destructive, handler: { (action) in
self.recorder.discardRecording {
print("Recording discarded successfully.")
}
})
let shareAction = UIAlertAction(title: "Share", style: .default, handler: { (action) in
// Try .fullScreen
preview?.modalPresentationStyle = .fullScreen
preview?.previewControllerDelegate = self
self.present(preview!, animated: true, completion: nil)
})
alert.addAction(deleteAction)
alert.addAction(shareAction)
self.present(alert, animated: true, completion: nil)
self.isRecording = false
self.viewReset()
}
}