应该如何布置NSTableCellView?

时间:2013-09-23 15:27:25

标签: xib nstextfield xcode5 monomac xamarin-studio

我有一个相当基本的MainWindow.xib,其中包含源列表样式的侧边栏。我是通过将源列表模板拖到窗口中创建的,该窗口已包含两个NSTableCellView s:HeaderCellDataCell

后者包含一个图标(使用NSImageView)和一个标签(NSTextField)。相反,我想要标签和另一个较小的标签。在IB中,这看起来如下:

Source list according to IB

如果我只关注DataCell,则会突出显示:

DataCell highlighted

事实上,实际上运行该程序,它看起来就像模板:

Second item in live DataCell selected

注意两个NSTextField如何被打成一个。我的理解是,基于视图的NSOutlineView s(以及基于视图的NSTableView s)应该被设计为IB内的模板。相反,模板中的尺寸似乎大部分都被忽略了。

以下是从数据源设置视图值的代码:

public class TourSourceListDelegate : NSOutlineViewDelegate
{
    public override bool IsGroupItem(NSOutlineView outlineView, MonoMac.Foundation.NSObject item)
    {
        return (item as TourSourceListDataSource.Item).IsHeader;
    }

    public override NSView GetView(NSOutlineView outlineView, NSTableColumn tableColumn, MonoMac.Foundation.NSObject item)
    {
        if (IsGroupItem(outlineView, item))
        {
            return outlineView.MakeView("HeaderCell", this);
        }
        else
        {
            var data = item as TourSourceListDataSource.Item;
            var dataView = outlineView.MakeView("DataCell", this);

            (dataView.Subviews[0] as NSTextField).StringValue = data.Name;
            (dataView.Subviews[1] as NSTextField).StringValue = data.Date_start.ToShortDateString();

            return dataView;
        }
    }
}

我已尝试覆盖GetRowHeight,但这似乎无法解决问题(它会腾出更多空间,但仍然不会让视图正确分发自己),它似乎也没必要。

我也试过在IB中使用各种AutosizingAutoresizes Subviews等切换,但这似乎不会产生直观的结果,而且似乎没有必要 - IB中显示的视图正是我想要的,只是在实践中标签稍长。

我还没有尝试将其转换为AutoLayout。

我错过了哪一个明显的步骤?

更多信息可能没有什么区别:这是一个Xamarin.Mac / MonoMac项目,包含Xcode 5.0,MacOSX10.8.sdk,Xamarin Studio 4.0.12,Xamarin.Mac 4.0.12和Mono 3.2 .3(针对Mono / .NET 4.0)。我还启用了App Sandboxing。

1 个答案:

答案 0 :(得分:1)

界面构建器中重要的是视图层次结构。细胞是什么样的观点?这些标签是否真的是细胞视图的子视图?层次结构应该类似于:

example NSOutlineView cell hiearchy

我看到一件可疑的事情是访问dataView.Subviews[0][1]。如果要将子视图添加到单元格,则应创建自己的NSTableViewCell子类,每个视图都连接到子类“IBOutlet属性”。子类在其实现中不需要任何代码,只需在@interface中声明其属性,例如titleFielddescriptionField,以及一个自动的@implementation合成它们。

当传递正确的标识符时,makeViewWithIdentifier(或者显然是Xamarin中的粘合MakeView)应创建您的NSTableViewCell子类,并且在运行时您可以使用po dataView验证在调试器中。然后使用NSTableViewCell子类'接口的属性访问子视图,而不是使用dataView.titleFielddataView.descriptionField假设哪个视图位于子视图阵列的哪个位置。

如果您的单元格视图有一个文本字段,那么您可以使用NSTableViewCell而不进行子类化,但可以连接textField插座(默认情况下连接它,只要您不删除并重新创建单元格视图的标签视图)因此您可以再次通过该属性访问它,而不必潜入子视图数组。

所有这一切,都不清楚为什么你会看到你是什么。看起来这些不是您期望的子视图,甚至可能看起来像错误的字体以及错误的位置。使用NSTableViewCell的自定义子类并在运行时验证其类是确保它创建所需视图的好方法,但您也可以使用po [dataView _subtreeDescription]将子视图转储到调试器中。