获取复选框以在 NSTableColumn 中反映其状态
我正在制作一个具有四列的 NSTableView 的程序,其中两列由复选框组成。我现在只想让其中一个工作起来,但我陷入了困境。
首先,这是我的相关代码:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
NSString *filePathThree = [[NSBundle mainBundle] pathForResource:@"mydictionary" ofType:@"plist"];
NSData *myDataThree = [[NSData alloc]initWithContentsOfFile:filePathThree];
self.flozzCodeAndName = (NSMutableDictionary *)[NSPropertyListSerialization
propertyListFromData:myDataThree
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:NULL
errorDescription:NULL];
return [[flozzCodeAndName objectForKey:@"name"] count];
}
- (void)tableView:(NSTableView *)tableView
setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
NSButtonCell *cell;
cell = [[NSButtonCell alloc] init];
[cell setButtonType:NSSwitchButton];
[cell setTitle:@""];
[cell setTag:rowIndex];
NSLog(@"%d", [cell tag]);
[cell setCellAttribute:NSCellEditable to:3];
[cell setImagePosition:NSImageOnly];
[cell setState:NSOnState];
NSLog(@"%d", [cell state]);
[havzColumn setDataCell:cell];
[myTableVeew reloadData];
[cell release];
}
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
NSString *filePathThree = [[NSBundle mainBundle] pathForResource:@"mydictionary" ofType:@"plist"];
NSData *myDataThree = [[NSData alloc]initWithContentsOfFile:filePathThree];
self.flozzCodeAndName = (NSMutableDictionary *)[NSPropertyListSerialization
propertyListFromData:myDataThree
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:NULL
errorDescription:NULL];
NSArray *myArray = [flozzCodeAndName objectForKey:[aTableColumn identifier]];
NSString *myStringValue = [myArray objectAtIndex:rowIndex];
return myStringValue;
}
如您所见,我对此表使用数据源方法而不是绑定。我为 Cocoa 读的书做了一些带有标签的复选框,但我认为它们在一个数组中,所以这可能不是最好的做法。
无论如何,当我运行它时,调试器将向我显示标签(等于行)以及按钮的状态(由于 NSOnState,所有按钮的状态均为 1)。我的问题是我无法根据方框的状态来选中和取消选中它们。我读了这个问题:表格列上的复选框不会注册点击
然后是 NSTableView 数据源引用。根据Nozzi先生在链接问题中的说法,在我看来,需要一个包含盒子状态的数组,所以我尝试了,将 [cell state]
设置为 NSNumber 以将其放入一个 NSMutableArray。我对此很生气,但我认为这是不对的。该表中有 454 行(由于数组从 0 开始,标签变为 453),所有四列。
我还想知道是否应该将 tableview:setObjectValue: 中的单元格定义内容放入“awakeFromNib”中。我确实在 IB 中放置了一个复选框按钮单元格,但我之前遇到了问题,所以我决定也以编程方式执行此操作。在所有这些过程中,我确实并且仍然在 setObjectValue 方法中有一个 [myTableVeew reloadData]
。
感谢您的帮助,如果需要任何其他信息,我可以得到它。
I'm making this program that has an NSTableView with four columns, two of which are make of checkboxes. I'm only trying to get one working right now and I've gotten stuck.
First, here's my relevant code:
- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
NSString *filePathThree = [[NSBundle mainBundle] pathForResource:@"mydictionary" ofType:@"plist"];
NSData *myDataThree = [[NSData alloc]initWithContentsOfFile:filePathThree];
self.flozzCodeAndName = (NSMutableDictionary *)[NSPropertyListSerialization
propertyListFromData:myDataThree
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:NULL
errorDescription:NULL];
return [[flozzCodeAndName objectForKey:@"name"] count];
}
- (void)tableView:(NSTableView *)tableView
setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
NSButtonCell *cell;
cell = [[NSButtonCell alloc] init];
[cell setButtonType:NSSwitchButton];
[cell setTitle:@""];
[cell setTag:rowIndex];
NSLog(@"%d", [cell tag]);
[cell setCellAttribute:NSCellEditable to:3];
[cell setImagePosition:NSImageOnly];
[cell setState:NSOnState];
NSLog(@"%d", [cell state]);
[havzColumn setDataCell:cell];
[myTableVeew reloadData];
[cell release];
}
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
NSString *filePathThree = [[NSBundle mainBundle] pathForResource:@"mydictionary" ofType:@"plist"];
NSData *myDataThree = [[NSData alloc]initWithContentsOfFile:filePathThree];
self.flozzCodeAndName = (NSMutableDictionary *)[NSPropertyListSerialization
propertyListFromData:myDataThree
mutabilityOption:NSPropertyListMutableContainersAndLeaves
format:NULL
errorDescription:NULL];
NSArray *myArray = [flozzCodeAndName objectForKey:[aTableColumn identifier]];
NSString *myStringValue = [myArray objectAtIndex:rowIndex];
return myStringValue;
}
As you can see, I'm using the data source method for this table rather than bindings. The book I read for Cocoa made some checkboxes with tags, but I think they were in an array, so that might not be the best thing to do.
Anyway, when I run this, the debugger will show me the tag (which equals the row) along with the state of the button (1 for all of them because of NSOnState). My problem is that I cannot get the boxes to check and uncheck depending on their state. I read this question: Checkbox on table column won't register click
And then the NSTableView datasource reference. According to Mr. Nozzi in the linked question, it seems to me that an array containing the states for the boxes is needed, so I tried that, setting [cell state]
to an NSNumber to get it into an NSMutableArray. I FUBAR'd that and don't think that was right. There are 454 rows in this table (tags go to 453 because of arrays starting at 0), for all four columns.
I also wonder if I should put the cell definition stuff that is in tableview:setObjectValue: into an 'awakeFromNib'. I did put a checkbox button cell in the IB, but I was having problems with it earlier, so I decided to do it programmatically too. During all of these, I did, and still do, have a [myTableVeew reloadData]
in the setObjectValue method.
The assistance is appreciated, if any other info is needed, I can get it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您有两个问题:您的数据源不断被破坏,并且您没有正确使用...objectValue...方法。
数据来源:
您在 -numberOfRowsInTableView: 方法中清除了数据源,并在每次表需要刷新时替换它。仅当您需要时(例如在应用程序启动时),您才需要缓存字典(的可变副本),然后仅从表数据源方法引用它。也许您应该将其移至实例变量并使用适当的访问器。
另外,文档提到,由于数据源方法被调用非常频繁,因此它们应该很快,因此仅从性能角度来看这不是一个好主意。您应该只做必要的事情来回答委托方法提出的问题,以保持表对大型数据集的响应。
对象值:您应该只从此方法返回对象值(通常是一个 NSNumber 对象,其中包含复选框要切换的状态。
您应该在加载视图时设置表格列的 -dataCell 或更简单的是:将复选框单元格拖到 Interface Builder 中的表列中,将其设置为不带代码的数据单元格
其他观察:如果您打算保留对此信息的更改。无论如何,请注意,您决不能依赖可写的应用程序包,并且决不应该尝试覆盖您从包中加载的资源文件,您需要将信息保存在其他地方。 ,仅使用您的捆绑副本作为模板副本。
You have two problems: Your data source keeps getting blown away and you're not using the ...objectValue... method properly.
Data Source:
You're blowing away your data source in your -numberOfRowsInTableView: method and replacing it every time the table needs to do a refresh. You'll want to cache (a mutable copy of) your dictionary only when you need to (like at application launch) then only refer to it from the table data source methods. Perhaps you should move it to an instance variable and use proper accessors.
Also, the documentation mentions that, because the data source methods are called very frequently, they should be fast, so from a performance viewpoint alone this is not a good idea. You should only do what it takes to answer the question the delegate method is posing to keep the table responsive with large data sets.
Object Value: You should ONLY be returning the object value from this method (usually an NSNumber object containing the state the checkbox is meant to toggle.
You should set your table column's -dataCell when the view is loaded or at application launch. Even easier: drag a check box cell into the table column in Interface Builder to set that as the data cell without code.
Additional Observation: If you plan to persist the changes to this information in any way, note that you must never rely on the application bundle being writable and should never attempt to overwrite resource files like the one you're loading from your bundle. You'll need to save the information elsewhere, using your bundle copy as a template copy only.