我创建了一个实现initWithFrame和drawRect的自定义视图。在IB中,我创建了一个窗口并将自定义视图放在窗口的中心。然后我使用编辑器>嵌入>滚动视图将自定义视图放入滚动视图。然后,什么都没有? initWithFrame消息将发送到自定义视图,但永远不会发送drawRect消息。
如果没有我的特定自定义视图,可以生成类似的行为。如果包装标签以相同的方式嵌入滚动视图中,则也不会绘制它。
如何让scrollview绘制其内容?
另外,在一个有点相关的说明中,以编程方式调整滚动视图中嵌入的视图的正确方法是什么?
谢谢!
答案 0 :(得分:23)
NSScrollView 与其他观看次数不同。 它做的事情就完全不同了,一开始就让每个人都疯了,特别是一旦你习惯了自动布局思维。 它也是其中一个视图(连同NSTableView,NSOutlineView和NSCollectionView等),在你开始看到工作之前,有许多部分需要设置。自动布局也增加了这一点。
NSScrollView 默认包含至少3个子视图:
NSClipView 或内容视图对象包含某种 NSView 。
(Apple称此 文档视图)
如果从对象库向xib添加一个简单的 NSScrollView ,它在Interface Builder中看起来有一个大小,但在运行时它的大小为零。 每次都会踢你的屁股。 你可以通过添加日志记录来看到这一点。
NSLog(@" size of document view:%@", NSStringFromRect(_myScrollView.documentView.frame);
即使你添加一个子视图并整天打电话给setNeedsDisplay:YES
,你也不会看到该死的东西。
你可以做些事情。
首先,您可以使用setFrameSize:NSMakeSize(somePointsWide, somePointsHigh)
你也可以把它变成一个自定义的NSView子类,它有一个intrinsicContentSize
的实现,根据你想要放在那里的逻辑规则来计算出来(包括一些默认的最小值)。
您还可以简单地说,所有子视图必须至少是来自 documentView 的N个点,或者每个边缘都有自动布局。
VFL(可视格式语言)如下所示:@"H:|-nPoints-[aSubviewOfDocumentView]-nPoints-|"
和此@"V:|-nPoints-[aSubviewOfDocumentView]-nPoints-|"
(确保您的子视图具有内在大小或他们自己的某个子视图,为他们提供最小尺寸...并实现- (BOOL)translatesAutoresizingMaskIntoConstraints { return NO; }
并通过IB中的复选框关闭文档视图的自动调整大小视图,或者通过调用{ {1}}或者你会讨厌生活。)
现在这导致了一个奇怪的事情。 使用自动布局,通常可以尽可能多地停止考虑帧和rects,但是使用NSScrollView documentView,您可能需要考虑不使用自动布局来定位子视图。在某些情况下,它可能更简单,只需让documentView适应。如果您使用上面的“nPoints”方法,并且您的子视图是可拖动的,您只想捕获子视图的帧原点的NSPoint(用它来确定您的delta),然后捕捉mouseDown点,当拖动完成时,捕获鼠标指向并计算新帧原点的增量。然后使用新点调用setFrameOrigin:
答案 1 :(得分:4)
您是使用自动布局还是老式视图调整大小?如果调用了init方法但没有调用draw方法,则听起来就像整个scrollView或自定义视图的大小为零。
如果您有自定义视图并且正在使用autolayout,那么您是否在自定义视图子类中实现了-intrinsicContentSize方法?
答案 2 :(得分:0)
我刚完成 fighting 哄骗NSScrollView来使用自定义视图。正如uchuugaka几年前指出的那样,在启用了自动布局系统的情况下重新调整NSScrollView的大小可能会导致滚动视图在您滚动的内容视图大于实际文档视图时增长。
需要注意两件事,都可以在您的customView的drawRect()中进行纠正
为解决这个问题,我的自定义视图(仅垂直滚动)在drawRect()中检查这些情况,并根据我们长大还是缩小来更正大小。
if scrollView.documentVisibleRect.size.height >= actualDocumentHeight {
//
// Sometimes the scroller machinery can enlarge the document rect a little
// extra when resizing the window quickly. We should check for that.
//
if self.bounds.size.height > scrollView.contentSize.height {
self.frame.size.height = scrollView.contentSize.height
self.bounds.size.height = scrollView.contentSize.height
}
} else {
//
// If it's smaller, set our size to the actual size and the scroll
// bars will pop on.
//
self.frame.size.height = actualDocumentHeight
self.bounds.size.height = actualDocumentHeight
}