带有 CustomView 的 MBProgressHUD:为什么我不能为我的自定义视图设置动画? [英] MBProgressHUD with CustomView: Why can't I animate my custom view?

查看:26
本文介绍了带有 CustomView 的 MBProgressHUD:为什么我不能为我的自定义视图设置动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不知何故不起作用......为什么?如何在不从动画中制作 gif 的情况下实现旋转的自定义螺旋桨?

This somehow doesn't work...why? How can I achieve a spinning custom propeller without making a gif out of the animation?

-(UIView *)propTest
{
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 37, 37)];

    UIImageView *movablePropeller = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 37 , 37)];

    movablePropeller.image = [UIImage imageNamed:@"MovablePropeller"];


    [view addSubview:movablePropeller];
    movablePropeller.center = view.center;

    CABasicAnimation *rotation;
    rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotation.fromValue = [NSNumber numberWithFloat:0.0f];
    rotation.toValue = [NSNumber numberWithFloat:(2 * M_PI)];
    rotation.cumulative = true;
    rotation.duration = 1.2f; // Speed
    rotation.repeatCount = INFINITY; // Repeat forever. Can be a finite number.

    [movablePropeller.layer addAnimation:rotation forKey:@"Spin"];

    return view;
}

-(void)presentMyHud
{
    MBProgressHUD *hud = [[MBProgressHUD alloc] initWithView:self.view];
    [self.view addSubview:hud];
    hud.mode = MBProgressHUDModeCustomView;
    hud.customView = [self propTest];
    hud.detailsLabelText = @"Getting data";
    [hud show:YES];
}

但我的螺旋桨保持静止...

But my propeller stays static...

推荐答案

如果螺旋桨没有旋转,如果您没有立即将此 view 添加到视图层次结构中,就会发生这种情况.通常,在addAnimation之前将视图添加到视图层次结构是明智的.

If the propeller is not spinning, that can happen if you didn’t immediately add this view to the view hierarchy. Generally, it’s prudent to add the view to the view hierarchy before you addAnimation.

- (UIView *)addPropellerToView:(UIView *)view {
    UIView *containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 37, 37)];

    // make sure to add it to the view hierarchy

    [view addSubview:containerView];

    // if you want to center it, set its `center` to be in the middle of the `bounds` ... don't use `center`

    containerView.center = CGPointMake(view.bounds.origin.x + view.bounds.size.width / 2, view.bounds.origin.y + view.bounds.size.height / 2);

    // I'd just use the `bounds` of the container view; reducing the risk that we get its coordinates wrong

    UIImageView *movablePropeller = [[UIImageView alloc] initWithFrame:containerView.bounds];

    movablePropeller.image = [UIImage imageNamed:@"MovablePropeller"];
    movablePropeller.contentMode = UIViewContentModeScaleAspectFill;

    [containerView addSubview:movablePropeller];

    // never set the center of a view to the center of its super view ... those are two different coordinate systems.
    // in this case, this line isn't needed at all, so I'll remove it.
    //
    //     movablePropeller.center = containerView.center;

    CABasicAnimation *rotation;
    rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotation.fromValue = @(0);
    rotation.toValue = @(2 * M_PI);
    rotation.cumulative = true;
    rotation.duration = 1.2f;
    rotation.repeatCount = INFINITY;

    [movablePropeller.layer addAnimation:rotation forKey:@"Spin"];

    return containerView;
}

产量:

一些不相关的观察:

  • 如果要将视图 A 置于视图 B 的中间,请将视图 A 的 center 设置为坐标到 B bounds 的中点,而不是 B 的中点中心.例如,你永远不想做:

  • If you want to center view A in the middle of view B, set view A’s center to coordinates to the midpoint of B’s bounds, not to B’s center. E.g., you never want to do:

A.center = B.center;

你想要的是:

A.center = CGPointMake(B.bounds.origin.x + B.bounds.size.width / 2, B.bounds.origin.y + B.bounds.size.height / 2);

我知道看起来应该是一回事,但事实并非如此.A的centerframe一样是在B的坐标系中定义的.但是B的center是在它的坐标系中定义的超级视图, 可能完全不同.有时您不会注意到差异(特别是如果 B 的 origin{0, 0}),但这表明对不同坐标系的误解,如果 B 不是't at {0, 0},那么一切都会出错.

I know it looks like it should be the same thing, but it’s not. A’s center is defined, like frame, in the coordinate system of B. But B’s center is defined in the coordinate system of its superview, which might be completely different. Sometimes you won’t notice the difference (specifically if B’s origin is {0, 0}), but it suggests a misunderstanding of the different coordinate systems, and if B isn’t at {0, 0}, then everything will be wrong.

您可以使用 NSNumber 文字,将 [NSNumber numberWithFloat:0.0f] 替换为 @(0).

You can use NSNumber literals, replacing [NSNumber numberWithFloat:0.0f] with @(0).

你真的不需要那个容器视图,所以你可以简化例程,如下所示.

You really don’t need that container view, so you could simplify the routine, like below.

- (UIView *)addPropellerTo:(UIView *)view {
    UIImageView *movablePropeller = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 37, 37)];
    movablePropeller.image = [UIImage imageNamed:@"MovablePropeller"];
    movablePropeller.contentMode = UIViewContentModeScaleAspectFill;
    [view addSubview:movablePropeller];
    movablePropeller.center = CGPointMake(view.bounds.origin.x + view.bounds.size.width / 2, view.bounds.origin.y + view.bounds.size.height / 2);

    CABasicAnimation *rotation;
    rotation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotation.fromValue = @(0);
    rotation.toValue = @(2 * M_PI);
    rotation.cumulative = true;
    rotation.duration = 1.2f;
    rotation.repeatCount = INFINITY;

    [movablePropeller.layer addAnimation:rotation forKey:@"Spin"];

    return movablePropeller;
}

这篇关于带有 CustomView 的 MBProgressHUD:为什么我不能为我的自定义视图设置动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆