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

时间:2017-07-27 17:43:41

标签: swift macos cocoa tableview custom-cell

我使用swift for osx。 我有一个带有自定义单元格视图的nstableview(一行,一列)。 在故事板中我有"设计"两个不同的行布局,标识符为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,如果我点击一行 我使用此功能检查选择是否正在改变:

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

但现在我不知道,如何显示所选行的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)
}

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

  • 如果我重新加载整个表格,布局只会更改。此代码不会产生任何影响://tblPositions.reloadData(forRowIndexes: tblPositions.selectedRowIndexes, columnIndexes: tblPositions.selectedColumnIndexes)

  • 如果我选择一行,tableview重新加载数据,布局将会改变,但所选行将被取消选择。这不应该发生。

1 个答案:

答案 0 :(得分:0)

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

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

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

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

  5. 它将再次调用func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int),您将提供与项目标志匹配的单元格。
  6. 使用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的数组。