使用单步旋转时如何实现流畅动画 / 如何在旋转开始时获取新的帧尺寸?

4

我想从两阶段旋转切换到一阶段旋转(以避免控制台警告,并因为苹果建议这样做,因为一阶段更快)。

然而,我无法在动画期间及早获得视图的新大小(考虑到导航栏、状态栏等),以执行更新UI的操作(而不是像许多应用程序那样仅在最后将项目捕捉到其新位置,这会导致动画结束时出现大的“抽搐”)。

我在 willAnimateRotationToInterfaceOrientation:duration: 方法中获得的尺寸是(或许很明显)旧的尺寸。

我可以手动计算它,计算出当前的栏高度,然后通过从旋转屏幕尺寸中减去这些来推断新的视图框架大小?(虽然这并不难做到,但可能很脆弱,因为它假设导航栏、状态栏等在两个方向上的高度相同,并且您必须手动考虑工具栏在纵向和横向上的高度不同 - 我只想确保我没有错过更简单或更常见的方法。)

任何其他人采取的方法的反馈都很好!

谢谢

Joseph

4个回答

5
我在it技术方面最成功的方法是使用视图的layoutSubviews方法进行自动旋转。当在方向更改期间调用layoutSubviews时,视图的边界已经设置为旋转结束时的边界。此时,您还可以查询状态栏、导航栏和工具栏的大小,并获取正确的旋转后值(尽管状态栏的宽度和高度可能会交换--我只取较小的值作为高度,效果很好)。利用这些信息,您可以布置子视图,然后他们将作为旋转的一部分进行动画处理。
创建每种情况都要使用UIView子类可能会很烦人,因此我创建了一个名为DelegatingView的特殊UIView子类,如下所示:
@protocol DelegatingViewDelegate

- (void)layoutSubviewsForView:(UIView*)view;

@end

@interface DelegatingView : UIView {
    id<DelegatingViewDelegate> _delegate;
}

@property (nonatomic,assign) id<DelegatingViewDelegate> delegate;

@end

@implementation DelegatingView

@synthesize delegate = _delegate;

- (void)layoutSubviews {
    [super layoutSubviews];
    [_delegate layoutSubviewsForView:self];
}

@end

我使用这个作为我的基础视图,在它上面添加子视图,并将UIViewController设置为代理。然后我可以从我的视图控制器中布局子视图,可以访问当前的方向等信息。


谢谢您,layoutSubviews确实效果更好;我想知道为什么苹果的旋转文档完全没有提到这个选项! - JosephH

3
你的目标操作系统版本是哪个?在操作系统4.0下(我进行了快速测试),[view bounds]willAnimateRotationToInterfaceOrientation:duration: 中会返回新的旋转后边界。

如果您没有看到这个,建议您再次确认视图是否设置了适当的自动调整大小掩码。


不幸的是,我还必须针对3.1和3.2。我需要检查我的代码,看看它是否在4.0上有效,或者是否存在某些更广泛的问题阻止了它的工作。谢谢您的回答,我会在检查更多后更新这个问题。 - JosephH

2

如果您的视图控制器中有复杂的布局需求,那么值得创建一个UIView子类,并在-layoutSubviews(进行视图布局的正确位置)中执行布局代码。正如Hilton Campbell所指出的那样,如果您使用此方法进行布局,则可以检查框架大小和子视图关系,并适当设置它们的新位置。

如果您的视图控制器的视图具有简单的一组子视图,则应该恰当地设置它们的autoresizingMask属性,并让它们自动动画化。


0

我尝试了两种方法来调整视图的大小。

1.) 在 -(void)viewWillAppear 之后通知子视图调整它们的大小。缺点是每次 viewWillAppear 都会执行。

ex:


- (void)viewWillAppear:(BOOL)animated
{
  [super viewWillAppear:animated];
  [self notifyChildViewWillAppear:animated];
}

在子视图中 - (void)notifyChildViewWillAppear:(BOOL)animated { // 此时,父视图边界的大小等于内容视图的大小 //(没有navigationBar的高度和工具栏的高度)。 self.frame = [self superview].bounds; }

2.) 手动计算所需的大小。 我会在viewDidLoad方法中计算。 navigationBar和toolBar的大小可以通过以下代码推导出来。


self.navagationController.navigationBar.view.frame.size.height;
self.tabBarController.tabBar.frame.size.height;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接