在 UIScrollView 中覆盖 drawRect 时的黑色背景
Posted
技术标签:
【中文标题】在 UIScrollView 中覆盖 drawRect 时的黑色背景【英文标题】:black background when overriding drawRect in UIScrollView 【发布时间】:2012-07-03 20:52:06 【问题描述】:所以我试图在我的 UIScrollView 中覆盖 drawRect,但是它给了我这个黑色背景,而不是我为我的 UIScrollView 指定的背景颜色。为什么是这样?如果我删除 drawRect 代码,那么一切都很好:
- (void)drawRect:(CGRect)rect
[super drawRect:rect];
if (shouldDrawVerticalLineForProfile)
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef separatorColor = [UIColor colorWithRed:47.0/255.0 green:47.0/255.0
blue:47.0/255.0 alpha:1.0].CGColor;
// Add at bottom
CGPoint startPoint = CGPointMake(60, 0);
CGPoint endPoint = CGPointMake(60, 10000);
CGContextSaveGState(context);
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetStrokeColorWithColor(context, separatorColor);
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
CGContextStrokePath(context);
CGContextRestoreGState(context);
【问题讨论】:
我认为 backgroundColor 属性只是简单地包装了一个 CGContextAddRect 和 CGContextFillPath,如果你这样做呢? 使用我上面提到的两个函数手动绘制bgcolor。 我知道这并不能从根本上解决问题,但我只是最终将我的自定义逻辑从override func draw(rect: CGRect)
方法移动到 override func layoutSubviews()
。但它特别适用于我的情况。
【参考方案1】:
我猜你要搜索的是:
myScrollViewInstance.opaque = NO
之后,滚动视图的背景不再是黑色。
【讨论】:
我试过这个但没有帮助。我认为不是背景是黑色的。只有当scrollView的drawRect被覆盖时,scrollView才会变黑。如果 drawRect 未被覆盖,则滚动视图正常为白色。 此答案仅在您真正想要半透明背景的情况下才是正确的。如果您期望不明确的backgroundColor
得到尊重,它将失败。【参考方案2】:
我在 UIScrollView 子类中覆盖 drawRect 时遇到了类似的情况。
简单地覆盖:
- (void)drawRect:(CGRect)rect
[super drawRect:rect];
导致黑色背景,而不是我在不覆盖的情况下获得的所需清晰背景。
我发现这是因为在 Interface Builder 中将 View Background 设置为 Default 并且将其设置为 Clear Color
为我解决了这个问题。
我不确定这是否与您的问题有关,但我想分享一下以防万一。
【讨论】:
UIView 的drawRect:
被记录为“这个方法的默认实现什么都不做。”,所以调用它肯定不会做任何事情。你必须自己填充背景。【参考方案3】:
AppleDocs 中非常清楚地记录了 UIView 的drawRect:
方法的答案。第一句话是:
这个方法的默认实现什么都不做。
因此,此处调用 super 的建议无济于事。其余答案包含在讨论的更下方:
...如果您的视图的 opaque 属性设置为 YES,您的 drawRect: 方法必须用不透明的内容完全填充指定的矩形。
意思是如果你不打算有一个透明的背景,你需要实际绘制背景。最正确的做法是使用以下drawRect:
模板:
- (void)drawRect:(CGRect)rect
[super drawRect:rect]; // optional if a direct UIView-subclass, should be called otherwise.
CGContextRef context = UIGraphicsGetCurrentContext();
// Fill the background color, if needed
if (self.opaque)
UIGraphicsPushContext(context);
CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
CGContextFillRect(context, rect);
UIGraphicsPopContext();
// Your code here...
【讨论】:
绝对有效的答案。很好的解释亚当 乐于助人。也许这是我的答案最终获得额外 15 票成为榜首的十年:)【参考方案4】:这应该会有所帮助
CGContextSetFillColorWithColor(context, colorBack);
CGContextFillRect(context, self.bounds);
// 相应地选择bounds和colorBack
【讨论】:
使用矩形,而不是边界,让 UIKit 在需要时优化绘图。【参考方案5】:请试试这个它为我工作
- (id)initWithFrame:(CGRect)frame
if (self = [super initWithFrame:frame])
[self setBackgroundColor:[UIColor clearColor]];
return self;
- (void)drawRect:(CGRect)rect
[super drawRect:rect];
if (shouldDrawVerticalLineForProfile)
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef separatorColor = [UIColor colorWithRed:47.0/255.0 green:47.0/255.0
blue:47.0/255.0 alpha:1.0].CGColor;
// Add at bottom
CGPoint startPoint = CGPointMake(60, 0);
CGPoint endPoint = CGPointMake(60, 10000);
CGContextSaveGState(context);
CGContextSetLineCap(context, kCGLineCapSquare);
CGContextSetStrokeColorWithColor(context, separatorColor);
CGContextSetLineWidth(context, 5.0);
CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5);
CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5);
CGContextStrokePath(context);
CGContextRestoreGState(context);
【讨论】:
【参考方案6】:唯一对我有用的是在调用setNeedsDisplay
之后显式设置背景。在我的示例中,我在地图上使用了 MKAnnotationView
的子类,而不是 UIScrollView
,所以我真的不知道这在 OP 场景中的适用程度如何。就我而言,我从setAnnotation
调用setNeedsDisplay
,我发现这样做会重置backgroundColor
。只需在setNeedsDisplay
解决问题后由backgroundColor
重新设置即可。
FWIW,我也观察到简单地覆盖 drawRect
以委托给超类会导致这个黑色背景问题。
【讨论】:
以上是关于在 UIScrollView 中覆盖 drawRect 时的黑色背景的主要内容,如果未能解决你的问题,请参考以下文章
为啥即使我覆盖 touchesMoved:withEvent:,UIScrollView 的子类仍会滚动?
UICollectionView targetContentOffsetForProposedContentOffset:被 UIScrollView 覆盖