CoreAnimation:对检查是否已结束感到困惑

发布于 2024-12-19 15:05:46 字数 2404 浏览 1 评论 0原文

我有一堆 NSView 子视图,它们排列在网格中。用户可以在网格周围拖动子视图,在 mouseUp 上,我重新排列子视图,将拖动的视图插入到它被放置的网格上的关闭点。

执行此操作的代码如下:

for(int x=0; x<[pagesToMoveLeft count]; x++) { 

    //get a grid location
    NSRect thisSubviewFrame = NSRectFromString([subviewCoords objectAtIndex:x]);

    //get the view to move
    NSView* viewToMove = [pagesToMoveLeft objectAtIndex:x];
    [[viewToMove animator] setFrame: thisSubviewFrame];

}

我在最后运行检查以确保一切都良好且干净(即 - 每个网格坐标都有一个视图)。为此,我在 mouseDown 上抓取所有子视图帧并将它们存储在一个数组中。在 mouseUp 上,动画结束后我调用 cleanUp 方法。在这里,我再次抓取所有子视图帧并存储它们。数组 1 和数组 2 应该匹配,如果不是有些东西没有到位,我可以使用数组 1 修复它。

我没有得到我预期的结果。当我在屏幕上移动项目时,它们都卡入正确的位置,这意味着数组 1 和数组 2 应该相等,但事实并非如此。这是我的日志:

"{{25, 25}, {170, 220}}",
"{{29, 25}, {170, 220}}",
"{{390, 25}, {170, 220}}",
"{{585, 25}, {170, 220}}",
"{{755, 25}, {170, 220}}",
"{{950, 25}, {170, 220}}",
"{{25, 270}, {170, 220}}",
"{{220, 270}, {170, 220}}",
"{{390, 270}, {170, 220}}",
"{{585, 270}, {170, 220}}",
"{{755, 270}, {170, 220}}",
"{{950, 270}, {170, 220}}"
)
(
"{{25, 25}, {170, 220}}",
"{{220, 25}, {170, 220}}",
"{{390, 25}, {170, 220}}",
"{{585, 25}, {170, 220}}",
"{{755, 25}, {170, 220}}",
"{{950, 25}, {170, 220}}",
"{{25, 270}, {170, 220}}",
"{{220, 270}, {170, 220}}",
"{{390, 270}, {170, 220}}",
"{{585, 270}, {170, 220}}",
"{{755, 270}, {170, 220}}",
"{{950, 270}, {170, 220}}"
)

第一个是移动后的帧(当前位置),第二个是它们的初始位置。查看每个数组中的第 2 项,它们都应为 (220, 25)。相反,当前的内容为 (29, 25)。这是我拖动的视图,我将其从第二个位置移动到第一个位置附近 (25, 25)。 29 是我鼠标向上移动的位置...动画起作用了,视图 2 捕捉到 25,25 位置,视图 1 移动到视图 2 位置。

我认为动画比代码慢,这就是为什么我在 mouseUp 处获取位置而不是动画结束处的位置。我查看了 CoreAnimation 文档,认为我需要使用类似 AnimationDidStop 的东西,但不确定如何实现它。

任何帮助将不胜感激。

编辑:

我想通了 -

...
for(int x=0; x<[pagesToMoveLeft count]; x++) { 

        //get a grid location
        NSRect thisSubviewFrame = NSRectFromString([subviewCoords objectAtIndex:x]);

        //get the view to move
        viewToMove = [pagesToMoveLeft objectAtIndex:x];

        CAAnimation *animation = [[viewToMove animationForKey:@"frameOrigin"] copy];
        [viewToMove setAnimations:[NSDictionary dictionaryWithObject:animation forKey:@"frameOrigin"]];
        animation.delegate = self;
        [[viewToMove animator] setFrame: thisSubviewFrame];
}

...

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag  {

    NSLog(@"ok");
}

I have a bunch of NSView subviews which are laid out in a grid. The user can drag the subviews around the grid and on mouseUp I rearrange the subviews inserting the dragged view into the closes spot on the grid it was dropped.

The code to do that is like this:

for(int x=0; x<[pagesToMoveLeft count]; x++) { 

    //get a grid location
    NSRect thisSubviewFrame = NSRectFromString([subviewCoords objectAtIndex:x]);

    //get the view to move
    NSView* viewToMove = [pagesToMoveLeft objectAtIndex:x];
    [[viewToMove animator] setFrame: thisSubviewFrame];

}

I run a check at the end to make sure everything is nice and clean (i.e. - each grid coordinate has a view). To do this, on mouseDown I grab all the subviews frames and store them in an array. On mouseUp, after the animation I call a cleanUp method. In here I grab all the subview frames again and store them. Array 1 and Array 2 should match up, if not something didn't fall into place and I can fix it using Array 1.

I'm not getting the results I expected. When I move items on the screen and they all snap into the correct place, meaning Array 1 and 2 should be equal, they are not. Here's my log:

"{{25, 25}, {170, 220}}",
"{{29, 25}, {170, 220}}",
"{{390, 25}, {170, 220}}",
"{{585, 25}, {170, 220}}",
"{{755, 25}, {170, 220}}",
"{{950, 25}, {170, 220}}",
"{{25, 270}, {170, 220}}",
"{{220, 270}, {170, 220}}",
"{{390, 270}, {170, 220}}",
"{{585, 270}, {170, 220}}",
"{{755, 270}, {170, 220}}",
"{{950, 270}, {170, 220}}"
)
(
"{{25, 25}, {170, 220}}",
"{{220, 25}, {170, 220}}",
"{{390, 25}, {170, 220}}",
"{{585, 25}, {170, 220}}",
"{{755, 25}, {170, 220}}",
"{{950, 25}, {170, 220}}",
"{{25, 270}, {170, 220}}",
"{{220, 270}, {170, 220}}",
"{{390, 270}, {170, 220}}",
"{{585, 270}, {170, 220}}",
"{{755, 270}, {170, 220}}",
"{{950, 270}, {170, 220}}"
)

The first one are the frames after the move (the current locations), the second is their initial locations. Look at item 2 in each array, they should both read (220, 25). Instead the current one reads (29, 25). That's the view I dragged, I moved it from the second location to near the first one (25, 25). The 29 is where I mousedUp...the animation worked, view 2 snapped to the 25,25 location and view 1 moved to the view 2 location.

I think the animation is slower than the code and that's why I am getting the location at mouseUp and not animation end. I looked at the CoreAnimation docs and think I need to use something like animationDidStop but am not sure how to implement it.

Any help would be appreciated.

Edit:

I figured it out -

...
for(int x=0; x<[pagesToMoveLeft count]; x++) { 

        //get a grid location
        NSRect thisSubviewFrame = NSRectFromString([subviewCoords objectAtIndex:x]);

        //get the view to move
        viewToMove = [pagesToMoveLeft objectAtIndex:x];

        CAAnimation *animation = [[viewToMove animationForKey:@"frameOrigin"] copy];
        [viewToMove setAnimations:[NSDictionary dictionaryWithObject:animation forKey:@"frameOrigin"]];
        animation.delegate = self;
        [[viewToMove animator] setFrame: thisSubviewFrame];
}

...

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)flag  {

    NSLog(@"ok");
}

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文