2013-03-25 102 views
2

我处在一个困境,哪个方法用于设置自定义UIViews框架与许多子视图,并仍然有动画和自动调整旋转。我最常做的,当我创建一个新的视图 - 控制的页头中的loadView或viewDidLoad中我的自定义视图,例如:自定义UIView布局与方向和动画的子视图?

-(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),但由于autoresizingmask它一切运作。

然后在自定义的UIView的DetailView的initWithFrame,我ALLOC所有子视图与CGRectZero,e.g:

-(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不是那么大,当你使用动画,因为当你在animationblock使用动画,layoutsubviews被称为动画的中间,它彻底打破了动画,如:

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

我相信有丑陋的解决方法这通过使用标志为每个动画和layoutsubviews使用这些标志设置动画的正确的开始或endframe但我认为我不应该为每个我想要做的动画创建一个标志。

所以我的问题是现在:我应该如何有一个自定义UIView动画,也可以自动调整自己旋转?

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

有什么建议吗?

+0

我也遇到了这个问题。你有其他正确的解决方案吗? – ShengHuaWu 2013-10-27 15:14:34

+1

嗨盛华武,我现在做的是以下。我仍然创建一个不实现layoutsubviews的自定义子视图。然后我在该视图中使用自定义的setNewFrame方法,该方法是在加载视图控制器和任何旋转更改时设置的。在那个自定义的setNewFrame方法中,我为那里的所有子视图设置了所有的框架。这种方式看起来不错,在子视图中的任何旋转和动画完美:) – 2013-10-27 17:04:49

+0

感谢您的分享。 – ShengHuaWu 2013-11-12 14:25:46

回答

0

我最近开始在我的UIViewControllers中开始覆盖viewDidLayoutSubviews(多次代替viewWillAppear)。

是的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. 
} 
+0

嗨DBD,谢谢你的回答。 viewDidLayoutSubviews也被称为轮换更改吗?你如何建议我实施这个?通过在此方法内的自定义视图上调用setFrame? – 2013-03-25 12:42:13

+0

我会倾向于在自定义的公共方法中对视图进行动画调用,这些视图根据需要从UIViewController调用。我一直犹豫在视图中添加自动动画,因为你永远不知道视图是否在屏幕上可见或不可见。您可能只会在动画中途出现视图。 – DBD 2013-03-25 14:18:20

+0

DBD,你能解释一下你最近的评论吗?你的意思是你不会把调用放到自定义的UIViews中去执行动画?你能回答我的第一条评论的问题吗? :) – 2013-03-25 14:40:02