NSTableCellViews应该如何布局?

9

我有一个相当基本的MainWindow.xib,其中包含一个源列表样式的侧边栏。我通过将“源列表”模板拖入窗口中创建它,其中已经包含两个NSTableCellViewHeaderCellDataCell

后者由一个图标(使用NSImageView)和一个标签(NSTextField)组成。但是,我想要标签和另一个更小的标签在其下方。在IB中,它看起来如下:

Source list according to IB

如果我只关注DataCell,它会相应地突出显示:

DataCell highlighted

问题在于,实际运行程序时,它看起来与模板完全不同:

Second item in live DataCell selected

请注意,这两个NSTextField被挤在一起。我的理解是,基于视图的NSOutlineView(以及基于视图的NSTableView)应该从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)。我还启用了应用程序沙箱。

1个回答

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]在调试器中转储子视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接