单击更改自定义视图单元格

change custom view cell on click

我和 swift 一起工作 osx。 我有一个带有自定义单元格视图的 nstableview(一行,一列)。 在情节提要中,我有 "designed" 两个不同的行布局,带有标识符 CellLayout1 和 CellLayout2

func numberOfRows(in tableView: NSTableView) -> Int {
   return dataArray.count
}


func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
   let view = tblPositions.make(withIdentifier: "CellLayout1", owner: nil) as! CustomCell
   view.txtName.stringValue = dataArray[row]
   return view
}

现在我想显示 CellLayout2,如果我点击一行 我使用这个函数来检查 selection 是否在变化:

func tableViewSelectionDidChange(_ notification: Notification) {
  // ?        
}

但现在我不知道如何显示 selected 行的 CellLayout2。 有谁能够帮助我? :)

更新

var selectedRow = Int()

func numberOfRows(in tableView: NSTableView) -> Int {
   return dataArray.count
}

func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {
    if selectedRow == row {
        return 200
    } else {
        return 60
    }
}


func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
   if selectedRow == row {
      let view = tableView.make(withIdentifier: "CellLayout1", owner: nil) as! CustomCell
            return view
        }
       let view = tableView.make(withIdentifier: "CellLayout2", owner: nil) as! CustomCell
        return view
}


func tableViewSelectionDidChange(_ notification: Notification) {
   selectedRow = tblPositions.selectedRow
   tblPositions.reloadData()
   //tblPositions.reloadData(forRowIndexes: tblPositions.selectedRowIndexes, columnIndexes: tblPositions.selectedColumnIndexes)
}

这种方式近乎完美 - 但是:

做一个好的 MVC 应该是这样的。

  1. 在单元格上单击您正在更新数据模型。例如更改标志。
  2. 模型应该触发该更改的通知
  3. 您的控制器应该观察模型,并且当收到该项目已更改的通知时,您应该将此通知传递给 table 视图:

    tableView.func reloadData(forRowIndexes: rowsToUpdate columnIndexes: colmnToUpdate)

  4. table 视图将重新加载给定索引的单元格

  5. 它将再次调用 func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) 您提供与项目标志匹配的单元格。

当使用 Array 作为数据模型时,可以使用 KVO


从我的一些项目中,我有一个很好的例子,说明控制器的外观。它在 Objective C 中,但应该会有帮助:

static char dummy = 0;
static NSString * const kImageCellsId = @"ImageCellView";
static NSString * const kDescriptionCellId = @"DescriptionCellView";

@interface CommonImagesViewController () <NSTableViewDataSource, NSTabViewDelegate>

@property (nonatomic, strong) IBOutlet NSTableView *tableView;
@property (nonatomic, strong) CommonImagesHandler *imageHandler;

@end

@implementation CommonImagesViewController

- (void)dealloc {
    [self.imageHandler removeObserver: self
                           forKeyPath: kCommonImagesHandlerImageCollectionKey
                              context: &dummy];
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.imageHandler = ClientManager.getInstance.imageHandler;
    [self.imageHandler addObserver: self
                        forKeyPath: kCommonImagesHandlerImageCollectionKey
                           options: (NSKeyValueObservingOptions)0
                           context: &dummy];

    [self.tableView reloadData];
}

#pragma mark - NSTableViewDataSource
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView
{
    return (NSInteger)self.imageHandler.imageCollection.count;
}

#pragma mark - NSTabViewDelegate
- (nullable NSView *)tableView: (NSTableView *)tableView
            viewForTableColumn: (nullable NSTableColumn *)tableColumn
                           row: (NSInteger)row
{
    ImageData *item = self.imageHandler.imageCollection[(NSUInteger)row];
    if (tableColumn == tableView.tableColumns[0]) {
        NSTableCellView *cell = (NSTableCellView *)[self.tableView makeViewWithIdentifier: kImageCellsId owner: nil];
        cell.imageView.image = item.image;
        cell.textField.stringValue = item.userDesc;
        return cell;
    }
    return nil;
}

#pragma mark - actions
- (IBAction)deleteAllEntries:(id)sender
{
    [self.imageHandler clearImageCollection];
}

- (IBAction)deleteSelected:(id)sender
{
    NSIndexSet *indexes = self.tableView.selectedRowIndexes;
    [self.imageHandler removeImageCollectionAtIndexes: indexes];
}

- (IBAction)viewImage:(id)sender
{
    // TODO:
}

#pragma mark - KVO
- (void)observeValueForKeyPath: (NSString *)keyPath
                      ofObject: (id)object
                        change: (NSDictionary *)change
                       context: (void *)context
{
    if (context == &dummy) {
        if (self.imageHandler == object && [keyPath isEqualToString: kCommonImagesHandlerImageCollectionKey]) {
            NSIndexSet *indexSet = change[NSKeyValueChangeIndexesKey];
            if (indexSet.count == 0) {
                return;
            }

            NSKeyValueChange changeType = (NSKeyValueChange)[change[NSKeyValueChangeKindKey] integerValue];
            switch (changeType) {
                case NSKeyValueChangeSetting:
                    [self.tableView reloadDataForRowIndexes: indexSet
                                              columnIndexes: [NSIndexSet indexSetWithIndex: 0]];
                    break;

                case NSKeyValueChangeInsertion:
                    [self.tableView insertRowsAtIndexes: indexSet withAnimation: NSTableViewAnimationSlideLeft];
                    break;

                case NSKeyValueChangeRemoval:
                    [self.tableView removeRowsAtIndexes: indexSet withAnimation: NSTableViewAnimationSlideRight];
                    break;

                case NSKeyValueChangeReplacement:
                    [self.tableView reloadData];
                    break;
            }
        }
    } else {
        [super observeValueForKeyPath: keyPath
                             ofObject: object
                               change: change
                              context: context];
    }
}

@end

其中 self.imageHandler 指向我的数据模型,其中包含完全支持 KVO 的数组。