2012-04-10 19 views
11

Đối với mục đích học tập tôi muốn chuyển đổi một NSOutlineView di động dựa trên một cái nhìn dựa trên một,Làm cách nào để tạo một NSOutlineView dựa trên chế độ xem đơn giản?

về cơ bản tôi muốn như sau:

  • thay vì của một tế bào bình thường, tôi muốn một 'hình ảnh và ô trong bảng chữ cái nhìn'
  • hình ảnh có thể là cổ phiếu NSApplicationIcon và các văn bản chỉ có thể là 'hello world' :)
  • tôi muốn làm điều này mà không sử dụng các ràng buộc và NSTreeController

Đây là 'thế giới đơn giản nhất NSOutlineView' dụ http://www.cocoasteam.com/Cocoa_Steam/Worlds_Simplest_Demo.html

Tôi tự hỏi nếu ai đó có thể sửa đổi nó để làm cho nó xem dựa trên và làm việc như tôi đã nói ở trên :) :)

tôi đã cố gắng nhìn vào ví dụ táo, và tìm kiếm những nơi khác trên internet, nhưng tôi vẫn không thể làm cho nó để làm việc - vì vậy cảm ơn rất nhiều trước :)

Trả lời

11

OK, vì vậy bạn muốn có một NSOutlineView với các ô ImageAndTextCell, phải không?

Hãy làm một trong những ví dụ điển hình nhất của loại này: một trình khám phá tệp đơn giản.

Những gì chúng ta sẽ cần:

  • một NSOutlineView (đặt một phác thảo để appdelegate của bạn, như fileOutlineView)
  • tạo ra 3 cột trong Outline với các số phân định sau (thiết lập chúng trong giao diện Builder): NameColumn, SizeColumn, ModifiedColumn

Bây giờ, đối với phần còn lại, tôi sẽ làm tất cả lập trình, vì vậy mà bạn có ý tưởng hay về những gì đang diễn ra ...

Cách thiết lập (ví dụ: trong - (void)awakeFromNib):

// set the Data Source and Delegate 
[fileOutlineView setDataSource:(id<NSOutlineViewDataSource>)self]; 
[fileOutlineView setDelegate:(id<NSOutlineViewDelegate>)self]; 

// set the first column's cells as `ImageAndTextCell`s 
ImageAndTextCell* iatc = [[ImageAndTextCell alloc] init]; 
[iatc setEditable:NO]; 
[[[fileOutlineView tableColumns] objectAtIndex:0] setDataCell:iatc]; 

Kết nối các dấu chấm:

/******************************************************* 
* 
* OUTLINE-VIEW DATASOURCE 
* 
*******************************************************/ 

- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item 
{   
    if ([item isFolder]) 
     return YES; 
    else 
     return NO; 
} 

- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item 
{  
    if (item==nil) 
    { 
     // Root 
     return [[filePath folderContentsWithPathAndBackIgnoringHidden] count]; 
    } 
    else 
    {   
     if ([item isFolder]) 
     { 
      return [[item folderContentsWithPathAndBackIgnoringHidden] count]; 
     } 
     else 
     { 
      return 0; 
     } 
    } 
} 

- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item 
{ 
    if (item == nil) 
    { 
     // Root 
     return [[filePath folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index]; 
    } 

    if ([item isFolder]) 
    { 
     return [[item folderContentsWithPathAndBackIgnoringHidden] objectAtIndex:index]; 
    } 

    // File 
    return nil; 
} 

- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)theColumn byItem:(id)item 
{   
    if ([[theColumn identifier] isEqualToString:@"NameColumn"]) 
    { 
     return [item lastPathComponent]; 
    } 
    else if ([[theColumn identifier] isEqualToString:@"SizeColumn"]) 
    { 
     if ([item isFolder]) return @"--"; 
     else return [NSString stringWithFormat:@"%d",[item getFileSize]]; 
    } 
    else if ([[theColumn identifier] isEqualToString:@"ModifiedColumn"]) 
    { 
     if ([item isFolder]) return @""; 
     else return [NSString stringWithFormat:@"%@",[item getDateModified]]; 
    } 

    // Never reaches here 
    return nil; 
} 

/******************************************************* 
* 
* OUTLINE-VIEW DELEGATE 
* 
*******************************************************/ 

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item 
{ 
    return YES; 
} 

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item 
{ 
    return NO; 
} 

- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { 
    [cell setDrawsBackground:NO]; 

    if ([item isFileHidden]) [cell setTextColor:[NSColor grayColor]]; 
    else [cell setTextColor:[NSColor whiteColor]]; 

    if ([[tableColumn identifier] isEqualToString:@"NameColumn"]) 
    { 
     if ([item isFolder]) 
      [cell setImage:[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] size:15.0]; 
     else 
      [cell setImage:[[NSWorkspace sharedWorkspace] iconForFile:item] size:15.0]; 

     if ([item isFileHidden]) 
     { 
      [cell setFileHidden:YES]; 
     } 
     else 
     { 
      [cell setFileHidden:NO]; 
     } 

    } 

} 

Gợi ý:ImageAndTextCell lớp có thể được tìm thấy here. Bạn cũng sẽ nhận thấy một vài phương pháp khác mà tôi đang sử dụng, mà rõ ràng là không được hỗ trợ bởi Cocoa (ví dụ isFileHidden, isFolder hoặc folderContentsWithPathAndBackIgnoringHidden) nhưng nó không phải là khó khăn để thực hiện chúng mình ...)

+18

Tôi không thấy làm thế nào điều này là chính xác. ImageAndTextCell thuộc loại NSCell, KHÔNG phải NSView. Câu hỏi đặt ra là về NSOutlineView dựa trên chế độ xem. Ví dụ của bạn chỉ là về việc tạo một lớp con NSCell tùy chỉnh mà chúng tôi đã có thể làm trong nhiều năm. Đối với NSTableView, có rất nhiều ví dụ về cách sử dụng NSView thay vì NSCell. Trông rất giống iOS. Tôi đã không tìm thấy bất kỳ ví dụ NSOutlineView đáng buồn. –

+1

@ Các bảng dựa trên Adam-view sử dụng NSTableCellViews làm chế độ xem của chúng. Từ đó bạn có thể thêm bất kỳ nội dung nào cho họ. Điều mà Dr.Kameleon đã nói là chính xác. Toàn bộ các điểm dựa trên bảng là bạn có thể thêm bất kỳ đối tượng xem nào bạn muốn (Có thể là ô, nút, hình ảnh hay ... bất kỳ điều gì) – Patrick

+1

Đây không phải là tạo chế độ xem phác thảo dựa trên chế độ xem. – JeremyP

0

Kiểm tra TableViewPlayground, cũng Xem Dựa NSTableView cơ bản đến nâng cao từ WWDC 2011.

+2

Cảm ơn, tôi đã kiểm tra ví dụ đó và tôi thấy nó quá cồng kềnh và khó hiểu. Tôi cần một ví dụ rất đơn giản để grok nó tôi nghĩ (im cũng kinda mới để ca cao: P) – horseyguy

8

Tôi đã tạo một dự án mẫu nhỏ chỉ thực hiện điều đó.

  • hiển thị một danh sách các mục
  • Chỉnh sửa các mục trong một thời trang master-chi tiết
  • Remove và thêm các mục
  • Sử dụng bindings

Check-out besi/mac-quickies trên github. Hầu hết những thứ được hoặc thực hiện trong IB hoặc có thể được tìm thấy trong các AppDelegate

screenshot

+2

Đó là một ví dụ dễ làm theo. Cảm ơn. – JeremyP

2

Để trở về nhằm cột OutlineView Thay vì sử dụng phương pháp nguồn dữ liệu đó trở objectValue:

  • (id) outlineView: (NSOutlineView *) outlineXem đối tượngValueForTableColumn: (NSTableColumn *) theColumn byItem: (id) mục

SỬ DỤNG PHƯƠNG PHÁP ĐẠT ĐƯỢC ĐẶT TRỞ LẠI TỔNG QUAN VỀ !!!!!!!!:

  • (NSView *) outlineView: (NSOutlineView *) outlineView viewForTableColumn: (NSTableColumn *) tableColumn mục: (id) mục

mọi thứ khác là tương tự (req tối thiểu là ba phương thức nguồn dữ liệu đầu tiên, bạn không cần phương thức đại biểu) nhưng, bạn không thể sử dụng willdisplaycell được gọi là chỉ dựa trên ô, làm mọi thứ cho chế độ xem trong phương thức viefortablecolumn như sau:

if ([[tableColumn identifier] isEqualToString:@"YourColumnIdentifier"]){ 
    NSTableCellView *cell = [outlineView makeViewWithIdentifier:@"YourViewsIdentifier" owner:self]; 
    [cell.textField setStringValue:[(YourItem *)item name]]; 
    [cell.imageView setImage:[(YourItem *)item image]]; 
    return cell; 
} 

return nil; 

và không cho có thể đặt số nhận dạng và đặt OutlineView thành Chế độ xem dựa trên (trong IB ...).

+0

OK, hoạt động nhưng kết quả là rất xấu. OutlineView xuất hiện phía sau khung nhìn: Vì vậy, điều này không hoàn toàn giống với NSTableView dựa trên khung nhìn. – Christophe