NSTableView中的NSButtonCell检查类型不允许更改值 [英] NSButtonCell of Check type within NSTableView does not allow to have value changed

查看:270
本文介绍了NSTableView中的NSButtonCell检查类型不允许更改值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有3个表视图的窗口(10.7.2,Xcode 4.2)。
它们都在IB中创建,NSButtonCells与插座连接。



我创建了控制器类,我用一些示例数据填充了所有三个视图:

   - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
return 10;
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

NSButtonCell * buttonCell;

if(aTableView == dimensionTable){
[dimensionButtonCell setTitle:@Dimension];
buttonCell = dimensionButtonCell;
}
else if(aTableView == shopTable){
[shopButtonCell setTitle:@Shop];
buttonCell = shopButtonCell;
}
else if(aTableView == countryTable){
[countryButtonCell setTitle:@Country];
buttonCell = countryButtonCell;
}


return buttonCell;

}

我有2个问题:


  1. 我无法通过GUI更改复选框状态。我可以改变它的程序,但。


  2. 我尝试用视图填充数据,没有插座到细胞。它没有工作。



NSButtonCell在单元格视图内是否与基于视图的表视图或正常解决方案

经过长期的努力,我设法找到问题的解决方案。这个问题的一个部分是数据模型方面的简单错误,但这并不重要,使用NSTableView委托和数据源来完成更困难的事情。



这主要是3个困难,阻碍了很好的理解和管理这个问题:




  • 苹果的文档缺乏关于差异和典型在表视图的数据源和 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex > - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 虽然看起来你可能需要后面的方法,因为NSButtonCells是自定义的NSCells,事实证明没有必要,但是我还是把它留在最后。


  • NSTableView方法中的内部转换


  • b
    $ b

    这里是你应该做的步骤:

       - (id)tableView:(NSTableView * )aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

    buttonCell = [aTableColumn dataCell];

    NSString * columnKey = [aTableColumn identifier];

    返回buttonCell;

    }

    您可以看到,

       - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row: NSInteger)row {

    buttonCell = [tableColumn dataCell];

    NSString * columnKey = [tableColumn identifier];

    if(tableView == dimensionTable){

    // returnObject = @Dimension;
    // [dimensionalButtonCell setTitle:@Dimension];
    // buttonCell = dimensionButtonCell;
    }

    else if(tableView == shopTable){

    [buttonCell setState:[[mySelectedShops objectAtIndex:row] integerValue]];
    [buttonCell setTitle:[myShops objectAtIndex:row]];

    }

    else if(tableView == countryTable){

    [buttonCell setState:[[mySelectedCountries objectAtIndex:row] integerValue]];
    [buttonCell setTitle:[myCountries objectAtIndex:row]];

    }

    return buttonCell;

    }

    你可以看到我使用第二个方法, $ c> objectValueForTableColumn 可以单独使用。
    你还可以看到,我有NSMutableArray mySelectedShops和mySelectedCountries来保存NSInteger(1或0)包装在NSNumber中为表视图中的每一行。



    如果你设置NSCell的状态或integerValue没有区别。两者都将使用NSInteger类型的值1或0来检查和取消选中NSButtonCell。

       - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {

    NSString * columnKey = [aTableColumn identifier];

    if(aTableView == dimensionTable){
    // [dimensionButtonCell setTitle:@Dimension];
    // buttonCell = dimensionButtonCell;
    }
    else if(aTableView == shopTable){

    [mySelectedShops replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell *)anObject integerValue]

    }
    else if(aTableView == countryTable){

    [mySelectedCountries replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell *)anObject integerValue] ];

    }

    }

    NSInteger值到NSCell对象,anObject这里是__NSCFBoolean类型,这意味着某些东西不能按预期工作。为了能够将对象值替换为数组,我已将其转换为NSCell,只获取integerValues。



    很明显,苹果正在向基于视图的单元格移动在UITableView。仍然,我希望这将有助于某人。


    I have window with 3 table views (10.7.2, Xcode 4.2). They are all created in IB and NSButtonCells are connected with outlets.

    I created controller class and I filled all three views with some sample data:

    - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView {
        return 10;
    }
    
    - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn    *)aTableColumn row:(NSInteger)rowIndex {
    
    NSButtonCell *buttonCell;
    
    if(aTableView == dimensionTable) {    
        [dimensionButtonCell setTitle:@"Dimension"];
        buttonCell = dimensionButtonCell;
    }
    else if(aTableView == shopTable) {
        [shopButtonCell setTitle:@"Shop"];
        buttonCell = shopButtonCell;
    }
    else if(aTableView == countryTable) {
        [countryButtonCell setTitle:@"Country"];
        buttonCell = countryButtonCell;
    }
    
    
    return buttonCell;
    
    }
    

    I have 2 questions:

    1. I cannot change checkbox state through GUI. I can change it programatically, though. It blinks a bit, when you hold down mouse button, but doesn't allow change...

    2. I tried to fill data as with views, without outlets to cells. It didn't work. Are NSButtonCell cels within cell views somehow different as view based Table Views or "normal" cel based Table Views?

    解决方案

    After long struggle I manage to find the solution for the problem. One part of the problem was simple bug at the data model side, but it wasn't crucial, something much more difficult was to be done with NSTableView delegate and datasource.

    THere were mainly 3 difficulties that prevented good understanding and managing this problem:

    • apple's documentation lacks of any reasonable explanation about differences and typical usage of - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndexin table view's data source and - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row of its delegate. While it may seem that you would need latter method, because NSButtonCells are custom NSCells it turns out it is not necessary, but I left it at the end anyway.

    • internal conversions in NSTableView methods

    • problem is not documented almost anywhere on the net

    Here are steps you should do:

    - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
    
        buttonCell = [aTableColumn dataCell];
    
        NSString *columnKey = [aTableColumn identifier];
    
        return buttonCell;
    
    }
    

    You can see this method has to be implemented whether you use it or not.

    - (NSCell *)tableView:(NSTableView *)tableView dataCellForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
    
        buttonCell = [tableColumn dataCell];
    
        NSString *columnKey = [tableColumn identifier];
    
        if(tableView == dimensionTable) {    
    
    //        returnObject = @"Dimension";
            //        [dimensionButtonCell setTitle:@"Dimension"];
            //        buttonCell = dimensionButtonCell;
        }
    
        else if(tableView == shopTable) {
    
            [buttonCell setState:[[mySelectedShops objectAtIndex:row] integerValue]];
            [buttonCell setTitle:[myShops objectAtIndex:row]];
    
        }
    
        else if(tableView == countryTable) {
    
            [buttonCell setState:[[mySelectedCountries objectAtIndex:row] integerValue]];
            [buttonCell setTitle:[myCountries objectAtIndex:row]];
    
        }
    
        return buttonCell;
    
    }
    

    you can see I used second method, however objectValueForTableColumn could be used solely. You can also see, I have NSMutableArray mySelectedShops and mySelectedCountries to hold NSInteger (1 or 0) wrapped in NSNumber for each row in Table View.

    If you set the state or integerValue of NSCell makes no difference. Both will check and uncheck NSButtonCell with values 1 or 0 of NSInteger type.

    - (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex {
    
        NSString *columnKey = [aTableColumn identifier];
    
        if(aTableView == dimensionTable) {    
    //        [dimensionButtonCell setTitle:@"Dimension"];
    //        buttonCell = dimensionButtonCell;
        }
        else if(aTableView == shopTable) {
    
            [mySelectedShops replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];
    
        }
        else if(aTableView == countryTable) {
    
            [mySelectedCountries replaceObjectAtIndex:rowIndex withObject:[NSNumber numberWithInteger:[(NSCell*)anObject integerValue]]];
    
        }
    
    }
    

    Although I passed NSInteger value to NSCell object, anObject here is of __NSCFBoolean type, which means something doesn't work as expected. To be able to replace object value to arrays I have casted it to NSCell only to get integerValues. It actually works without cast as well, so it is another mystery to me, but I like it more that way.

    It is clear Apple is moving to view based cells like in UITableView. Still, I hope this will help to somebody.

    这篇关于NSTableView中的NSButtonCell检查类型不允许更改值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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