动画未执行到另一个视图控制器

时间:2012-10-21 19:38:26

标签: objective-c ios cocoa-touch

我试图在一个视图中触发动画,基于单独的类文件中发生的事情。它得到了方法,它支持吐出两个NSLog语句,但不提交UIView Animation

以下是代码:

ViewController.h

@interface ViewController : UIViewController {

}

-(void)closeMenu;

ViewController.m

-(void)closeMenu{

    //close the menu
    NSLog(@"Got here");

    [UIView animateWithDuration:0.6 animations:^{

        [UIView setAnimationBeginsFromCurrentState:YES]; // so it doesn't cut randomly, begins from where it is

        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];

        [menuView setFrame:CGRectMake(menuView.frame.origin.x, -menuView.frame.size.height, menuView.frame.size.width, menuView.frame.size.height)];

    }];


    NSLog(@"Got here2");

}

OtherClass.m(注释的代码可能与这个问题无关,当然在实际应用中仍然使用。但Jut认为它可能使理解更容易)

#import "ViewController.h"

...

//- (void) item:(SDGroupCell *)item subItemDidChange:(SDSelectableCell *)subItem
//{
    ViewController *foo = [[[ViewController alloc] init] autorelease];

    //SelectableCellState state = subItem.selectableCellState;
    //NSIndexPath *indexPath = [item.subTable indexPathForCell:subItem];
    //switch (state) {
        //case Checked:
            //NSLog(@"Changed Sub Item at indexPath:%@ to state \"Checked\"", indexPath);

            //close the menuView

            [foo closeMenu];

            //break;
        //case Unchecked:
            //NSLog(@"Changed Sub Item at indexPath:%@ to state \"Unchecked\"", indexPath);
            //break;
        //default:
            //break;
    //}
}

2 个答案:

答案 0 :(得分:1)

您将旧式动画与基于块的动画混合在一起。例如,在文档中,它指出了setAnimationBeginsFromCurrentState

  

在iOS 4.0及更高版本中不鼓励使用此方法。相反,你   应该使用theanimateWithDuration:delay:options:animations:completion:   指定动画和动画选项的方法。

我不能100%确定是否支持此功能。您应该至少将动画代码更改为:

[UIView animateWithDuration:0.6
                      delay:0.0
                    options:UIViewAnimationOptionBeginFromCurrentState|UIViewAnimationOptionCurveEaseInOut  
                 animations:^{
    [menuView setFrame:CGRectMake(menuView.frame.origin.x, -menuView.frame.size.height, menuView.frame.size.width, menuView.frame.size.height)];

                            }
                 completion:nil];

除此之外,它似乎应该有效。如果影响框架,它可能会导致问题。在动画块之前计算帧可能是值得的。甲' LA:

CGRect newFrame = CGRectMake(menuView.frame.origin.x, -menuView.frame.size.height, menuView.frame.size.width, menuView.frame.size.height)

[UIView animateWithDuration...:^{ menuView.frame = newFrame; }...];

编辑哦,等等,看起来你在(void) item:(SDGroupCell *)item subItemDidChange:(SDSelectableCell *)subItem中重新分配/初始化对象,并在其上调用方法,但视图无处可见在视图层次结构中。您需要在屏幕上显示的实例上调用动画。希望有道理吗?

编辑2:要在已经显示的实例上调用它,通常需要将其存储在实例变量中。我不能确切地说出你的情况如何,但通常它的形式如下:

@interface OtherClass () {
    ViewController* m_viewController;
}
@end

....

- (void)viewDidLoad // Or where ever you first create your view controller
{
    ...
    // If you're adding a ViewController within another ViewController, you probably need View Controller Containment
    m_viewController = [[ViewController alloc] init];
    [self addChildViewController:m_viewController];
    [m_viewController didMoveToParentViewController:self];
    [self.view addSubview:m_viewController.view];
    ...
}

// If you're using ARC code, the dealloc wouldn't typically be necessary
- (void)dealloc
{
    [m_viewController release];
    [super dealloc];
}

//- (void) item:(SDGroupCell *)item subItemDidChange:(SDSelectableCell *)subItem
//{
    //SelectableCellState state = subItem.selectableCellState;
    //NSIndexPath *indexPath = [item.subTable indexPathForCell:subItem];
    //switch (state) {
        //case Checked:
            //NSLog(@"Changed Sub Item at indexPath:%@ to state \"Checked\"", indexPath);

            //close the menuView

            [m_viewController closeMenu];

            //break;
        //case Unchecked:
            //NSLog(@"Changed Sub Item at indexPath:%@ to state \"Unchecked\"", indexPath);
            //break;
        //default:
            //break;
    //}
    }

如果您需要从课外访问它,这不够,请使用属性。即。

标题文件

@property (nonatomic, strong) ViewController* myViewController

.m文件

// Use it as such
[self.myViewController closeMenu];

答案 1 :(得分:1)

那个动画代码真的很奇怪。你正在混合新的和旧的UIView动画代码,我认为你不能这样做(但我可能是错的)。

由于您已经开始使用基于块的API,我建议您使用该路由(Apple建议使用相同的方法)。

您使用的方法与animateWithDuration:delay:options:animations:completion:选项类似。您可以为延迟传递0,为完成传递一个BOOL的空块。

您要为选项传递的两个标记是UIViewAnimationOptionBeginFromCurrentStateUIViewAnimationOptionCurveEaseInOut

您的代码看起来像这样

[UIView animateWithDuration:0.6 
                      delay:0.0
                    options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut  
                 animations:^{
                    // set your frame here...
                    [menuView setFrame:CGRectMake(menuView.frame.origin.x,
                                                  -menuView.frame.size.height,
                                                  menuView.frame.size.width,
                                                  menuView.frame.size.height)];
               } completion:^(BOOL finished){}];