我想在滚动表上放置一个文本标签,但标签与滚动图形冲突。在这里你可以看到一个测试,我有意将标签的一半放在桌子外面并在表格中向上滚动,这导致标签覆盖的一部分被拖动,直到它退出窗口
此外,当我走到桌子的另一端并向下滚动时,有时标签似乎被重新绘制,并且它的大块随着滚动一起上升:
表似乎正在重绘其内容,并且在它们被覆盖时不会通知其余的视图对象重绘自己。我该如何解决这个问题?事实上,这似乎与How to place an NSButton over an NSTableView高度相关,它似乎有相同的问题,但有一个按钮而不是标签。
答案 0 :(得分:1)
不要这样做,因为你会失去很多表现并增加能量消耗。
尝试使用NSScrollView方法
- (void)addFloatingSubview:(NSView *)view forAxis:(NSEventGestureAxis)axis
答案 1 :(得分:1)
这是因为滚动视图设置为在滚动时复制其内容,并仅重新绘制新发现的部分作为性能优化。要关闭它,请使用
myScrollView.contentView.copiesOnScroll = NO;
虽然这会让滚动使用更多CPU(你也可以在XIB中执行此操作,查找'滚动副本'复选框)。
可能更好的方法是将滚动视图和按钮切换为图层支持:
myTableView.enclosingScrollView.wantsLayer = YES;
myTextView.wantsLayer = YES;
(同样,您可以在XIB文件的“图层”检查器中设置此项,您可以在其中单击每个视图旁边的复选框以为其指定图层)现在,滚动视图将仅复制其自身图层中的内容(不再包含您的文本视图)。此外,现在所有文本视图的合成都将在图形卡中完成。但是,如果将文本放在其自己的图层中的透明背景上,则会丢失子像素消除锯齿。但如果它是任何其他类型的视图(或者你的文本后面实际上有一个坚实的背景),那么看起来会很好。
答案 2 :(得分:1)
另一种获得正确重绘的替代方法是在Effects Inspector中打开xib根视图,并将其标记为使用Core Animation Layer。这避免了需要使用重绘钩子创建自定义类。
答案 3 :(得分:0)
是的,似乎NSTableView 缓存孔表的绘图,以便滚动视图不必为每个像素刷新它。然而,这正是所需要的。幸运的是,它可以完成,我设法通过以下方式子类化NSScrollView以向reflectScrolledClipView:
添加属性和挂钩:
@interface EHScrollView : NSScrollView
@property (nonatomic, weak) NSView *refreshView;
@end
实施将是:
#import "EHScrollView.h"
@implementation EHScrollView
- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
[super reflectScrolledClipView:aClipView];
[self.refreshView setNeedsDisplay:YES];
}
@end
然后,唯一需要修改用户界面的xib。如果表嵌入在滚动视图中,请选择滚动视图并对其进行修改以继承自定义类EHScrollView。然后,在视图控制器初始化中,使用出口滚动视图和表视图,通过refreshView
属性将后者链接到前者。
现在,每个滚动都会自动调用setNeedsDisplay:
上的refreshView
,这意味着表格和覆盖在顶部的任何内容都将重新绘制。当然,这比非刷新表更具性能,所以只在有意义的地方使用。