使用单步旋转时如何实现平滑的动画/如何在旋转开始时获取新的帧大小?

发布于 2024-09-14 12:21:59 字数 474 浏览 2 评论 0原文

我正在尝试从两级旋转切换到一级旋转(以避免控制台警告,并且因为苹果建议这样做,因为一级旋转速度更快)。

但是,我不知道如何尽早获取视图的新大小(考虑到导航栏、状态栏等),以便在动画期间执行 UI 更新(而不是简单地将项目捕捉到它们的位置)就像许多应用程序似乎所做的那样,在最后添加新位置,这会导致动画末尾出现一个大“混蛋”)。

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

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

任何关于其他人所采取的方法的反馈都会很棒!

谢谢

约瑟夫

I'm trying to switch from two-stage rotation to one-stage rotation (to avoid the console warning, and because Apple recommend doing so because one-stage is faster).

However I can't figure out how to get the new size of my view (taking into account the navigation bar, status bar, etc) early enough to perform the update of my UI during the animation (rather than simply snapping the items to their new positions at the end as many applications seem to do, which results in a big "jerk" right at the end of the animation).

The sizes I get in the willAnimateRotationToInterfaceOrientation:duration: method are (perhaps obviously) the old sizes.

I can see I should be able calculate it by hand, working out the current bar heights, then inferring the new view frame size by deducted those from the rotated screen dimensions? (which isn't that difficult to do, though is perhaps fragile as it assumes the navigation bar, status bar, etc will be the same height in both orientations, and you'd have to manually take account of the toolbar being different heights in portrait vs landscape - I just want to make sure I've not missed a more straightforward or common way.)

Any feedback on approaches other people have taken would be great!

Thanks

Joseph

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心在旅行 2024-09-21 12:21:59

我使用视图的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 作为委托。然后我可以从视图控制器布局子视图,访问当前方向等等。

I've had the most success using my view's layoutSubviews method for autorotations. When layoutSubviews gets called during an orientation change, the view's bounds are already set to what they will be at the conclusion of the rotation. You can also at this time query the status bar, navigation bar, and toolbar for their sizes and get the correct post-rotation values (although the status bar width and height may be swapped--I just take the smaller value as the height, works great). Using that information you can lay out subviews and they will then be animated as part of the rotation.

It can be annoying to create a UIView subclass for every situation where you want to do this, so I created a special subclass of UIView called DelegatingView, which looks like this:

@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

I use this as my base view, add subviews to it, and set my UIViewController as the delegate. Then I can layout subviews from my view controller, having access to the current orientation and so on.

谁许谁一生繁华 2024-09-21 12:21:59

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

如果您没有看到这一点,我建议您仔细检查您的视图是否具有适当的自动调整大小蒙版集。

Which OS version are you targeting? Under OS 4.0 (which is what I did a quick test in), [view bounds] within willAnimateRotationToInterfaceOrientation:duration: returns the new, post-rotation bounds.

If you are not seeing that, I’d suggest double-checking that your view has the appropriate auto resize mask set.

执手闯天涯 2024-09-21 12:21:59

如果您的视图控制器的视图有复杂的布局要求,那么创建 UIView 的子类并在 -layoutSubviews (执行视图布局的正确位置)中执行布局代码是值得的。正如希尔顿坎贝尔指出的,如果您使用这种方法进行布局,您可以检查框架大小和子视图关系并适当地设置它们的新位置。

如果您的视图控制器的视图有一组简单的子视图,那么您可能应该适当地设置它们的 autoresizingMask 属性,并让它们自动为自己设置动画。

If you have complex layout requirements in the view of your view controller, it is worth it to create a subclass of UIView and perform your layout code in -layoutSubviews (the correct place to do view layout). As Hilton Campbell pointed out, if you use this method for layout, you can check frame sizes and subview relationships and set their new positions appropriately.

If your view controller's view has a simple set of subviews, then you should probably just set their autoresizingMask properties appropriately, and let them animate themselves automagically.

泪眸﹌ 2024-09-21 12:21:59

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

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

前任:


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

在子视图中 - (void)notifyChildViewWillAppear:(BOOL)动画 { // 此时superview的bounds的大小 //等于内容视图的大小 //(没有导航栏的高度和工具栏的高度。 self.frame = [自我超级视图].bounds; }

2.) 手工计算所需的尺寸。
我计算为viewDidLoad。
导航栏和工具栏的大小可以通过以下代码得出。


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

I tried two methods to adjust view's size.

1.) notify child views to adjust their size after -(void)viewWillAppear;
The drawback is that it will be executed each time when viewWillAppear.

ex:


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

at child view - (void)notifyChildViewWillAppear:(BOOL)animated { // at this time, the size of superview's bounds //equals the content view's size // (no navigationBar's height and toolbar's height. self.frame = [self superview].bounds; }

2.) Calculate the necessary size by hand.
I calculate as viewDidLoad.
The sizes of navigationBar and toolBar can be derived by following code.


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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文