【问题标题】:UIView transform property is being resetUIView 转换属性正在重置
【发布时间】:2014-08-01 20:58:14
【问题描述】:

我有一个 UICollectionView。我想要一种行为,当用户触摸一个单元格时,它会缩小,就好像它被稍微向下推一样。我已经通过使用 UICollectionViewDelegate 方法完成了这项工作:

- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    [self scaleDownCell:cell];
}

- (void) collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(NSIndexPath *)indexPath{
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    [self scaleUpCell:cell];
}

我的问题是有时我的单元格会开始缩小,然后突然变回全尺寸,而不执行放大动画,产生生涩的效果。在调用我的放大方法之前,我已经用断点检查它是否放大了。我正在尝试找出原因。

比例函数如下:

+ (void)scaleDownCell:(UICollectionViewCell *)cell
{
    CGAffineTransform transform = CGAffineTransformMakeScale(0.95, 0.95);    
    [UIView animateWithDuration:SCALE_DOWN_ANIMATION_DURATION
                          delay:0.0
         usingSpringWithDamping:SCALE_DOWN_SPRING_DAMPING
          initialSpringVelocity:SCALE_DOWN_SPRING_VELOCITY
                        options:0
                     animations:^{
                         cell.transform = transform;
                     }
                     completion:^(BOOL finished) {
                     }];
}

+ (void)scaleUpCell:(UBCollectionViewCell *)cell
{
    CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 1.0);    
    [UIView animateWithDuration:SCALE_UP_ANIMATION_DURATION
                          delay:0.3
         usingSpringWithDamping:SCALE_UP_SPRING_DAMPING
          initialSpringVelocity:SCALE_UP_SPRING_VELOCITY
                        options:0
                     animations:^{
                         cell.transform = transform;
                     }
                     completion:^(BOOL finished) {
                     }];
}

编辑:我基本上想用这种缩放行为替换我的单元格中的突出显示,它具有完全相同的目的,我希望它发生在单元格突出显示的完全相同的情况下,所以它似乎是一个合适的地方应用我的转变。

无论如何,我首先尝试在单元子类中覆盖 UIResponder 触摸方法,但观察到相同的行为。即使我删除了放大方法以使其永远不会被调用,也会发生突然放大,因此放大动画不会取消我的缩小。我可以通过日志语句看到我的缩减被调用一次,并且动画完成块被调用 finsished == YES。在调用完成块之前,单元格正在按比例放大(我已将动画持续时间设置为超长以帮助调试)。当我触摸单元格然后快速滚动时似乎会发生这种情况,所以我猜滚动与它有关。

【问题讨论】:

  • 断点不会显示变换是否完成动画,因为这是在图层的属性上执行的,并且在动画开始后立即设置为这样。您可以发布您定义的常量 - 您确定放大延迟 (0.3) 大于 SCALE_DOWN_ANIMATION_DURATION 常量吗?
  • 感谢您的评论。我已经尝试过使用不同的常量来试图弄清楚发生了什么,但正如我编辑的问题中所述,即使我从未调用放大方法,我仍然会看到我的变换的相同重置。
  • @Darren 然后发生了其他事情。毕竟,放大方法所做的只是将变换设置为 1 的比例 - 也就是说,没有效果。因此,如果您看到事情扩大了,那么显然您还有其他代码,您自己不知道并且上面没有引用,那就是这样做!你需要找到那个代码。
  • 或者我想知道这是否是自动布局和视图变换是敌人的经典问题(我在这里详细讨论:stackoverflow.com/questions/12943107/…) - 尝试用 CABasicAnimation 替换您的 UIView 动画并查看如果能解决的话。
  • 我有另一个想法 - 你对滚动的评论很有启发性。想想集合视图布局是如何工作的 - it 负责每个单元格的属性,包括它的变换 (developer.apple.com/library/ios/documentation/uikit/reference/…)。所以很自然,如果你自己改变单元格的变换,你不告诉布局,布局负责,它会取消你的变换。

标签: ios uiview uiviewanimation


【解决方案1】:

问题在于,您正在劫持“突出显示”的概念,而不是某些东西。突出显示是一项复杂而令人困惑的业务。在被点击和选择的过程中,单元格会多次突出显示和取消突出显示。因此,响应是错误的。

如果您尝试检测的是 touch,那么您应该响应 touch。如果手势识别器不行,那么使用你自己的单元子类,这样你就可以直接实现 UITouch 检测。

要记住的另一件事是,按照您编写此内容的方式,如果在缩小过程中扩大规模,它只会将其杀死。

编辑 - 最后一个想法 - 在您的编辑中,您发表评论说滚动与此有关。这就说得通了。想想集合视图布局是如何工作的 - 负责每个单元格的属性,包括它的变换 (https://developer.apple.com/library/ios/documentation/uikit/reference/UICollectionViewLayoutAttributes_class/Reference/Reference.html)。所以很自然,如果你自己改变单元格的变换,你不告诉布局,而布局负责,它会取消你的变换。

【讨论】:

  • 感谢您的回答,我添加了我的 cmets 在我的问题中解决了这个问题,因为它们太长了,无法发表评论。
  • 转换被 UICollectionViewLayout 子类中 layoutAttributesForElementsInRect: 方法返回的 UICollectionViewLayoutAttributes 重置。我可以通过在此方法中将属性转换属性设置为相应集合视图单元格的转换来解决此问题。感谢您的帮助!
  • 很高兴你把它修好了!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-27
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多