如何在不扭曲其内容的情况下沿一个轴调整 UICollectionViewCell 的大小?

Posted

技术标签:

【中文标题】如何在不扭曲其内容的情况下沿一个轴调整 UICollectionViewCell 的大小?【英文标题】:How can I resize a UICollectionViewCell along one axis without distorting its contents? 【发布时间】:2014-11-06 03:32:02 【问题描述】:

我正在尝试仅沿一个轴调整 UICollectionViewCell 的大小而不扭曲其内容。

我已经阅读了涉及 UICollectionViewLayoutAttributes layoutAttributesForItemAtIndexPath 和 layoutAttributesForElementsInRect 的类似问题的答案。我还尝试在 UICollectionViewCell 子类中使用 initWithFrame 和 awakeFromNib。我尝试在这些方法中将 UIViewContentMode 设置为 UIViewContentModeScaleAspectFit 或 UIViewContentModeScaleAspectFill,但这没有任何效果。

到目前为止,当我只沿着一个轴拉伸时,我仍然会得到扭曲的文本。

所以...

我有一个 UICollectionView,其单元格在 xib 中定义。目前该单元格仅包含一个 UILabel。集合视图使用 UICollectionViewFlowLayout 进行一些小的自定义:

self.flowLayout = [[UICollectionViewFlowLayout alloc] init];
[self.flowLayout setMinimumLineSpacing:1.0f];
[self.flowLayout setItemSize:CGSizeMake(self.cellSize.width, self.cellSize.height)];
[self.flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
[self.collectionView setCollectionViewLayout:self.flowLayout];

UICollectionView 嵌入在 UIScrollView 中,并且完全适合滚动视图的尺寸。滚动视图大小在两个方向上都设置为比屏幕大得多。硬编码数字仅用于测试;稍后我会将它们转换为适当的常量。

self.cellSize = CGSizeMake(150.0f, 150.0f);
CGSize scrollViewSize = self.scrollView.contentSize;
scrollViewSize.width = 20 * self.cellSize.width + 20.0f;
scrollViewSize.height = 20 * self.cellSize.height + 20.0f;
self.scrollView.contentSize = scrollViewSize;

self.collectionViewHeightConstraint.constant = self.scrollView.contentSize.height;
self.collectionViewWidthConstraint.constant = self.scrollView.contentSize.width;

结果是一个可以在任何方向滚动的网格。那部分正在工作。

网格需要可以按比例或一次仅沿一个轴进行拉伸。我正在使用以下捏合手势识别器进行单轴缩放(同样,y 的硬编码 1.0 值仅用于测试):

- (IBAction)handlePinchGesture:(UIPinchGestureRecognizer *)recognizer

    recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, 1.0);
    recognizer.scale = 1;

当我用捏合手势调整集合视图的大小时,每个单元格中的标签都会拉伸和变形。这是屏幕截图:(来源:afterburnerimages.com)

我很乐意提供任何其他相关信息,非常感谢所有帮助!

【问题讨论】:

不清楚你想要发生什么。如果你只在一个维度上拉伸一个视图,那么它里面的所有东西都会在一维上被拉伸,所以会被扭曲——这只是基本的几何图形,与编程无关。您希望在标签中看到什么文字? 我想让标签保持其纵横比,即使单元格的纵横比发生变化。我想到的两个选项是让标签在单元格大小变化时保持相同大小,或者在单元格不变化时让标签按比例拉伸。我希望将标签的视图与单元格的视图分开控制。 【参考方案1】:

好的,你正在使用包含集合视图的滚动视图,然后你可以使用滚动视图委托进行缩放,在你的情况下它是拉伸的,你可以像下面这样使用更好

例如,

- (void)viewDidLoad

   [super viewDidLoad];
   // Do any additional setup after loading the view, typically from a nib.
   _scrollView = [[UIScrollView alloc]initWithFrame:self.view.bounds];
   _scrollView.delegate = self;

   UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
   [flowLayout setMinimumLineSpacing:1.0f];
   [flowLayout setScrollDirection:UICollectionViewScrollDirectionVertical];
   [self.collectionVIew setCollectionViewLayout:flowLayout];
   [self.collectionVIew registerClass:[CustomCollectionVIewCell class] forCellWithReuseIdentifier:@"CELL_ID"];

   //setting up content size for scroll view
   CGSize size = self.scrollView.contentSize;
   size.width = 200 * 10;
   size.height = 185 * 10;
   self.scrollView.contentSize = size;
   CGRect rect = CGRectZero;
   rect.origin = self.scrollView.bounds.origin;
   rect.size = size;
   self.collectionVIew.frame = rect;
   self.scrollView.backgroundColor = [UIColor greenColor];
   [self.scrollView addSubview:self.collectionVIew];
   [self.view addSubview:self.scrollView];

  // CGRect scrollViewFrame = self.scrollView.frame;
  // CGFloat scaleWidth = _collectionVIew.frame.size.width / self.scrollView.contentSize.width;
  // CGFloat scaleHeight = _collectionVIew.frame.size.height / self.scrollView.contentSize.height;
  // CGFloat minScale = MIN(scaleWidth, scaleHeight);


   //set min scale must be less than max zoom scale so that it can be zoomable
   self.scrollView.minimumZoomScale = 0.5;
   self.scrollView.maximumZoomScale = 1.0f;
  // self.scrollView.zoomScale = minScale; //default is 1.0f;


并使用滚动视图代理来执行缩放

 - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
  
     return self.collectionVIew; //return collection view which is embedded inside scroll view
  

结果类似于下面的 gif 按比例拉伸而不影响集合视图的内容,希望这对你有帮助.. :)

【讨论】:

感谢您的建议。但我想让内容只水平拉伸,而不是按比例拉伸。 我想让单元格改变形状(纵横比)而不拉伸和扭曲文本。

以上是关于如何在不扭曲其内容的情况下沿一个轴调整 UICollectionViewCell 的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不缩放其内容的情况下调整 opengl 视口大小

如何在不使用 transform.Rotate 的情况下在其本地或世界轴上旋转带有第二个四元数的四元数?

是否可以制作一个 UILabel、UITextView 或类似的东西,它总是在不截断的情况下调整其高度以适应其在 Interface Builder 中的内容?

如何在不包含(或少量)背景像素的情况下调整对象内的矩形或调整其大小?

如何在不改变文本透明度的情况下为 UILabel 设置背景图像并调整其 alpha?

具有自动布局的多行UILabel,如何在不更改标签框架的情况下根据内容调整字体大小?