UICollectionViewCell 捏合中的 CALayer
CALayer inside UICollectionViewCell pinch
我加了一个GIF来描述一个问题。我有一个包含很多单元格的 UICollectionView
,每个单元格内部都有一个 CALayer
。我的 UICollectionView
中有一个 pinch
手势。当它放大时,看起来每个单元格都在放大。查看 gif 上单元格之间的空格。是否可以一起放大每个单元格?提前致谢
代码:
单元格子类
@property (nonatomic, strong) CALayer *circularLayer;
- (void)layoutSubviews
{
[self updateRoundedCorners];
}
- (void)updateRoundedCorners
{
CGRect bounds = self.bounds;
self.circularLayer.bounds = bounds;
self.circularLayer.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
}
#pragma mark - Property Set
- (void)setCellObject:(VenueLayoutCellObject *)cellObject
{
self->_cellObject = cellObject;
self.objectBackgroundColor = cellObject.objectColor;
self.type = cellObject.type;
}
控制器
- (void)didReceivePinchGesture:(UIPinchGestureRecognizer *)gesture
{
static CGFloat scaleStart;
if (gesture.state == UIGestureRecognizerStateBegan) {
scaleStart = self.venueLayoutZoom;
}
else if (gesture.state == UIGestureRecognizerStateChanged) {
self.venueLayoutZoom = scaleStart * gesture.scale;
[self.activeCollectionView.collectionViewLayout invalidateLayout];
}
}
更新:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
VenueLayoutCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kVenueLayoutCellReuseIdentifier forIndexPath:indexPath];
self.activeCollectionViewCellsDictionary[indexPath] = cell;
if (self.activeCollectionViewObjects.count > indexPath.section) {
NSArray *rows = self.activeCollectionViewObjects[indexPath.section];
if (rows.count > indexPath.row) {
if ([rows[indexPath.row] isKindOfClass:[VenueLayoutCellObject class]]) {
VenueLayoutCellObject *object = rows[indexPath.row];
cell.cellObject = object;
}
}
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
CGFloat widthAndHeight = [self widthAndHeightForActiveCollectionViewItem];
return CGSizeMake(widthAndHeight *self.venueLayoutZoom, widthAndHeight * self.venueLayoutZoom);
}
- (CGFloat)widthAndHeightForActiveCollectionViewItem
{
NSArray *array = self.activeCollectionViewObjects;
__block NSInteger maxCount = 0;
[array enumerateObjectsUsingBlock:^(NSArray *subArray, NSUInteger idx, BOOL * _Nonnull stop) {
if (subArray.count > maxCount) {
maxCount = subArray.count;
}
}];
CGFloat widthAndHeight = CGRectGetWidth(self.activeCollectionView.bounds) / maxCount;
return widthAndHeight;
}
单元格子类
@property (nonatomic, strong) CALayer *circularLayer;
- (void)layoutSubviews
{
[super layoutSubviews];
[self updateRoundedCorners];
}
我看到这段代码唯一的重要问题是缺少 [super layoutSubviews];
如果它不起作用,请提供更多代码。
您对图层所做的更改是 implicitly animated,这意味着它们是通过动画执行的,即使您没有特别指示它们这样做。
由于您是在响应用户手势,因此您不希望更改是动画的,因为这会使它们滞后于手势。
您可以像这样在布局子视图期间关闭隐式动画:
- (void)layoutSubviews
{
[super layoutSubviews];
[CATransaction begin];
[CATransaction setDisableActions: YES];
[self updateRoundedCorners];
[CATransaction commit];
}
我加了一个GIF来描述一个问题。我有一个包含很多单元格的 UICollectionView
,每个单元格内部都有一个 CALayer
。我的 UICollectionView
中有一个 pinch
手势。当它放大时,看起来每个单元格都在放大。查看 gif 上单元格之间的空格。是否可以一起放大每个单元格?提前致谢
代码:
单元格子类
@property (nonatomic, strong) CALayer *circularLayer;
- (void)layoutSubviews
{
[self updateRoundedCorners];
}
- (void)updateRoundedCorners
{
CGRect bounds = self.bounds;
self.circularLayer.bounds = bounds;
self.circularLayer.position = CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
}
#pragma mark - Property Set
- (void)setCellObject:(VenueLayoutCellObject *)cellObject
{
self->_cellObject = cellObject;
self.objectBackgroundColor = cellObject.objectColor;
self.type = cellObject.type;
}
控制器
- (void)didReceivePinchGesture:(UIPinchGestureRecognizer *)gesture
{
static CGFloat scaleStart;
if (gesture.state == UIGestureRecognizerStateBegan) {
scaleStart = self.venueLayoutZoom;
}
else if (gesture.state == UIGestureRecognizerStateChanged) {
self.venueLayoutZoom = scaleStart * gesture.scale;
[self.activeCollectionView.collectionViewLayout invalidateLayout];
}
}
更新:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
VenueLayoutCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kVenueLayoutCellReuseIdentifier forIndexPath:indexPath];
self.activeCollectionViewCellsDictionary[indexPath] = cell;
if (self.activeCollectionViewObjects.count > indexPath.section) {
NSArray *rows = self.activeCollectionViewObjects[indexPath.section];
if (rows.count > indexPath.row) {
if ([rows[indexPath.row] isKindOfClass:[VenueLayoutCellObject class]]) {
VenueLayoutCellObject *object = rows[indexPath.row];
cell.cellObject = object;
}
}
}
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout *)collectionViewLayout
sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
CGFloat widthAndHeight = [self widthAndHeightForActiveCollectionViewItem];
return CGSizeMake(widthAndHeight *self.venueLayoutZoom, widthAndHeight * self.venueLayoutZoom);
}
- (CGFloat)widthAndHeightForActiveCollectionViewItem
{
NSArray *array = self.activeCollectionViewObjects;
__block NSInteger maxCount = 0;
[array enumerateObjectsUsingBlock:^(NSArray *subArray, NSUInteger idx, BOOL * _Nonnull stop) {
if (subArray.count > maxCount) {
maxCount = subArray.count;
}
}];
CGFloat widthAndHeight = CGRectGetWidth(self.activeCollectionView.bounds) / maxCount;
return widthAndHeight;
}
单元格子类
@property (nonatomic, strong) CALayer *circularLayer;
- (void)layoutSubviews
{
[super layoutSubviews];
[self updateRoundedCorners];
}
我看到这段代码唯一的重要问题是缺少 [super layoutSubviews]; 如果它不起作用,请提供更多代码。
您对图层所做的更改是 implicitly animated,这意味着它们是通过动画执行的,即使您没有特别指示它们这样做。
由于您是在响应用户手势,因此您不希望更改是动画的,因为这会使它们滞后于手势。
您可以像这样在布局子视图期间关闭隐式动画:
- (void)layoutSubviews
{
[super layoutSubviews];
[CATransaction begin];
[CATransaction setDisableActions: YES];
[self updateRoundedCorners];
[CATransaction commit];
}