动画兄弟NSViews

时间:2011-08-04 16:52:34

标签: objective-c cocoa animation core-animation nsview

背景&目标

我在IB的nib文件中有一个窗口和三个单独的视图。这三个视图用于程序的三个“部分”:第一个是用户删除文件,第二个是选择某些选项,第三个是程序完成任务时用进度条显示的位置。 / p>

我希望在这些视图发生变化时对它们进行动画制作,并且我正在制作淡入/淡出动画。目标是让旧视图(即将消失的视图)在新视图淡入时淡出。视图具有不同的大小,因此我同时为窗口框架设置动画(这些视图填满了窗口)。所有三个视图都在IB中启用了Core Animation,但没有别的(例如窗口的内容视图)。

代码

在程序开始时,我会注册视图的大小,以便稍后使用它们,将视图添加到窗口并将第2和第3视图设置为隐藏。

- (void)awakeFromNib
{
    // Register native views' size (when they get displayed again the window can be set to their bounds)
    view1NativeSize = [firstView bounds].size;
    view2NativeSize = [secondView bounds].size;
    view3NativeSize = [thirdView bounds].size;

    // Add views to the main window's content view
    NSRect viewFrame = [[mainWindow contentView] bounds];
    [firstView setFrame: viewFrame];
    [secondView setFrame: viewFrame];
    [thirdView setFrame: viewFrame];

    [[mainWindow contentView] addSubview: firstView];
    [[mainWindow contentView] addSubview: secondView];
    [[mainWindow contentView] addSubview: thirdView];

    // Set their attributes
    [secondView setHidden: TRUE];
    [thirdView setHidden: TRUE];

    currView = 1;
}

然后我有三种方法在视图之间交换,我计算新窗口框架并调用动画方法。

- (IBAction)goToFirstView: (id)sender
{        
    NSRect newFrame = [mainWindow frame];
    newFrame.size = view1NativeSize;
    newFrame.size.height += [self titleBarHeight]; // Method that returns the title bar height

    if (currView == 1) {
        return;
    }
    else if (currView == 2) {
        [self animateFromView: secondView toView: firstView andWindowFrame: newFrame];
        currView--;
    }
    else if (currView == 3) {
        [self animateFromView: thirdView toView: firstView andWindowFrame: newFrame];
        currView -= 2;
    }
}
- (IBAction)goToSecondView: (id)sender
{
    NSRect newFrame = [mainWindow frame];
    newFrame.size = view2NativeSize;
    newFrame.size.height += [self titleBarHeight];

    if (currView == 2) {
        return;
    }
    else if (currView == 1) {
        [self animateFromView: firstView toView: secondView andWindowFrame: newFrame];
        currView++;
    }
    else if (currView == 3) {        
        [self animateFromView: thirdView toView: secondView andWindowFrame: newFrame];
        currView--;
    }
}
- (IBAction)goToThirdView: (id)sender
{
    NSRect newFrame = [mainWindow frame];
    newFrame.size = view3NativeSize;
    newFrame.size.height += [self titleBarHeight];

    if (currView == 3) {
        return;
    }
    else if (currView == 1) {
        [self animateFromView: firstView toView: thirdView andWindowFrame: newFrame];
        currView += 2;
    }
    else if (currView == 2) {
        [self animateFromView: secondView toView: thirdView andWindowFrame: newFrame];
        currView++;
    }
}

动画的方法非常简单。我为观点制作动画。

- (void)animateFromView: (NSView*)oldView
                 toView: (NSView*)newView
         andWindowFrame: (NSRect)newWindowFrame
{
    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setDuration: 0.5];

    [[newView animator] setHidden: FALSE];
    [[oldView animator] setHidden: TRUE];
    //[[mainWindow animator] setFrame: newWindowFrame]; --Doesn't work??

    [NSAnimationContext endGrouping];

    [mainWindow setFrame: newWindowFrame display: YES animate: YES];
}

问题

我有两个问题(最重要的是第一个):

  • 在第三个视图中有一个进度指示器,它永远不会正确显示。它没有更新!我叫-startAnimation:但它根本不动。如果我在第三层关闭CA,它将不会正确淡入/淡出,但进度条开始工作(动画)。不知道为什么......

  • 在我尝试解决第一个问题的众多实验中,我尝试为窗口的内容视图启用CA并关闭三个子视图的CA.第一个问题没有解决,但我注意到了一些事情:旧视图逐渐消失,因为新视图消失了,而在更改之前(使用CA的子视图)我只能注意到新视图渐渐消失。我记录了它并且在sloooowww-moootion中观看了它,发现我是对的:旧视图神奇地消失了,所有我看到的是新视图渐渐消失。有趣的是,我只是在观看动画后才真正想要的。我是应该仅为内容视图或所有三个子视图单独启用CA? (或者是其他问题?)

我尝试了许多内容,例如为进度条打开CA.我在这里发现了许多与此问题相近的问题,但没有具体解决进度条问题。

祝你找到解决方案:)

1 个答案:

答案 0 :(得分:0)

要处理您的交叉淡入淡出,您可以使用CAT变换,如this answer中所述,但对于交叉淡入淡出,您不需要设置过渡类型,因为它是默认值。

我担心我没有得到进度条问题的答案,但这可能与你正在进行交叉淡入淡出的非正统方式有关。