NSScrollView:淡入顶部
我想做的事:
在OS 10.10的Messages.app中,当向上滚动最左侧的窗格(对话列表)时,一条漂亮的水平线会消失约0.5秒。 当你向下滚动时,线条消失。
我拥有的:
我试图在自己的应用程序中实现这种效果,并且我已经非常接近。 我subclassed NSScrollView并完成以下操作:
- (void) awakeFromNib { _topBorderLayer = [[CALayer alloc] init]; CGColorRef bgColor = CGColorCreateGenericGray(0.8, 1.0f); _topBorderLayer.backgroundColor = bgColor; CGColorRelease(bgColor); _topBorderLayer.frame = CGRectMake(0.0f, 0.0f, self.bounds.size.width, 1.0f); _topBorderLayer.autoresizingMask = kCALayerWidthSizable; _topBorderLayer.zPosition = 1000000000; _fadeInAnimation = [[CABasicAnimation animationWithKeyPath:@"opacity"] retain]; _fadeInAnimation.duration = 0.6f; _fadeInAnimation.fromValue = @0; _fadeInAnimation.toValue = @1; _fadeInAnimation.removedOnCompletion = YES; _fadeInAnimation.fillMode = kCAFillModeBoth; [self.layer insertSublayer:_topBorderLayer atIndex:0]; }
- (void) layoutSublayersOfLayer:(CALayer *)layer { NSPoint origin = [self.contentView documentVisibleRect].origin; // 10 is a fudge factor for blank space above first row's actual content if (origin.y > 10) { if (!_topBorderIsShowing) { _topBorderIsShowing = YES; [_topBorderLayer addAnimation:_fadeInAnimation forKey:nil]; _topBorderLayer.opacity = 1.0f; } } else { if (!_topBorderIsShowing) { _topBorderIsShowing = NO; // Fade out animation here; omitted for brevity } } }
问题
我添加的“边框”子图层并不是在ScrollView中绘制其他所有内容的顶层,所以我们最终得出了这个结论:
在我的outlineView的这一行图像,文本框和复选框周围的框架是“透支”我的边框层。
这是什么原因导致
我认为这是因为scrollView包含在启用了Vibrancy的NSVisualEffectView中。 我认为这是因为如果我将我的“边框”子图层的颜色更改为100%黑色,则此问题会消失。 同样,如果我在OS X的“系统偏好设置”>“辅助功能”中打开“降低透明度”,问题就会消失。
我认为Vibrancy合成将我的灰色边框子图层和代表outlineView行中每个组件的图层分开,并将颜色分解。
所以...我怎样才能阻止单层? 我已经尝试过各种各样的事情来克服这一点。 我觉得自己是坚实实施的99%,但无法解决最后一个问题。 谁能帮忙?
注意:
我知道,在分层支持的环境中直接使用图层是很危险的。 Apple的文档清楚地表明,如果我们使用图层支持,则无法更改视图图层的某些属性。 但是:添加和删除子图层(就像我)不是被禁止的操作。
更新:
如果您使用AutoLayout,此答案在工作时会导致问题。 调用Layout之后,你会开始警告scrollView仍然需要更新,因为在更新过程中有些东西弄脏了布局。 我还没有找到解决方法。
原始解决方案
解决这个问题的最简单的方法就是用下面的边框子层的高度插入contentView:
- (void) tile { id contentView = [self contentView]; [super tile]; [contentView setFrame:NSInsetRect([contentView frame], 0.0, 1.0)]; }
在几个小时前应该想到它。 很棒。 我会留下任何可能希望实现这些漂亮边界的人的问题。
链接地址: http://www.djcxy.com/p/74243.html