你似乎是讓圖像視圖大小的圖像視圖的固有大小來決定。但圖像視圖的固有尺寸取決於圖像的大小,而不管圖像視圖的內容模式如何。
不是依賴於攝像畫面的固有大小,您可以定義圖像視圖大小的限制,如:
class FoodCell: UITableViewCell {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var mainImage: UIImageView!
private var aspectConstraint: NSLayoutConstraint?
func setContent(title: String, image: UIImage) {
// remove constraint, if any
if aspectConstraint != nil {
mainImage.removeConstraint(aspectConstraint!)
}
// add constraint
let ratio = image.size.width/image.size.height
aspectConstraint = NSLayoutConstraint(item: mainImage, attribute: .width, relatedBy: .equal, toItem: mainImage, attribute: .height, multiplier: ratio, constant: 0)
aspectConstraint?.priority = 999
mainImage.addConstraint(aspectConstraint!)
// set the image and label
titleLabel.text = title
mainImage.image = image
mainImage.backgroundColor = .red
}
}
注意,我設置爲高優先級的限制,但低於1000我這樣做的原因有兩個:如果您在返回執行剛剛在時間的調整限制
首先,細胞會產生各種有關表視圖單元格的內在高度自動佈局警告從cellForRowAt
(即使是約束實際上是完全可以滿足的)。第二,當你的單元的高度可以根據外部輸入(例如圖像的大小)而改變時,你經常想約束單元格中圖像視圖有多高,恕我直言,恕不另行通知。如果讓細胞圖像增長到荒謬的高度(如果什麼形象是一個蘿蔔,這是200像素寬和2000像素高大的垂直光),就可以結束了怪異UX在圖像的觀點是如此高大,你失去整個「我在桌面視圖中滾動」的氛圍。
所以我喜歡約束圖像視圖的最大高度,不顧形象。因此,在IB中,我定義了一個約束條件,指出圖像視圖的高度應該爲<=
到200點(使用任何你想要的值)。然後,我使用內容模式顯示「縮放比例適合」的圖像。
注意,除上述外,另一種方法是讓你的約束是,但調整圖像大小,本身,因此,如果它真的很大,它是按比例縮小的尺寸適合圖像視圖的寬度。例如,你可以這樣做:
func setContent(title: String, image: UIImage) {
titleLabel.text = title
if image.size.width > mainImage.frame.width {
let size = CGSize(width: mainImage.frame.width, height: max(200, mainImage.frame.width * image.size.height/image.size.width))
mainImage.image = image.scaledAspectFit(to: size)
} else {
mainImage.image = image
}
mainImage.backgroundColor = .red
}
其中:
extension UIImage {
/// Resize the image to be the required size, stretching it as needed.
///
/// - parameter newSize: The new size of the image.
/// - parameter contentMode: The `UIViewContentMode` to be applied when resizing image.
/// Either `.scaleToFill`, `.scaleAspectFill`, or `.scaleAspectFit`.
///
/// - returns: Return `UIImage` of resized image.
func scaled(to newSize: CGSize, contentMode: UIViewContentMode = .scaleToFill) -> UIImage? {
if contentMode == .scaleToFill {
return filled(to: newSize)
} else if contentMode == .scaleAspectFill || contentMode == .scaleAspectFit {
let horizontalRatio = size.width/newSize.width
let verticalRatio = size.height/newSize.height
let ratio: CGFloat!
if contentMode == .scaleAspectFill {
ratio = min(horizontalRatio, verticalRatio)
} else {
ratio = max(horizontalRatio, verticalRatio)
}
let sizeForAspectScale = CGSize(width: size.width/ratio, height: size.height/ratio)
let image = filled(to: sizeForAspectScale)
if contentMode == .scaleAspectFill {
let subRect = CGRect(
x: floor((sizeForAspectScale.width - newSize.width)/2.0),
y: floor((sizeForAspectScale.height - newSize.height)/2.0),
width: newSize.width,
height: newSize.height)
return image?.cropped(to: subRect)
}
return image
}
return nil
}
/// Resize the image to be the required size, stretching it as needed.
///
/// - parameter newSize: The new size of the image.
///
/// - returns: Resized `UIImage` of resized image.
func filled(to newSize: CGSize) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(newSize, false, scale)
draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
/// Crop the image to be the required size.
///
/// - parameter bounds: The bounds to which the new image should be cropped.
///
/// - returns: Cropped `UIImage`.
func cropped(to bounds: CGRect) -> UIImage? {
var rect = bounds
rect.size.width *= scale
rect.size.height *= scale
if let imageRef = cgImage?.cropping(to: rect) {
return UIImage(cgImage: imageRef, scale: scale, orientation: imageOrientation)
} else {
return nil
}
}
/// Resize the image to fill the rectange of the specified size, preserving the aspect ratio, trimming if needed.
///
/// - parameter newSize: The new size of the image.
///
/// - returns: Return `UIImage` of resized image.
func scaledAspectFill(to newSize: CGSize) -> UIImage? {
return scaled(to: newSize, contentMode: .scaleAspectFill);
}
/// Resize the image to fit within the required size, preserving the aspect ratio, with no trimming taking place.
///
/// - parameter newSize: The new size of the image.
///
/// - returns: Return `UIImage` of resized image.
func scaledAspectFit(to newSize: CGSize) -> UIImage? {
return scaled(to: newSize, contentMode: .scaleAspectFit)
}
}
這種 「調整圖像大小」 的方法還有另外一個優點。小圖像視圖中的大圖像仍然需要大量內存。但是,如果將圖像大小調整爲適合圖像視圖的大小,則可避免浪費內存。
所以紅色是不想要的部分吧?你有沒有嘗試固定標籤的高度? – RomOne