简体   繁体   中英

contentMode (scaleAspectFill) on UIImageView - Swift

I'm trying to create a small example which explains the contentMode ( scaleAspectFill ) of an UIImageView .

Everything is coded, and no storyboard is used. Checked a lot of examples that would help to explain this. But, couldn't find any that suits my requirement.

Please find the entire code below.

class ImageViewController: UIViewController {

    let marginSpacing = CGFloat(10)

    lazy var imageView1: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var imageView2: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var imageView3: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var imageView4: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var imageView5: UIImageView = {
        let view = UIImageView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var contentView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    lazy var scrollView: UIScrollView = {
        let view = UIScrollView()
        view.translatesAutoresizingMaskIntoConstraints = false
        return view
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Image Auto-Scale"
        // Do any additional setup after loading the view.
        setupImageView()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    /*
    // 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.
    }
    */

    fileprivate func setupImageView() {

        updateImageViews()
        colorImageViews()
        addImageViews()
        setupImageConstraints()
    }

    fileprivate func updateImageViews() {

        self.navigationItem.setRightBarButton(UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(tappedBackButton)), animated: true)

        imageView1.image = #imageLiteral(resourceName: "Sample")
        imageView1.contentMode = .scaleAspectFill

        imageView2.image = #imageLiteral(resourceName: "Sample")
        imageView2.contentMode = .scaleAspectFill

        imageView3.image = #imageLiteral(resourceName: "Sample")
        imageView3.contentMode = .scaleAspectFill

        imageView4.image = #imageLiteral(resourceName: "Sample")
        imageView4.contentMode = .scaleAspectFill

        imageView5.image = #imageLiteral(resourceName: "Sample")
        imageView5.contentMode = .scaleAspectFill

    }

    fileprivate func colorImageViews() {

        contentView.backgroundColor = UIColor.white
    }

    fileprivate func addImageViews() {

        contentView.addSubview(imageView1)
        contentView.addSubview(imageView2)
        contentView.addSubview(imageView3)
        contentView.addSubview(imageView4)
        contentView.addSubview(imageView5)
        scrollView.addSubview(contentView)
        view.addSubview(scrollView)
    }

    fileprivate func setupImageConstraints() {

        if #available(iOS 11, *) {

            NSLayoutConstraint.activate([scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
                                         scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)])
        } else {

            NSLayoutConstraint.activate([scrollView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor),
                                         scrollView.bottomAnchor.constraint(equalTo: bottomLayoutGuide.topAnchor)])
        }

        NSLayoutConstraint.activate([scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                                     scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                                     scrollView.widthAnchor.constraint(equalTo: view.widthAnchor),
                                     contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor),
                                     contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor),
                                     contentView.topAnchor.constraint(equalTo: scrollView.topAnchor),
                                     contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor),
                                     contentView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
                                     contentView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
                                     contentView.heightAnchor.constraint(equalToConstant: 1000),
                                     imageView1.topAnchor.constraint(equalTo: contentView.topAnchor, constant: marginSpacing),
                                     imageView1.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.5, constant: 0),
                                     imageView1.heightAnchor.constraint(equalTo: imageView1.widthAnchor, multiplier: 3.0/4.0, constant: 0),
                                     imageView1.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
                                     imageView2.topAnchor.constraint(equalTo: imageView1.bottomAnchor, constant: marginSpacing),
                                     imageView2.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.75, constant: 0),
                                     imageView2.heightAnchor.constraint(equalTo: imageView2.widthAnchor, multiplier: 2.0/3.0, constant: 0),
                                     imageView2.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
                                     imageView3.topAnchor.constraint(equalTo: imageView2.bottomAnchor, constant: marginSpacing),
                                     imageView3.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.6, constant: 0),
                                     imageView3.heightAnchor.constraint(equalTo: imageView3.widthAnchor, multiplier: 1.0/1.0, constant: 0),
                                     imageView3.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
                                     imageView4.topAnchor.constraint(equalTo: imageView3.bottomAnchor, constant: marginSpacing),
                                     imageView4.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.4, constant: 0),
                                     imageView4.heightAnchor.constraint(equalTo: imageView4.widthAnchor, multiplier: 1.0/3.0, constant: 0),
                                     imageView4.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
                                     imageView5.topAnchor.constraint(equalTo: imageView4.bottomAnchor, constant: marginSpacing),
                                     imageView5.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: 0.5, constant: 0),
                                     imageView5.heightAnchor.constraint(equalTo: imageView5.widthAnchor, multiplier: 3.0/4.0, constant: 0),
                                     imageView5.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor)])
    }

    @objc func tappedBackButton (sender: UIBarButtonItem!) {
        self.dismiss(animated: true, completion: nil);
    }

}

This would display 5 images at different aspect ratios, showing that the image might be cropped when scaleAspectFill is used, but it is never squished or stretched.

Strange thing is that, I'm able to have the image at the aspect ratios I've used, when debugging the view hierarchy, but on the simulator all I get is something else!

Note: Please use a random image of your liking, as I've used one directly from my Assets.

Please find the screenshot attached which showcases this weird behaviour.

屏幕截图

Is there anything that I missed?

You want to set this for all the UIImageView s:

imageView.clipsToBounds = true

Otherwise the image will be rendered beyond the frame of an imageView.

If you would be using storyboards, you could check it in the Attributes Inspector:

IB属性检查器

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM