点击更改自定义视图单元格 [英] change custom view cell on click

查看:121
本文介绍了点击更改自定义视图单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在osx上使用swift。
我有一个带有自定义单元格视图的nstableview(一行,一列)。我在情节提要中的
设计了两个不同的行布局,标识符为CellLayout1和CellLayout2

i work with swift for osx. I have a nstableview (one row, one column) with a custom cell view. in the storyboard i have "designed" two different row layouts with identifiers CellLayout1 and 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,如果我单击
i行,请使用此功能检查选择是否正在更改:

now i would like to show the CellLayout2, if i click on a row i use this function to check if the selection is changing:

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

但现在我不知道如何显示CellLayout2选定的行。
有人可以帮助我吗? :)

but now i don't know, how can i show the CellLayout2 for the selected row. can anybody help me? :)

更新

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)
}

这种方法几乎完美-但是:

this way works nearly perfect - but:


  • 仅当我重新加载整个表时,布局才会更改。该代码无效: // tblPositions.reloadData(forRowIndexes:tblPositions.selectedRowIndexes,columnIndexes:tblPositions.selectedColumnIndexes)

如果我选择一行,则tableview将重新加载数据,布局将更改,但是所选行将被取消选择。

if i select a row, the tableview reload the data, the layout will change, but the selected row will deselected. this should not happen.

推荐答案

要做一个好的MVC应该去像这样。

To do a good MVC it should go like this.


  1. 在单元格单击上,您正在更新数据模型。例如更改标志。

  2. 模型应触发该更改的通知

  3. 您的控制器应观察模型,并在收到通知时通知该项目已更改,则应将此通知传递给表视图:

  1. on cell click you are updating data model. For example change flag.
  2. model should trigger notification for that change
  3. your controller should observe model, and when notification was received that item was changed, you should pass this notification to a table view:

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

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

table view will reload cell for given index

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

When using Array as a data model than KVO can be used.



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


From some of my projects I have a good example how controller can look like. It is in Objective C, but should be helpful:

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完全实现支持的数组。

Where self.imageHandler points to my data model, which contains array with full implemented support for KVO.

这篇关于点击更改自定义视图单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆