自定义UIView布局与方向和动画的子视图?
我处在一个困境,哪个方法用于设置自定义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。
有什么建议吗?
我最近开始在我的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.
}
嗨DBD,谢谢你的回答。 viewDidLayoutSubviews也被称为轮换更改吗?你如何建议我实施这个?通过在此方法内的自定义视图上调用setFrame? – 2013-03-25 12:42:13
我会倾向于在自定义的公共方法中对视图进行动画调用,这些视图根据需要从UIViewController调用。我一直犹豫在视图中添加自动动画,因为你永远不知道视图是否在屏幕上可见或不可见。您可能只会在动画中途出现视图。 – DBD 2013-03-25 14:18:20
DBD,你能解释一下你最近的评论吗?你的意思是你不会把调用放到自定义的UIViews中去执行动画?你能回答我的第一条评论的问题吗? :) – 2013-03-25 14:40:02
我也遇到了这个问题。你有其他正确的解决方案吗? – ShengHuaWu 2013-10-27 15:14:34
嗨盛华武,我现在做的是以下。我仍然创建一个不实现layoutsubviews的自定义子视图。然后我在该视图中使用自定义的setNewFrame方法,该方法是在加载视图控制器和任何旋转更改时设置的。在那个自定义的setNewFrame方法中,我为那里的所有子视图设置了所有的框架。这种方式看起来不错,在子视图中的任何旋转和动画完美:) – 2013-10-27 17:04:49
感谢您的分享。 – ShengHuaWu 2013-11-12 14:25:46