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

上一篇: NSScrollView: fade in a top

下一篇: UIButton shadow not looking right