iOS 11 中的 UITableViewCell 转换中断

Posted

技术标签:

【中文标题】iOS 11 中的 UITableViewCell 转换中断【英文标题】:UITableViewCell Transform Breaks in iOS 11 【发布时间】:2017-10-28 00:31:23 【问题描述】:

在我构建的应用程序中,通过在 cellForRowAtIndexPath 中运行以下代码,我有一个表格视图,显示每个单元格左侧的图像:

cell.imageView.image = [UIImage imageNamed:myImage];

但是图片太大了,所以我把它缩小了:

cell.imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);

这在 ios 10 中运行良好。但是一旦我使用 iOS 11 SDK 升级到最新的 Xcode,图像变得非常庞大。事实证明,转换图像视图的第二行代码现在什么都不做:我可以将其注释掉,将 0.3 更改为其他内容,等等,这没有任何区别。 CGAffineTransformMakeScale 在新的 Xcode 中仍然有文档,所以我假设它没有被弃用,但是为什么这会在 iOS 11 中中断,我该如何修复它?有任何想法吗?提前致谢!请注意,我使用的是 Objective-C。

编辑:

刚刚尝试对代码进行 3 处更改:

    将第二行更改为cell.imageView.transform = CGAffineTransformMakeScale(0.0000001, 0.0000001);。什么都没有发生(即图像视图和其中的图像仍然一样大)。

    将第二行更改为cell.imageView.transform = CGAffineTransformMakeScale(0, 0);。图像从图像视图中消失了,但图像视图仍然是相同的大小,并且您可以分辨出来,因为它仍然会替换单元格中的文本并将其推向右侧。

    删除第一行代码(不再将图像分配给图像视图)。 imageview 消失,文本一直移动到单元格的左侧。

也许这可以帮助了解正在发生的事情?

【问题讨论】:

分享图片 @SyedQamarAbbas,图像视图是动态的,有很多很多的图像可以显示在表格单元格标题的左侧。在 iOS 11 之前,它们都适当地缩小了,现在它们都没有。所以它不是特定于图像的。 【参考方案1】:

因此,如果您尝试调整图像大小以适应 imageView,您实际上应该像这样使用 imageView 的 contentMode 属性:

cell.imageView.contentMode = UIViewContentModeScaleAspectFit;

或在 Swift 中用于其他人

cell.imageView.contentMode = .scaleAspectFit

这会保持图像的尺寸并将最大尺寸的图像适合imageView而不改变尺寸

您也可以尝试 UIViewContentModeScaleAspectFit(或 Swift 中的 .scaleAspectFill),它基本上完全填充了 imageView 的尺寸,但如果图片比图像视图更宽或更高,它会裁剪出不适合的内容。

以下是直接来自 Obj-C 和 Swift 源文件的所有 contentMode:

typedef NS_ENUM(NSInteger, UIViewContentMode) 
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter,              // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
;

public enum UIViewContentMode : Int 
    case scaleToFill
    case scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
    case scaleAspectFill // contents scaled to fill with fixed aspect. some portion of content may be clipped.
    case redraw // redraw on bounds change (calls -setNeedsDisplay)
    case center // contents remain same size. positioned adjusted.
    case top
    case bottom
    case left
    case right
    case topLeft
    case topRight
    case bottomLeft
    case bottomRight

编辑:

由于我看到您也有兴趣更改 imageView 本身的尺寸(“为文本留出更多空间”),我建议实际上是在情节提要中或以编程方式使用 AutoLayout 添加您自己的imageView 并根据需要调整大小和放置位置,而不是在单元格上使用默认的 imageView,这意味着方便/标准化的工具。

如果您对此不熟悉,我会在 Google 上搜索 AutoLayout 教程。或者也许“使用 AutoLayout 创建自定义 UITableViewCell”

如果您实际上不想创建自己的子类,您可以尝试在某处设置“cell.imageView.frame = ...”以手动将其调整为您想要的大小,然后设置其内容模式以确保图像适合很好。

看到这个问题:How do I make UITableViewCell's ImageView a fixed size even when the image is smaller

【讨论】:

是的,使用“fill”或“fit”值中的一个,或其他值之一并将clipsToBounds设置为true。 目标c码是cell.imageView.contentMode = UIViewContentModeScaleAspectFit; 感谢您的回复,@gadu 和 @danh。我实际上想要做的不仅仅是缩小图像视图中的图像,而是缩小整个图像视图,包括其中的图像。区别很重要的原因是这在单元格的其余部分为文本留下了更多空间。 cell.imageView.transform = CGAffineTransformMakeScale(0.3, 0.3); 代码在 iOS 10 中两者都有,但在 iOS 11 中两者都没有。 是否有触发它缩小尺寸的操作,或者您只是希望它始终缩小尺寸? 我希望它总是被缩小,所以我只是在 cellForRowAtIndexPath 方法中包含那行代码,以便它为每个单元格运行。【参考方案2】:

找到了我自己的问题的答案,归功于 Paul 对这个问题的回答:How to resize a cell.imageView in a TableView and apply tintColor in Swift

CGSize  itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContextWithOptions(itemSize, false, 0);
CGRect  imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

我仍然不知道为什么旧的 CGAffineTransformMakeScale 不再工作了,但这可以完成工作。

【讨论】:

以上是关于iOS 11 中的 UITableViewCell 转换中断的主要内容,如果未能解决你的问题,请参考以下文章

iOS:自定义UITableViewCell的实现需要调用super

iOS7 手机应用中的通话、邮件等图标放入UITableViewCell

UITableViewCell 使用 separatorInset 隐藏分隔符在 iOS 11 中失败

UITableViewCell Autolayout问题(iOS 11,Xcode 9.2)

iOS 11 中 UITableViewCell 内的 UIImageView 的固定大小

UITableViewCell.textLable.text 没有出现在 xcode 9.2 的 iOS11.2 模拟器上