使用开始和结束数组状态对 NSTableView 进行动画处理

发布于 2024-12-19 02:30:32 字数 744 浏览 2 评论 0原文

我一直在研究 NSTableViewmoveRowAtIndex:toIndex 方法来对表中的行进行动画处理。据我所知,这对于排序并没有多大帮助。我对其工作原理的解释是,如果我想将第 0 行移动到第 4 行,那么它们之间的行就会得到适当的处理。但是,如果我有一个带有数组支持的表视图,然后对数组进行排序,我希望表视图从旧状态动画到新状态。我不知道哪些项目是移动的,哪些是为了容纳移动的项目而移动的。

示例:

[A,B,C,D] --> [B,C,D,A]

我知道第 0 行移至第 3 行,因此我会说 [tableView moveRowAtIndex:0 toIndex:3]。但是如果我对 [A,B,C,D] 应用一些自定义排序操作​​以使其看起来像 [B,C,D,A],我实际上不知道第 0 行移动到第 3 行而不是第 1 行、2 和 3 移动到第 0,1 和 2 行。我认为我应该能够指定所有移动(第 0 行移动到第 4 行,第 1 行移动到第 0 行等),但是动画看起来不正确我尝试一下。

有更好的方法吗?

编辑:我发现这个网站,似乎做我想做的事,但对于应该简单的事情来说似乎有点太多(至少我认为它应该很简单)

I've been looking over NSTableView's moveRowAtIndex:toIndex method for animating rows in a table. It's not really helpful for sorting though from what I can tell. My interpretation of how it works is, if I want to move row 0 to row 4, then the rows in between are handled appropriately. However, if I have a table view with an array backing it, and then I sort the array, I want the table view to animate from the old state to the new state. I don't know which items were the ones that moved vs the ones that shift to accommodate the moved ones.

Example:

[A,B,C,D] --> [B,C,D,A]

I know that row 0 moved to row 3 so I would say [tableView moveRowAtIndex:0 toIndex:3]. But if I apply some custom sort operation to [A,B,C,D] to make it look like [B,C,D,A], I don't actually know that row 0 moved to row 3 rather than rows 1,2, and 3 moving to rows 0,1, and 2. I would think that I should just be able to specify all of the movements (row 0 moved to row 4, row 1 moved to row 0, etc.) but the animation doesn't look correct when I try that.

Is there a better way to do this?

Edit: I found this site, which seems to do what I want but seems like a bit much for something that should be simple (at least I think it should be simple)

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

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

发布评论

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

评论(1

淡淡の花香 2024-12-26 02:30:32

moveRowAtIndex:toIndex: 的文档说,“更改在发送到表时逐渐发生”。

从 ABCDE 到 ECDAB 的转变可以最好地说明“增量”的重要性。

如果您只考虑初始和最终索引,它看起来像:

E: 4->0
C: 2->1
D: 3->2
A: 0->3
B: 1->4

但是,当增量执行更改时,“初始”索引可能会在您转换数组时跳转:

E: 4->0 (array is now EABCD)
C: 3->1 (array is now ECABD)
D: 4->2 (array is now ECDAB)
A: 3->3 (array unchanged)
B: 4->4 (array unchanged)

基本上,您需要逐步告诉 NSTableView,需要移动哪些行才能得到与排序数组相同的数组。

这是一个非常简单的实现,它采用任意排序的数组并“重放”将原始数组转换为排序数组所需的移动:

// 'backing' is an NSMutableArray used by your data-source
NSArray* sorted = [backing sortedHowYouIntend];

[sorted enumerateObjectsUsingBlock:^(id obj, NSUInteger insertionPoint, BOOL *stop) {

  NSUInteger deletionPoint = [backing indexOfObject:obj];

  // Don't bother if there's no actual move taking place
  if (insertionPoint == deletionPoint) return;

  // 'replay' this particular move on our backing array
  [backing removeObjectAtIndex:deletionPoint];
  [backing insertObject:obj atIndex:insertionPoint];

  // Now we tell the tableview to move the row
  [tableView moveRowAtIndex:deletionPoint toIndex:insertionPoint];
}];

The documentation for moveRowAtIndex:toIndex: says, "Changes happen incrementally as they are sent to the table".

The significance of 'incrementally' can be best illustrated with the transformation from ABCDE to ECDAB.

If you just consider the initial and final indexes, it looks like:

E: 4->0
C: 2->1
D: 3->2
A: 0->3
B: 1->4

However, when performing the changes incrementally the 'initial' indexes can jump around as you transform your array:

E: 4->0 (array is now EABCD)
C: 3->1 (array is now ECABD)
D: 4->2 (array is now ECDAB)
A: 3->3 (array unchanged)
B: 4->4 (array unchanged)

Basically, you need to tell the NSTableView, step-by-step, which rows need to be moved in order to arrive at an array identical to your sorted array.

Here's a very simple implementation that takes an arbitrarily sorted array and 'replays' the moves required to transform the original array into the sorted array:

// 'backing' is an NSMutableArray used by your data-source
NSArray* sorted = [backing sortedHowYouIntend];

[sorted enumerateObjectsUsingBlock:^(id obj, NSUInteger insertionPoint, BOOL *stop) {

  NSUInteger deletionPoint = [backing indexOfObject:obj];

  // Don't bother if there's no actual move taking place
  if (insertionPoint == deletionPoint) return;

  // 'replay' this particular move on our backing array
  [backing removeObjectAtIndex:deletionPoint];
  [backing insertObject:obj atIndex:insertionPoint];

  // Now we tell the tableview to move the row
  [tableView moveRowAtIndex:deletionPoint toIndex:insertionPoint];
}];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文