为什么缩放以填充给出比 UIImageVIew 尺寸更大的图像? (使用 swift)
Why scale to fill give bigger image than UIImageVIew size? (using swift)
我正在尝试显示地名列表,包括使用 PFQueryTableViewController
的照片。它包含在 parse.com
的 ParseUI SDK 中
我成功显示了图像。不幸的是,当我将 UIImageView 模式更改为 Aspect fill 时,图像变得比应有的大。
图片如下:
https://dl.dropboxusercontent.com/u/86529526/pic_normal.png
https://dl.dropboxusercontent.com/u/86529526/pic_error.png
在pic_normal
中,你会看到两个单元格,有两个正常图像。
在 pic_error
中,您将看到第二个单元格被第一个单元格图像覆盖。
谁能帮我解决这个问题?我也把我的全部代码放在这里:
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()
}
}
如果你想保持不同宽度的宽高比,那么使用 AspectFill 并使用 imageview 属性 clipstoBounds,它不会将 imageview 扩展到框架之外
来自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.
所以你的选择是使用
UIViewContentModeScaleToFill
,并可能改变显示图像的纵横比,
UIViewContentModeScaleAspectFill
,并在您的 PFImageView
上使用 clipToBounds = YES
,以裁剪超出范围的部分图像。
将内容模式设置为 Aspect Fill
,尝试将 clips to bounds 也设置为 true,原因是内容模式 aspect fill
不断填充图像视图的框架,直到框架完全填满填充内容也保持 aspect ratio
完好无损。在以图像保持宽高比填充容器的过程中,垂直或水平框架被完全填充,并且继续填充直到另一个(如果水平而不是垂直或反之亦然)部分被完全填充。因此,垂直或水平方向的第一个填充部分将超出边界,并且内容将在图像视图的框架之外可见。要剪切额外的内容,我们需要使用 imageView 的 clipsToBounds
属性 设置为 true
来剪切额外的部分
cell.photo.contentMode = UIViewContentMode.ScaleAspectFill
cell.photo.clipsToBounds = true
另外,对于喜欢 Interface Builder 的人,您可以在选择 Aspect Fill
时在图像视图中检查 Clip Subviews
,然后它不会调整大小您的 Image View 但仍然保持相同的纵横比。
参考:另一个 post 中的答案,让您清楚地了解 -
我正在尝试显示地名列表,包括使用 PFQueryTableViewController
的照片。它包含在 parse.com
我成功显示了图像。不幸的是,当我将 UIImageView 模式更改为 Aspect fill 时,图像变得比应有的大。
图片如下:
https://dl.dropboxusercontent.com/u/86529526/pic_normal.png https://dl.dropboxusercontent.com/u/86529526/pic_error.png
在pic_normal
中,你会看到两个单元格,有两个正常图像。
在 pic_error
中,您将看到第二个单元格被第一个单元格图像覆盖。
谁能帮我解决这个问题?我也把我的全部代码放在这里:
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()
}
}
如果你想保持不同宽度的宽高比,那么使用 AspectFill 并使用 imageview 属性 clipstoBounds,它不会将 imageview 扩展到框架之外
来自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.
所以你的选择是使用
UIViewContentModeScaleToFill
,并可能改变显示图像的纵横比,UIViewContentModeScaleAspectFill
,并在您的PFImageView
上使用clipToBounds = YES
,以裁剪超出范围的部分图像。
将内容模式设置为 Aspect Fill
,尝试将 clips to bounds 也设置为 true,原因是内容模式 aspect fill
不断填充图像视图的框架,直到框架完全填满填充内容也保持 aspect ratio
完好无损。在以图像保持宽高比填充容器的过程中,垂直或水平框架被完全填充,并且继续填充直到另一个(如果水平而不是垂直或反之亦然)部分被完全填充。因此,垂直或水平方向的第一个填充部分将超出边界,并且内容将在图像视图的框架之外可见。要剪切额外的内容,我们需要使用 imageView 的 clipsToBounds
属性 设置为 true
cell.photo.contentMode = UIViewContentMode.ScaleAspectFill
cell.photo.clipsToBounds = true
另外,对于喜欢 Interface Builder 的人,您可以在选择 Aspect Fill
时在图像视图中检查 Clip Subviews
,然后它不会调整大小您的 Image View 但仍然保持相同的纵横比。
参考:另一个 post 中的答案,让您清楚地了解 -