Why scale to fill give bigger image than UIImageVIew size? (using swift)

28,932

Solution 1

With content mode set to Aspect Fill, try setting clips to bounds to true as well, reason being the content mode aspect fill keeps on filling the frame of the image view till the frame is fully filled with content also keeping the aspect ratio intact. In the process of filling the container with image maintaining aspect ratio, either vertical or horizontal frame is fully filled, and the filling is continued till the other (if horizontal than vertical or vise versa) portion is fully filled. Thus the first filled portion either across vertical or horizontal will go out of bounds and the content will be visible outside the frame of the image view. To clip the extra content we need to clip the extra portion using imageView's clipsToBounds property set to true

cell.photo.contentMode = UIViewContentMode.ScaleAspectFill
cell.photo.clipsToBounds = true

Solution 2

enter image description here

Reference: an answer in another post which gives you clear insight - https://stackoverflow.com/a/14220605/3021573

Solution 3

Alternatively for guys who prefer Interface Builder, you can check the Clip Subviews at your image view when you choose Aspect Fill, then it will not resize your Image View but still keep the same aspect ratio.

enter image description here

Solution 4

If you want to maintain the aspect ratio with varying width ,then use AspectFill and also use the imageview property clipstoBounds,it will not spread the imageview beyond the frame

Solution 5

From apple doc:

UIViewContentModeScaleToFill

Scales the content to fit the size of itself by changing the aspect ratio of the content if necessary

UIViewContentModeScaleAspectFill

Scales the content to fill the size of the view. Some portion of the content may be clipped to fill the view’s bounds.

So your options are to use

  • UIViewContentModeScaleToFill, and possibly change the aspect ratio of displayed image,
  • UIViewContentModeScaleAspectFill, and use clipToBounds = YES on your PFImageView, to clip portions of image out of bounds.
Share:
28,932

Related videos on Youtube

Gibran
Author by

Gibran

just started learning to build iOS app with Swift. Also combine it with parse.com.

Updated on July 09, 2022

Comments

  • Gibran
    Gibran almost 2 years

    I'm trying to showing a list of place name, including it's photo using PFQueryTableViewController. It's included in ParseUI SDK from parse.com

    I have managed to show the image. Unfortunately, when I change the UIImageView mode to Aspect fill, the image is become bigger than it should be.

    here are the pictures:

    https://dl.dropboxusercontent.com/u/86529526/pic_normal.png https://dl.dropboxusercontent.com/u/86529526/pic_error.png

    in pic_normal, you will see two cell, with two normal image. in pic_error, you will the second cell was being overlaid by the first cell image.

    can anyone help me to solve this problem? I also put my whole code here :

    import UIKit
    
    class TableViewController: PFQueryTableViewController, UISearchBarDelegate {
    
        @IBOutlet var searchBar: UISearchBar!
    
    
        // Initialise the PFQueryTable tableview
        override init(style: UITableViewStyle, className: String!) {
            super.init(style: style, className: className)
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
    
            // Configure the PFQueryTableView
            self.pullToRefreshEnabled = true
            self.paginationEnabled = false
        }
    
        // Define the query that will provide the data for the table view
        override func queryForTable() -> PFQuery {
    
            // Start the query object
            var query = PFQuery(className: "Places")
    
            // query with pointer
            query.includeKey("mainPhoto")
    
            // Add a where clause if there is a search criteria
            if searchBar.text != "" {
                query.whereKey("name", containsString: searchBar.text)
            }
    
            // Order the results
            query.orderByAscending("name")
    
            // Return the qwuery object
            return query
        }
    
    
        //override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject) -> PFTableViewCell? {
            var cell = tableView.dequeueReusableCellWithIdentifier("CustomCell") as! CustomTableViewCell!
            if cell == nil {
                cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CustomCell")
            }
    
            // Extract values from the PFObject to display in the table cell
            if let name = object["name"] as? String{
                cell.name.text = name
            }
    
            // display initial image
            var initialThumbnail = UIImage(named: "question")
            cell.photo.image = initialThumbnail
    
    
            // extract image from pointer
            if let pointer = object["mainPhoto"] as? PFObject {
                cell.detail.text = pointer["photoTitle"] as? String!
                if let thumbnail = pointer["photo"] as? PFFile {
                    cell.photo.file = thumbnail
                    cell.photo.loadInBackground()
                }
            }
            cell.sendSubviewToBack(cell.photo)
    
            // return the cell
            return cell
        }
    
    
    
    
        // In a storyboard-based application, you will often want to do a little preparation before navigation
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    
            // Get the new view controller using [segue destinationViewController].
            var detailScene = segue.destinationViewController as! DetailViewController
    
            // Pass the selected object to the destination view controller.
            if let indexPath = self.tableView.indexPathForSelectedRow() {
                let row = Int(indexPath.row)
                detailScene.currentObject = objects[row] as? PFObject
            }
        }
    
        override func viewDidLoad(){
            super.viewDidLoad()
            let tapGesture = UITapGestureRecognizer(target:self, action:Selector("hideKeyboard"))
            tapGesture.cancelsTouchesInView = true
            tableView.addGestureRecognizer(tapGesture)
        }
    
        func hideKeyboard(){
            tableView.endEditing(true)
        }
    
        override func viewDidAppear(animated: Bool) {
    
            // Refresh the table to ensure any data changes are displayed
            tableView.reloadData()
    
            // Delegate the search bar to this table view class
            searchBar.delegate = self
        }
    
        func searchBarTextDidEndEditing(searchBar: UISearchBar) {
    
            // Dismiss the keyboard
            searchBar.resignFirstResponder()
    
            // Force reload of table data
            self.loadObjects()
        }
    
        func searchBarSearchButtonClicked(searchBar: UISearchBar) {
    
            // Dismiss the keyboard
            searchBar.resignFirstResponder()
    
            // Force reload of table data
            self.loadObjects()
        }
    
        func searchBarCancelButtonClicked(searchBar: UISearchBar) {
    
            // Clear any search criteria
            searchBar.text = ""
    
            // Dismiss the keyboard
            searchBar.resignFirstResponder()
    
            // Force reload of table data
            self.loadObjects()
        }
    
    }
    
    • Rizwan Shaikh
      Rizwan Shaikh about 9 years
      make UIImageView mode to Aspect Fit
    • Gibran
      Gibran about 9 years
      I want to fill the UIImageVIew, but also keep the aspect ratio.
    • Rizwan Shaikh
      Rizwan Shaikh about 9 years
      refer this answer you know the difference between aspect fill and aspect fit stackoverflow.com/questions/4895272/…
    • Fitzgerald Afful
      Fitzgerald Afful over 6 years
      This answer helped me when all the UIViewContentModes couldnt. - stackoverflow.com/a/35685883/8694980
  • clearlight
    clearlight over 7 years
    Couldn't that just be a comment below the question? You haven't really provided an answer but merely a reference. That's where people usually make small helpful contributions that don't really qualify as technical answers provided by the poster.
  • Avinash B
    Avinash B over 7 years
    Sorry for that, but the answer is a really lengthy one. Also,thought it is better that the credit remains to the person who has written that one. I am new to stack overflow. please suggest what i can do now.
  • IDIR Samir
    IDIR Samir over 6 years
    @AvinashB You can just reference the article directly instead of the answer. This way you're still keeping credits to the author. Even better would be: extract important parts from the article into your answer here on SO and mention the source of your information.