У меня есть UIViewController с UIImageView, если я коснусь экрана, я хочу, чтобы UIImageView изменил свой contentMode. Но я обнаружил, что это не работает с некоторыми изображениями, в основном с AVCaptureSession.
Скриншоты: Заполнение пропорций
Соответствие пропорций
Я также обнаружил, что он работает нормально, когда я меняю ориентацию устройства на альбомную и обратно. Но когда я тапаю, экран снова не работает.
Подгонка пропорций после изменения ориентации на альбомную и обратно (я хочу, чтобы она выглядела каждый раз при подгонке сторон)
Мой код:
Контроллер камеры:
class CameraController: UIViewController {
private var captureSession = AVCaptureSession()
private var captureDevice: AVCaptureDevice!
private var capturePhotoOutput = AVCapturePhotoOutput()
private var previewLayer: AVCaptureVideoPreviewLayer!
override func viewDidLoad() {
super.viewDidLoad()
setupCaptureSession()
setupCaptureDevice()
setupInputAndOutput()
setupPreviewLayer()
startCaptureSession()
setupLayout()
}
private func setupCaptureSession() {
captureSession.sessionPreset = .photo
}
private func setupCaptureDevice() {
guard let device = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: AVMediaType.video, position: .back).devices.first else { return }
captureDevice = device
}
private func setupInputAndOutput() {
do {
let captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
captureSession.addInput(captureDeviceInput)
let captureSettings = AVCapturePhotoSettings(format: [AVVideoCodecKey: AVVideoCodecType.jpeg])
capturePhotoOutput.setPreparedPhotoSettingsArray([captureSettings], completionHandler: nil)
captureSession.addOutput(capturePhotoOutput)
} catch {
print(error.localizedDescription)
}
}
private func setupPreviewLayer() {
previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
previewLayer.videoGravity = .resizeAspectFill
previewLayer.connection?.videoOrientation = .portrait
previewLayer.frame = view.frame
view.layer.insertSublayer(previewLayer, at: 0)
}
private func startCaptureSession() {
captureSession.startRunning()
}
private func setupLayout() {
let captureButton = UIButton(frame: CGRect(x: 0, y: 0, width: 44, height: 44))
captureButton.backgroundColor = .white
captureButton.layer.cornerRadius = 22
captureButton.addTarget(self, action: #selector(didPressCaptureButton), for: .touchUpInside)
captureButton.center.x = view.center.x
captureButton.center.y = view.frame.height - 50
view.addSubview(captureButton)
}
@objc private func didPressCaptureButton() {
let settings = AVCapturePhotoSettings()
capturePhotoOutput.capturePhoto(with: settings, delegate: self)
}
}
extension CameraController: AVCapturePhotoCaptureDelegate {
func photoOutput(_ output: AVCapturePhotoOutput, didFinishProcessingPhoto photo: AVCapturePhoto, error: Error?) {
guard let imageData = photo.fileDataRepresentation() else { return }
guard let image = UIImage(data: imageData) else { return }
print("Image size: ", image.size)
let previewController = PreviewController()
previewController.image = image
present(previewController, animated: true, completion: {
self.captureSession.stopRunning()
})
}
}
Контроллер предварительного просмотра:
class PreviewController: UIViewController {
var imageView: UIImageView!
var image: UIImage!
override func viewDidLoad() {
super.viewDidLoad()
setupImageView()
}
func setupImageView() {
imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
view.addSubview(imageView)
imageView.addConstraintsToFillSuperview()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let contentMode: UIViewContentMode = imageView.contentMode == .scaleAspectFill ? .scaleAspectFit : .scaleAspectFill
imageView.contentMode = contentMode
}
}
Что я здесь делаю неправильно?
Спасибо!
layoutSubviews()
— это то, что вы вызываете при работе внутриUIView
. Но ваш код выглядит так, как будто он изUIViewController
, поэтому правильный метод для вызова —view.setNeedsLayout()
. - person dfd   schedule 03.06.2018setNeedsDisplay
, но в целом идея изменения режима содержимого представления изображения, когда оно уже отображает изображение, кажется отвратительной. Тот факт, что вы чувствуете, что вам нужно это сделать, сам по себе является Плохим Запахом, на мой взгляд. - person matt   schedule 03.06.2018