自定义UIView layoutSubviews具有方向和动画?

时间:2013-03-25 09:02:26

标签: iphone ios uiview core-animation layoutsubviews

我处于两难境地,这种方法用于设置自定义UIViews的帧,其中包含许多子视图,并且仍然具有动画并自动调整为旋转。我在创建新的viewcontroller时通常会在loadView或viewDidLoad中分配我的自定义视图,例如:

-(void)viewDidLoad
{
    [super viewDidLoad];
    detailView = [[DetailView alloc] initWithFrame:CGRectMake(0, 0,      self.view.frame.size.width, self.view.frame.size.height)];
    detailView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
    self.view = detailView;    
}

通常这个宽度& iPhone5屏幕的高度不正确(实际的视图框架在viewWillAppear之前没有设置),但由于自动调整遮罩,所有这些都可以解决。

然后在自定义UIView DetailView的initWithFrame中,我用CGRectZero分配所有子视图,例如:

-(id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        label = [[UILabel alloc] initWithFrame:CGRectZero];
        [self addSubview:label];
    }
 }

然后我覆盖layoutsubviews以设置所有子视图的所有帧。这适用于任何屏幕尺寸和任何方向,例如:

-(void)layoutSubviews
{
    [super layoutSubviews];
    label.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
}

然而,我发现当你使用动画时layoutSubviews并不是那么好,因为当你在动画块中使用动画时,在动画中间调用layoutsubviews并完全打破动画,例如:

-(void)animateLabel
{
    [UIView animateWithDuration:0.4f animations:^
    {
        label.transform = CGAffineTransformMakeTranslation(100, 100);
    }];
}

我相信通过为每个动画使用标志并且在布局子视图中使用这些标志来设置动画块的正确开始或结束帧,这有一些丑陋的变通方法,但我认为我不应该为每个动画创建一个标志。动画我想做。

所以现在我的问题是:我应该如何设置自定义UIView动画,并自动将其自身调整为旋转?

我现在可以提出的唯一解决方案(我不喜欢): 不要使用layoutSubviews,而是使用自定义UIView的setFrame / setBounds方法来设置所有子视图的帧。然后每次轮换时检查viewController,然后使用自定义UIView的setFrame / setBounds方法更改所有子视图的所有帧。我不喜欢这个解决方案,因为iOS5和iOS6中的旋转方法不同,我不想在每个UIViewController中使用它自己的自定义UIView。

有什么建议吗?

1 个答案:

答案 0 :(得分:0)

我最近在我的viewDidLayoutSubviews中开始覆盖viewWillAppear(多次而不是UIViewControllers)。

是轮换时调用viewDidLayoutSubviews。 (来自评论)

该方法在所有内部布局都已完成后触发,因此应设置所有已完成的帧,但仍然可以在视图可见之前为您提供进行调整的时间,并且不应该出现任何动画问题,因为你还没有进入动画块。

viewcontroller.m

- (void)viewDidLayoutSubViews {
    // At this point I know if an animation is appropriate or not.
    if (self.shouldRunAnimation)
        [self.fuView runPrettyAnimations];
}

fuView.m

- (void)runPrettyAnimations {
    // My animation blocks for whatever layout I'd like.
}

- (void)layoutSubviews {
    // My animations are not here, but non animated layout changes are.
    // - Here we have no idea if our view is visible to the user or may appear/disappear
    // partway through an animation.
    // - This also might get called far more than we intend since it gets called on
    // any frame updates.
}