代码之家  ›  专栏  ›  技术社区  ›  Bob de Graaf

自定义UI视图布局带有方向和动画的子视图?

  •  2
  • Bob de Graaf  · 技术社区  · 12 年前

    我很困惑该用哪种方法来设置自定义UIViews的框架,其中有许多子视图,但仍然有动画并自动调整到旋转。当我创建一个新的视图控制器时,我通常会在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才设置实际的视图框架),但由于自动resizingmask,这一切都可以实现。

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

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

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

    -(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 WITH动画,它也会自动调整自己以适应旋转?

    我现在唯一能想到的解决方案(我不喜欢): 不要使用layoutSubview,而是使用自定义UIView的setFrame/setBounds方法来设置所有子视图的框架。然后在每次发生旋转时签入viewController,然后使用自定义UIView的setFrame/setBounds方法更改所有子视图的所有帧。我不喜欢这个解决方案,因为iOS5和iOS6中的旋转方法不同,我不想在每个有自己自定义UIView的UIViewController中都这样做。

    有什么建议吗?

    1 回复  |  直到 12 年前
        1
  •  0
  •   DBD    12 年前

    我最近开始重写 viewDidLayoutSubviews (多次而不是 viewWillAppear )在我的 UIViewControllers .

    视图Did布局子视图 被称为旋转。(来自评论)

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

    视图控制器.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.
    }