点击更改自定义视图单元格 [英] change custom view cell on click
问题描述
我在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.
- 在单元格单击上,您正在更新数据模型。例如更改标志。
- 模型应触发该更改的通知
-
您的控制器应观察模型,并在收到通知时通知该项目已更改,则应将此通知传递给表视图:
- on cell click you are updating data model. For example change flag.
- model should trigger notification for that change
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屋!