如何使用 Cocoa 中的 Bindings+CoreData 实现 iTunes 风格的源列表?

发布于 2024-08-10 06:03:58 字数 422 浏览 1 评论 0原文

举例来说,我正在 Cocoa 中编写一个 iTunes 克隆应用程序,该应用程序由 CoreData 支持。为了简单起见,假设有两个“部分”,“库”,其中包含音乐、电影、广播等内容。第二个部分称为“播放列表”,其中保存用户生成的播放列表(只是哑列表,不是智能播放列表) 。

因此,SourceList 本身通常会使用 NSOutlineView 来实现,这通常很简单。

源列表的“库”部分并不真正包含用户生成的任何内容,仅包含应用程序的“功能”(实质上),其中“播放列表”部分仅包含用户创建的自定义列表。如何使用 Bindings 和 CoreData 来做到这一点?是否可以仅将播放列表部分绑定到用户的数据并以自定义方式显示库功能?

总的来说,我仍然对 Bindings 和 AppKit 不太熟悉,所以请耐心等待。我很感激你的帮助。我应该补充一点,我的目标是 10.6 及以上。

Let's say, for illustration, I was writing an iTunes clone app in Cocoa, that was backed by CoreData. For simplification's sake, let's say there are two "sections", "Library" with things like Music, Movies, Radio, etc. And a second section called "Playlists" which holds user-generated playlists (just dumb lists, not smart playlists).

So the SourceList itself would typically be implemented with NSOutlineView, that's generally straightforward.

The Library section of the source list doesn't really house anything generated by the user, only "features" of the app (in essence) where the Playlists section only holds custom lists as created by the user. How would one do this with Bindings and CoreData? Is it possible just to bind the Playlists section to the user's data and have a custom way of displaying the Library features?

I'm still getting my feet wet with Bindings and AppKit in general, so please bear with me. I appreciate the help. I should add, I'm targeting 10.6 and above.

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

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

发布评论

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

评论(2

陈独秀 2024-08-17 06:03:58

我对核心数据没有太多经验,但我广泛使用了 Cocoa 的绑定。根据我的经验,这样的方法最适合“手动”调整的对象的中间 NSArray

举个例子,我想您将有一个由用户生成的自定义播放列表 NSArray,并且您还将有一个单独的 NSArray 包含您的标准库项目。通过此设置,我将在一个名为 combinedArray 的控制器中创建一个属性,该属性将绑定到您的 NSOutlineView。然后,我会将用户生成的播放列表数组绑定到控制器,并让控制器中的一些代码在播放列表数组被修改时自动更新组合数组。

这是一个快速模型:

TheController.h

@interface TheController : NSObject
{
    NSArray * combinedArray;
    NSArray * userPlaylists;
}
@property (retain) NSArray * combinedArray;
@property (copy) NSArray * userPlaylists;
@end

TheController.m

@implementation TheController

@synthesize combinedArray;
@synthesize userPlaylists;
- (void)setUserPlaylists:(NSArray *)newLists
{
    // standard property setting code:
    if (newLists != userPlaylists)
    {
        [userPlaylists release];
        userPlaylists = [newLists copy];
    }

    // modify the combined array:
    NSMutableArray * allItems = [NSMutableArray arrayWithCapacity:0];
    [allItems addObjectsFromArray:standardLibrary];
    [allItems addObjectsFromArray:userPlaylists];
    [self setCombinedArray:allItems];
}

@end

I haven't had a lot of experience with core data, but I have made extensive use of Cocoa's bindings. In my experience, something like this works best with an intermediate NSArray of objects which is "manually" adjusted.

As an example, I imagine you would have a custom NSArray of playlists that are user-generated, and you would also have a separate NSArray containing your standard Library items. With this setup, I would create a property in one of your controllers called combinedArray, which would be the property that gets bound to your NSOutlineView. I would then bind your user-generated playlist array to the controller, and have some code in the controller automatically update the combined array whenever the playlist array is modified.

Here is a quick mock-up:

TheController.h

@interface TheController : NSObject
{
    NSArray * combinedArray;
    NSArray * userPlaylists;
}
@property (retain) NSArray * combinedArray;
@property (copy) NSArray * userPlaylists;
@end

TheController.m

@implementation TheController

@synthesize combinedArray;
@synthesize userPlaylists;
- (void)setUserPlaylists:(NSArray *)newLists
{
    // standard property setting code:
    if (newLists != userPlaylists)
    {
        [userPlaylists release];
        userPlaylists = [newLists copy];
    }

    // modify the combined array:
    NSMutableArray * allItems = [NSMutableArray arrayWithCapacity:0];
    [allItems addObjectsFromArray:standardLibrary];
    [allItems addObjectsFromArray:userPlaylists];
    [self setCombinedArray:allItems];
}

@end
萌︼了一个春 2024-08-17 06:03:58

由于本例中的源列表实际上是一个“范围”,而不是一个除了某些“LibraryItem”实体的实例之外什么都没有的平面列表,我认为以“老式”方式实现它更容易(即表数据源协议) 。

这使您可以精确控制分组、如何/何时将“静态”项目(例如“库”和“音乐”以及“电影”、“播放列表”)与商店中的项目(例如“播放列表”部分)。

在我看来,处理拖放也更容易一些,这对于防止播放列表项目被拖放到“电影”组中是关键。

Since the source list in this case is really a "scope" and not a flat list of nothing but instances of some "LibraryItem" entity, I think it's easier to implement this the "old fashioned" way (ie, table data source protocol).

This gives you precise control over grouping, how/when to mix "static" items (like "Library" and "Music", and "Movies", "Playlists") with items from your store (like the individual Playlist items under the "Playlists" section).

It's also a little easier to deal with drag and drop, in my opinion, which is key when preventing a Playlist item from being dropped upon your "Movies" group.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文