如何在运行时更改uiimageview内容模式?

时间:2018-06-03 13:05:48

标签: ios swift uiimageview contentmode

我有一个带有UIImageView的UIViewController,如果我点击屏幕,我希望UIImageView更改其contentMode。但我发现这不适用于某些图像,主要来自AVCaptureSession。

截图: Aspect填充

enter image description here

方面适合

enter image description here

我还发现,当我将设备方向更改为横向和背景时,它工作正常。但是当我点击屏幕时再没有工作。

在改变了横向和背面的方向后适合方面(这是我希望每次在宽高比适合时的样子)

enter image description here

我的代码:

CameraController:

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()
    })
}
}

PreviewController:

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
}

}

我在这里做错了什么?

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以在运行时使用以下方法更改ImageView Navigate

#include <Windows.h>
#include <Ole2.h>
#include "resource.h"
#include <iostream>
#include <atlbase.h> //activex
#include <atlwin.h> //windows
#include <atlcom.h>
#include "exdisp.h"
#include <comutil.h>

#pragma comment(lib, "comsuppw.lib")

//This will load the browser dll then library and will generate headers
//All the declarations will be in the namespace SHDocVw
//#import "shdocvw.dll"
using namespace std;

class CMyDialog : public CAxDialogImpl<CMyDialog>
{
public:
enum { IDD = IDD_DIALOG1 };

BEGIN_MSG_MAP(CMyDialog)
MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
COMMAND_HANDLER(IDCANCEL, BN_CLICKED, OnBnCancel)
COMMAND_HANDLER(IDOK, BN_CLICKED, OnBnOk)
END_MSG_MAP()
CComPtr<IWebBrowser2>  ctrl;
LRESULT OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
// Do some initialization code
HRESULT hr;
//IDC_EXPLORER_TEST is the ID of your control
GetDlgControl(IDC_EXPLORER_TEST, __uuidof(ctrl), (void**)&ctrl);

VARIANT address;
address.vt = VT_BSTR;
address.bstrVal = SysAllocString(L"google.com");

VARIANT empty;
empty.vt = VT_EMPTY;

hr = ctrl->Navigate2(&address, &empty, &empty, &empty, &empty);

SysFreeString(address.bstrVal);

/* 

Also fails

_variant_t a = SysAllocString(L"google.com");
VARIANT f;
f.vt = VT_I2;
f.iVal = navBrowserBar;
_variant_t fr = SysAllocString(L"_self");
_variant_t h = SysAllocString(L" ");

hr = ctrl->Navigate2(&a, &f, &fr, &h, &h);
*/
  
LRESULT res = CAxDialogImpl<CMyDialog>::OnInitDialog(uMsg, wParam, lParam, bHandled);
return 0;
}
public:
LRESULT OnBnCancel(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
EndDialog(IDCANCEL);
return 0;
}
LRESULT OnBnOk(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
EndDialog(IDOK);
return 0;
}
};
CComModule _Module;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
CMyDialog dlg;
dlg.DoModal();

return 0;
}