今天研究了一下一种导航栏Naughty的属性效果
思路就是 通过 scrollViewDidScroll 不断地调整drawRect引用的属性然后进行setNeedsDisplay来绘制效果
(drawRect中的逻辑后面说明) 中间碰到的一个问题就是 前面绘制的内容 在后面更新绘制的时候不会被清除 如图:
对着问题找原因 - 从stackoverflow上得到一些信息:
Make you sure have this set (but it should be defaulted to YES).
self.clearsContextBeforeDrawing = YES;
From Apple's Docs in UIView
When set to YES, the drawing buffer is automatically cleared to transparent black before the drawRect: method is called. This behavior ensures that there are no visual artifacts left over when the view’s contents are redrawn. If the view’s opaque property is also set to YES, the backgroundColor property of the view must not be nil or drawing errors may occur. The default value of this property is YES.
If you set the value of this property to NO, you are responsible for ensuring the contents of the view are drawn properly in your drawRect: method. If your drawing code is already heavily optimized, setting this property is NO can improve performance, especially during scrolling when only a portion of the view might need to be redrawn.
指的是 clearsContextBeforeDrawing 这个属性需要设置YES 但是我实际测试了发现没有效果 而且这个属性默认就是YES 于是乎又找到另外个信息
Set the backgroundColor of the view to [UIColor clearColor].
Note that setting the background color only needs to be done once, when the view is created.
在初始化绘制的view中设置 background color 为 clearColor 测试了一下确实可以了
-(SSNaughtyProgressView *)progressView{
if (!_progressView) {
_progressView = [[SSNaughtyProgressView alloc] init];
//如果不设置background 那么在draw rect 中之前的绘制会被叠加 不会清除
_progressView.backgroundColor = [UIColor clearColor];
}
return _progressView;
}
确实可以了 但是为什么呢~ 陷入沉思~
Apple的文档上对drawRect方法是这样描述的:
Discussion
The default implementation of this method does nothing. Subclasses that use technologies such as Core Graphics and UIKit to draw their view’s content should override this method and implement their drawing code there. You do not need to override this method if your view sets its content in other ways. For example, you do not need to override this method if your view just displays a background color or if your view sets its content directly using the underlying layer object.
By the time this method is called, UIKit has configured the drawing environment appropriately for your view and you can simply call whatever drawing methods and functions you need to render your content. Specifically, UIKit creates and configures a graphics context for drawing and adjusts the transform of that context so that its origin matches the origin of your view’s bounds rectangle. You can get a reference to the graphics context using the UIGraphicsGetCurrentContext function, but do not establish a strong reference to the graphics context because it can change between calls to the drawRect: method.
Similarly, if you draw using OpenGL ES and the GLKView class, GLKit configures the underlying OpenGL ES context appropriately for your view before calling this method (or the glkView:drawInRect: method of your GLKView delegate), so you can simply issue whatever OpenGL ES commands you need to render your content. For more information about how to draw using OpenGL ES, see OpenGL ES Programming Guide.
You should limit any drawing to the rectangle specified in the rect parameter. In addition, if the opaque property of your view is set to YES, your drawRect: method must totally fill the specified rectangle with opaque content.
If you subclass UIView directly, your implementation of this method does not need to call super. However, if you are subclassing a different view class, you should call super at some point in your implementation.
This method is called when a view is first displayed or when an event occurs that invalidates a visible part of the view. You should never call this method directly yourself. To invalidate part of your view, and thus cause that portion to be redrawn, call the setNeedsDisplay or setNeedsDisplayInRect: method instead.
中间这句
You should limit any drawing to the rectangle specified in the rect parameter. In addition, if the opaque property of your view is set to YES, your drawRect: method must totally fill the specified rectangle with opaque content.
您应该将任何绘图限制为rect参数中指定的矩形。 此外,如果视图的opaque属性设置为YES,则drawRect:方法必须使用不透明内容完全填充指定的矩形。
后面我将 opaque 设置为false 发现也是可以的 猜测应该是与绘制context上下文的时候透明的问题
-(SSNaughtyProgressView *)progressView{
if (!_progressView) {
_progressView = [[SSNaughtyProgressView alloc] init];
//如果不设置background 那么在draw rect 中之前的绘制会被叠加 不会清除
//或者设置 opaque 为 false 来指定透明的问题
_progressView.backgroundColor = [UIColor clearColor];
_progressView.opaque = false;
}
return _progressView;
}