Ios UITableView中的动态UIImageView大小
我想用显示图像的自定义TableViewCell实现TableView 为了简单起见,我使用autolayout(如下所示)将UIImageView放在tableviewcell中。 我想要的是在UIImageView中显示图像,但是这些图像的尺寸可以是任何东西,并且不一致(纵向、横向、方形) 因此,我希望显示具有固定宽度(设备宽度)和动态高度的图像,该高度与图像的比率有关。我想要这样的东西:Ios UITableView中的动态UIImageView大小,ios,swift,uitableview,uiimageview,autolayout,Ios,Swift,Uitableview,Uiimageview,Autolayout,我想用显示图像的自定义TableViewCell实现TableView 为了简单起见,我使用autolayout(如下所示)将UIImageView放在tableviewcell中。 我想要的是在UIImageView中显示图像,但是这些图像的尺寸可以是任何东西,并且不一致(纵向、横向、方形) 因此,我希望显示具有固定宽度(设备宽度)和动态高度的图像,该高度与图像的比率有关。我想要这样的东西: 不幸的是,我没能达到那个结果 下面是我如何实现它的-(我使用Haneke从存储在AmazonS3中
不幸的是,我没能达到那个结果 下面是我如何实现它的-(我使用Haneke从存储在AmazonS3中的URL图像加载图像): 类TestCellVC:UITableViewCell{ @IBVAR selfieImageView:UIImageView! @IBOutlet弱var高度约束:NSLayoutConstraint! func loadItem(#selfie:selfie){ 让selfieImageURL:NSURL=NSURL(字符串:selfie.show_selfie_pic())! self.selfieImageView.hnk_setImageFromURL(selfieImageURL,占位符:nil,格式:HNKFormat(名称:“原始”),失败:{error->println中的Void(错误) },成功:{(图像)->Void in //屏幕宽度 var screen_width=UIScreen.mainScreen().bounds.width //宽高比 变量比率=image.size.height/image.size.width //图片的计算高度 设新高度=屏幕宽度*比率 //方法1 self.heightConstraint.constant=新高度 //方法2 //self.selfieImageView.bounds=CGRectMake(0,0,屏幕宽度,新高度) self.selfieImageView.image=图像 } ) } 重写func viewDidLoad(){ super.viewDidLoad() //为自定义TableViewCell注册xib var nib=UINib(nibName:“TestCell”,bundle:nil) self.tableView.registerNib(nib,强制重用标识符:“TestCell”) //动态设置单元格的高度 self.tableView.rowHeight=UITableViewAutomaticDimension self.tableView.estimateDroweight=500.0 //从UITableView中删除分隔线 self.tableView.separatorStyle=UITableViewCellSeparatorStyle.None loadData() } 重写func tableView(tableView:UITableView,cellForRowAtIndexPath:nsindepath)->UITableView单元格{ var cell=tableView.dequeueReusableCellWithIdentifier(“TestCell”)作为TestCellVC cell.loadItem(selfie:self.selfies\u数组[indexPath.row]) //拆下单元分离器的插图 cell.layoutMargins=UIEdgeInsetsZero cell.separatorInset=UIEdgeInsetsZero //更新单元约束 cell.setNeedsUpdateConstraints()单元格 cell.updateConstraintSifRequired() cell.sizeToFit() 返回单元 } } 我对动态高度的计算是正确的(我已经打印出来了)。我尝试了这两种方法(在代码中描述),但都不起作用:
从imageView中删除高度约束。选择以“方面”开头的图像视图的内容模式,例如:方面填充或方面匹配(根据您的要求进行匹配) 注意:您还需要设置行的高度,以便imageView适合该行。使用
heightForRowAtIndexPath
设置自定义行高度。如果希望UIImageView告诉UITableView它需要多高,则需要配置表格视图以启用自动行计算。您可以通过将EstimateDrowEight设置为固定的正值,并将rowHeight设置为UIViewAutomaticDimension来完成此操作。这是第一部分 现在您需要配置UIImageView,以便根据表视图所需的宽度和图像的纵横比请求高度。这将是第二部分 首先,将contentMode设置为.AspectFit。这将导致视图根据所采用的任何尺寸调整图像外观的大小。但是,这仍然不会导致它使用自动布局请求所需的高度。相反,它将请求intrinsicContentSize的高度,这可能与调整大小的图像大不相同。因此,第二,向UIImageView添加一个约束,其形式为
width=height*multiplier
,其中multiplier基于图像本身的纵横比
现在,表格视图将需要正确的宽度,contentMode机制将确保图像在不失真的情况下正确调整大小,纵横比约束将通过自动布局确保图像视图需要正确的高度
这很有效。它的缺点是,每次将新图像指定给图像视图时,您都需要更新纵横比约束,如果图像视图位于要重复使用的单元格中,这可能非常常见
另一种方法是仅添加高度约束,并在包含图像视图的视图的LayoutSubview中更新它。这具有更好的性能,但代码模块性较差。在情节提要中,为您的
UIImageView添加尾随、前导、底部和顶部约束。加载图像后,只需向UIImageView
添加一个方面约束即可。“图像”单元格的外观如下所示:
class ImageTableViewCell: UITableViewCell {
@IBOutlet weak var customImageView: UIImageView!
internal var aspectConstraint : NSLayoutConstraint? {
didSet {
if oldValue != nil {
customImageView.removeConstraint(oldValue!)
}
if aspectConstraint != nil {
customImageView.addConstraint(aspectConstraint!)
}
}
}
override func prepareForReuse() {
super.prepareForReuse()
aspectConstraint = nil
}
func setCustomImage(image : UIImage) {
let aspect = image.size.width / image.size.height
let constraint = NSLayoutConstraint(item: customImageView, attribute: NSLayoutAttribute.width, relatedBy: NSLayoutRelation.equal, toItem: customImageView, attribute: NSLayoutAttribute.height, multiplier: aspect, constant: 0.0)
constraint.priority = 999
aspectConstraint = constraint
customImageView.image = image
}
}
您可以在此处查看工作示例
将图像加载到tableView时,每个图像可以具有不同的纵横比。
通过使用,我们可以从url获取图像-
testImageView.sd_setImage(with: url, placeholderImage: nil, options: [], completed: { (downloadedImage, error, cache, url) in
print(downloadedImage?.size.width)//prints width of image
print(downloadedImage?.size.height)//prints height of image
})
在UITableViewCell
中,将imageView的约束设置为顶部
,底部
,前导
,尾随
,固定高度约束
wi
testImageView.sd_setImage(with: url, placeholderImage: nil, options: [], completed: { (downloadedImage, error, cache, url) in
print(downloadedImage?.size.width)//prints width of image
print(downloadedImage?.size.height)//prints height of image
})
var cellFrame = cell.frame.size
cellFrame.height = cellFrame.height - 15
cellFrame.width = cellFrame.width - 15
cell.feedImageView.sd_setImage(with: url, placeholderImage: nil, options: [], completed: { (theImage, error, cache, url) in
cell.feedImageHeightConstraint.constant = self.getAspectRatioAccordingToiPhones(cellImageFrame: cellFrame,downloadedImage: theImage!)
})
func getAspectRatioAccordingToiPhones(cellImageFrame:CGSize,downloadedImage: UIImage)->CGFloat {
let widthOffset = downloadedImage.size.width - cellImageFrame.width
let widthOffsetPercentage = (widthOffset*100)/downloadedImage.size.width
let heightOffset = (widthOffsetPercentage * downloadedImage.size.height)/100
let effectiveHeight = downloadedImage.size.height - heightOffset
return(effectiveHeight)
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = self.rowHeights[indexPath.row]{
return height
}else{
return defaultHeight
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return imageArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let identifier = "editImageCell"
let customCell : EdiPostImageCell = (self.imagesTableView.dequeueReusableCell(withIdentifier: identifier)) as! EdiPostImageCell
let aspectRatio = (imageArray[indexPath.row]).size.height/(imageArray[indexPath.row]).size.width
customCell.editlImageView.image = imageArray[indexPath.row]
let imageHeight = self.view.frame.width*aspectRatio
self.imagesTableView.beginUpdates()
self.rowHeights[indexPath.row] = imageHeight
tableView.endUpdates()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
let entity = self.fetchedResultController.object(at: indexPath as IndexPath) as! Message
var newh:CGFloat = 100.00
if let fileThumbnails = entity.file_thumbnails as? NSArray{
if fileThumbnails.count != 0{
fileThumbnails.map { (thumbNail) in
newh = self.getImageHeight(image:UIImage(data: thumbNail as! Data)! , h: UIImage(data: thumbNail as! Data)!.size.height , w: UIImage(data: thumbNail as! Data)!.size.width)
}
}
}
if entity.fileStatus == "DeletedMedia" {
newh = 100
}
if entity.fileStatus == nil{
newh = 0.0
}
print ("newH " , newh)
return newh
}
func getImageHeight(image : UIImage, h : CGFloat, w : CGFloat) -> CGFloat {
let aspect = image.size.width / image.size.height
var newH = (messagesTV.frame.size.width) / aspect
// customise as you want in newH
if(newH > 500){
newH = 500
//maximum height 500
}
if(newH < 100){
newH = 100
//minimum height = 100
}
return newH
}