Вот быстрый класс 3 UIImagePickerController, который позволит пользователю захватывать видео, только если камера находится в альбомной ориентации.
Когда вы создаете свой UIImagePickerController:
var imagePicker = CameraVideo_ViewController()
Вам необходимо иметь это также и в вашем делегате:
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
self.imagePicker.isInFinalScreen = false
}
И это класс.У меня нет времени, чтобы привести его в порядок, и это действительно грязно ... Я создал этот класс, пытаясь сделать все возможное, не удаляя стандартные элементы управления.Была использована куча хаков, поэтому будьте очень осторожны при удалении переменных, потому что большинство из них считается, даже если они кажутся бесполезными. Я попытаюсь опубликовать более чистую версию, когда найду время, но до тех пор, если кто-то сможет опубликовать более чистый и более новичокдружественная версия этого I / мы будем благодарны.
import UIKit
import AVFoundation;
class CameraVideo_ViewController: UIImagePickerController {
var viewMain:UIView!
var lastOrientationWasLandscape:UIDeviceOrientation?
var isForLibrary:Bool! = false
var parentController:UIViewController!
override func viewDidAppear(_ animated: Bool) {
if isForLibrary == true {
return
}
let orientation = UIDevice.current.orientation
if orientation == .landscapeLeft || orientation == .landscapeRight {
lastOrientationWasLandscape = orientation
}
if (self.isInFinalScreen == true){
self.recordBut.frame = CGRect(x: self.view.frame.size.width - 70 - 16, y: self.view.frame.size.height / 2 - 35, width: 70, height: 70)
self.isInFinalScreen = false
}
recordBut.alpha = 1
recordBut.isUserInteractionEnabled = true
retakeBut.alpha = 1
retakeBut.isUserInteractionEnabled = true
UIDevice.current.beginGeneratingDeviceOrientationNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged(_:)), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
let notif = Notification.init(name: NSNotification.Name.UIDeviceOrientationDidChange)
orientationChanged(notif)
}
override func viewWillDisappear(_ animated: Bool) {
viewMain.alpha = 0
viewMain.isUserInteractionEnabled = false
lastOrientationWasLandscape = nil
recordBut.alpha = 0
recordBut.isUserInteractionEnabled = false
retakeBut.alpha = 0
retakeBut.isUserInteractionEnabled = false
self.viewMain.alpha = 0
self.viewMain.isUserInteractionEnabled = false
isInFinalScreenBool = false
recordedThisSession = false
if isForLibrary == true {
return
}
print("hidingCameraView")
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
UIDevice.current.endGeneratingDeviceOrientationNotifications()
}
override func viewDidLoad() {
super.viewDidLoad()
if isForLibrary == true {
return
}
viewMain = UIView()
viewMain.frame = CGRect(x: view.frame.minX, y: view.frame.minY, width: view.frame.width, height: view.frame.height)
viewMain.backgroundColor = UIColor.clear
let viewBg = UIView()
viewBg.frame = CGRect(x: view.frame.minX, y: view.frame.minY, width: view.frame.width, height: view.frame.height)
viewBg.backgroundColor = UIColor.black
viewBg.alpha = 0.5
let viewAlertBg = UIView()
viewAlertBg.frame = CGRect(x: view.frame.width/2 - 250/2, y: view.frame.height/2 - 100/2 - 25, width: 250, height: 100)
viewAlertBg.backgroundColor = UIColor.white
viewAlertBg.alpha = 1
viewAlertBg.clipsToBounds = true;
var path = UIBezierPath(roundedRect:viewAlertBg.bounds,
byRoundingCorners:[.topLeft, .topRight],
cornerRadii: CGSize(width: 25, height: 25))
var maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
viewAlertBg.layer.mask = maskLayer
let viewAlertBgUnderline = UIView()
viewAlertBgUnderline.frame = CGRect(x: view.frame.width/2 - 250/2, y: viewAlertBg.frame.maxY, width: 250, height: 1)
viewAlertBgUnderline.backgroundColor = UIColor.lightGray
viewAlertBgUnderline.alpha = 1
viewAlertBgUnderline.clipsToBounds = true;
let viewAlertCancelBut = UIButton()
viewAlertCancelBut.frame = CGRect(x: view.frame.width/2 - 250/2, y: viewAlertBgUnderline.frame.maxY, width: 250, height: 50)
viewAlertCancelBut.backgroundColor = UIColor.white
viewAlertCancelBut.setTitle("Back", for: .normal)
viewAlertCancelBut.setTitleColor(UIColor.blue, for: .normal)
path = UIBezierPath(roundedRect:viewAlertCancelBut.bounds,
byRoundingCorners:[.bottomLeft, .bottomRight],
cornerRadii: CGSize(width: 25, height: 25))
maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath
viewAlertCancelBut.layer.mask = maskLayer
viewAlertCancelBut.addTarget(self, action: #selector(onBack(_:)), for: .touchUpInside)
let alertLabel = UILabel()
alertLabel.numberOfLines = 4
alertLabel.frame = CGRect(x: 16, y: 16, width: 250 - 32, height: 100 - 32)
alertLabel.textAlignment = NSTextAlignment.center
alertLabel.adjustsFontSizeToFitWidth = true
alertLabel.font = UIFont.systemFont(ofSize: 12)
alertLabel.backgroundColor = UIColor.clear
alertLabel.textColor = UIColor.black
let boldText = "The video must be recorded in landscape mode.\n"
let normalText = "Please hold your device in a horizontal position!"
let attrs = [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 13)]
let boldString = NSMutableAttributedString(string:boldText, attributes:attrs)
let attributedString = NSMutableAttributedString(string:"")
attributedString.append(boldString)
attributedString.append(NSMutableAttributedString(string:normalText, attributes:nil))
alertLabel.attributedText = attributedString
viewAlertBg.addSubview(alertLabel)
viewMain.addSubview(viewBg)
viewMain.addSubview(viewAlertCancelBut)
viewMain.addSubview(viewAlertBg)
viewMain.addSubview(viewAlertBgUnderline)
viewMain.alpha = 0
viewMain.isUserInteractionEnabled = false
// Start/ Stop fake button
recordBut = UIButton()
if (UIDevice.current.userInterfaceIdiom == .phone){
recordBut.frame = CGRect(x: self.view.frame.size.width / 2 - 35, y: self.view.frame.size.height - 70 - 2, width: 70, height: 70)
}else{
recordBut.frame = CGRect(x: self.view.frame.size.height - 70 - 16, y: self.view.frame.size.width/2 - 35, width: 70, height: 70)
}
recordBut.setTitle("", for: .normal)
recordBut.setTitleColor(UIColor.blue, for: .normal)
recordBut.isUserInteractionEnabled = true
recordBut.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.5)
recordBut.addTarget(self, action: #selector(tapped(_:)), for: .touchUpInside)
self.view.addSubview(recordBut)
retakeBut = UIButton()
if (UIDevice.current.userInterfaceIdiom == .phone){
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}else{
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.width - 70, width: 80, height: 70)
}
retakeBut.setTitle("", for: .normal)
retakeBut.setTitleColor(UIColor.blue, for: .normal)
retakeBut.isUserInteractionEnabled = true
retakeBut.backgroundColor = UIColor(red: 0, green: 1, blue: 0, alpha: 0.5)
retakeBut.addTarget(self, action: #selector(retake(_:)), for: .touchUpInside)
self.view.addSubview(retakeBut)
self.view.addSubview(viewMain)
}
override func viewDidLayoutSubviews() {
if isForLibrary == true {
return
}
self.adjustViews(for: UIDevice.current.orientation)
}
var t:UITapGestureRecognizer!
var recordBut:UIButton!
var retakeBut:UIButton!
var isInFinalScreen:Bool = false
var isRecording:Bool = false
var isInFinalScreenBool:Bool = false
var recordedThisSession:Bool = false
func tapped(_ sender:UIButton){
if (isRecording == false && self.startVideoCapture()){
recordedThisSession = true
isRecording = true
retakeBut.alpha = 0
retakeBut.isUserInteractionEnabled = false
}else{
retakeBut.alpha = 1
retakeBut.isUserInteractionEnabled = true
recordBut.alpha = 0
recordBut.isUserInteractionEnabled = false
self.stopVideoCapture()
isRecording = false
if (UIDevice.current.orientation != .portrait){
self.adjustViews(for: UIDevice.current.orientation)
}
isInFinalScreen = true
return
}
}
func retake(_ sender:UIButton){
if (recordedThisSession == false){
onBack(sender)
}
self.dismiss(animated: true, completion: {
self.parentController.present((self.parentController as! AddVideo_ViewController).imagePicker, animated: true, completion: {
})
})
}
func onBack(_ sender:UIButton){
self.isInFinalScreen = false
self.dismiss(animated: true, completion: {
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func orientationChanged(_ notification: Notification) {
self.adjustViews(for: UIDevice.current.orientation)
}
func adjustViews(for orient: UIDeviceOrientation) {
var orientation = orient
if (orientation.isLandscape == true) || (orientation.isFlat && lastOrientationWasLandscape?.isPortrait == false) {
print(".....landscape.....")
if (UIDevice.current.userInterfaceIdiom == .pad){
self.recordBut.frame = CGRect(x: self.view.frame.size.width - 70 - 16, y: self.view.frame.size.height/2 - 35, width: 70, height: 70)
self.retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}else{
recordBut.frame = CGRect(x: self.view.frame.size.width / 2 - 35, y: self.view.frame.size.height - 70 - 2, width: 70, height: 70)
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}
if (recordedThisSession == false){
if (UIDevice.current.userInterfaceIdiom == .pad){
self.retakeBut.frame = CGRect(x: self.view.frame.size.width - 100, y: self.view.frame.size.height - 70, width: 100, height: 70)
}else{
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}
}
if (self.isInFinalScreenBool == true){
return
}
if (self.isInFinalScreen == true){
self.isInFinalScreenBool = !isInFinalScreenBool
self.isInFinalScreen = false
return
}
if (self.isRecording){
return
}
self.viewMain.alpha = 0
self.viewMain.isUserInteractionEnabled = false
self.lastOrientationWasLandscape = orientation
}
else {
print(".....portrait.....")
self.lastOrientationWasLandscape = UIDeviceOrientation(rawValue: UIDeviceOrientation.portrait.rawValue)
if (UIDevice.current.userInterfaceIdiom == .pad){
self.recordBut.frame = CGRect(x: self.view.frame.size.width - 70 - 16, y: self.view.frame.size.height / 2 - 35, width: 70, height: 70)
self.retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}else{
recordBut.frame = CGRect(x: self.view.frame.size.width / 2 - 35, y: self.view.frame.size.height - 70 - 2, width: 70, height: 70)
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}
if (recordedThisSession == false){
if (UIDevice.current.userInterfaceIdiom == .pad){
self.retakeBut.frame = CGRect(x: self.view.frame.size.width - 100, y: self.view.frame.size.height - 70, width: 100, height: 70)
}else{
retakeBut.frame = CGRect(x: 0, y: self.view.frame.size.height - 70, width: 80, height: 70)
}
}
if (self.isInFinalScreenBool == true){
return
}
if (self.isInFinalScreen){
return
}
if (self.isRecording){
return
}
self.viewMain.alpha = 1
self.viewMain.isUserInteractionEnabled = true
}
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Удачи!