转换UIScrollView的子视图

时间:2014-04-02 18:44:08

标签: ios objective-c uiscrollview core-animation

我正在尝试重现iOS 7应用切换器之类的效果,我可以在较小的转换视图之间滚动。我目前的障碍是获取contentOffset

为了做到这一点,我在我的视图中添加了一个scrollView,并将其调整为视图的边界。然后,我创建了一个容器视图,该视图可以保留所有卡片' - 这是我应用转换的容器视图。

无论如何,我遇到的问题是在应用了变换后调整其中特定卡片出现 - 现在,我无法在变换过程中以一种方式调整contentOffset很顺利

无论如何,代码会有所帮助!这是:

NSInteger idx = selectedCardIndex;

if (TransformApplied)
{        
    [UIView animateWithDuration:0.5 animations:^{
        [self.container setTransform:CGAffineTransformIdentity];
        [self.container setFrame:CGRectOffset(self.container.frame, (1-ScaleFactor)/2 * NumCards * ScreenWidth, 0)];
        [self.scrollView setContentSize:self.container.frame.size];
        [self.scrollView setContentOffset:CGPointMake(ScreenWidth * idx, 0) animated:NO];

        [self.scrollView setPagingEnabled:YES];

    } completion:^(BOOL finished) {
        TransformApplied = NO;
    }];
}
else
{
    [UIView animateWithDuration:0.5 animations:^{
        [self.container setTransform:CGAffineTransformMakeScale(ScaleFactor, ScaleFactor)];
        [self.container setFrame:CGRectOffset(self.container.frame, (-1)*((1-ScaleFactor)/2) * NumCards * ScreenWidth, 0)];
        [self.scrollView setContentSize:CGSizeMake(ScreenWidth * ScaleFactor * NumCards, ScreenHeight * ScaleFactor)];
        [self.scrollView setContentOffset:CGPointMake(ScaleFactor * ScreenWidth * idx, 0) animated:NO];


        [self.scrollView setPagingEnabled:NO];

    } completion:^(BOOL finished) {
        TransformApplied = YES;
    }];
}

更多 我注意到在应用身份变换时一切都很顺利,但是当应用较小的变换时,我得到一个奇怪的跳跃'在动画之前的帧中。

如果我在缩放变换(底部块)中注释掉内容偏移调整,那么一切都会顺利运行,但是在缩放变换后contentOffset是错误的。

最后,调用setContentOffset:animated:会产生一个不稳定的动画,所以这是不行的。

任何帮助都非常感谢!!!!

更新

我已经研究过在CALayer上锚定点/位置属性,并且我已经完美地使用了动画效果:

NSInteger idx = selectedCardIndex;

if (TransformApplied)
{
    [UIView dd_AnimateWithDuration:0.5 animations:^{
        [self.container setTransform:CGAffineTransformIdentity];
        [self.scrollView setContentOffset:CGPointMake(ScreenWidth * idx, 0) animated:NO];

        [self.scrollView setPagingEnabled:YES];

    } completion:^(BOOL finished) {
        TransformApplied = NO;
    }];
}
else
{
    CGPoint anchor      = CGPointMake((idx * ScreenWidth + ScreenWidth/2)/CGRectGetWidth(self.container.frame), 0.5f);
    [self.container.layer setAnchorPoint:anchor];
    CGPoint position    = CGPointMake((anchor.x) * self.container.frame.size.width, self.container.layer.position.y);
    [self.container.layer setPosition:position];

    [UIView dd_AnimateWithDuration:0.5 animations:^{
        [self.container setTransform:CGAffineTransformMakeScale(ScaleFactor, ScaleFactor)];

        [self.scrollView setPagingEnabled:NO];

    } completion:^(BOOL finished) {
        TransformApplied = YES;
    }];
}

然而,现在我必须想办法摆脱滚动视图中的所有额外空间,而不允许更改容器的位置....

1 个答案:

答案 0 :(得分:0)

很久以前,我有一个关于视图位置的类似问题。经过长时间的研究,我得到了UIView文档。它会显示transform的{​​{1}}和frame属性并带有警告:

  

警告:   如果transform属性不是identity变换,则此属性的值未定义,因此应忽略。   更改框架矩形会自动重新显示接收器而不调用drawRect:方法。如果希望在框架矩形更改时调用drawRect:方法,请将contentMode属性设置为UIViewContentModeRedraw。   可以对此属性的更改进行动画处理。但是,如果transform属性包含非标识变换,则frame属性的值是未定义的,不应修改。在这种情况下,您可以使用center属性重新定位视图,并使用bounds属性调整大小。

因此,基本的想法是,当您的观看UIView包含非身份转换时,您不应该依赖或更改frame

更重要的想法是,在寻找其他地方之前,总是给官方文档提供机会。

我希望这会有所帮助。