CATiledLayer: How to cause reload of just some tiles? - ios

I'm using a tiled layer in a scroll view to display a custom view. The contents of the custom view change periodically, and I know the rectangle in which those changes occur. However I have found that if I do a setNeedsRedisplay only one tile is getting redrawn. How can I tell the CATiledLayer to redraw only the affected tiles?

If you call setNeedsDisplay on the CATiledLayer, then it redraws all its tiles. If you use setNeedsDisplayInRect instead, it should only redraws those tiles that intersect with the rectangle you specify. Note however, that it will redraw the whole tile, not just the part that intersects with the rectangle.
Note also the redraw bug in CATiledLayer when you call setNeedsDisplay when it is in the process of drawing. More on that you can find in this question.

Related

Drawing beyond a UIView's bounds

I'm trying to draw a complex border around a UIView in it's drawRect method using core graphics. The border is being clipped because it's outside of the view's bounds. Is there any way to prevent this clipping? Setting clipsToBounds to NO doesn't work.
drawRect: gives you a CGRect. This defines the area in which you can draw. As it stands, you cannot draw outside this area.
You'd have to look into a different solution to your problem. I'd suggest CALayers, or a subview/superview hierarchy, perhaps a border view and a content view. But don't try doing that in drawRect:, unless you can get the desired results while keeping within the area specified by drawRect:.

Resize UIView so that whatever I draw is visible - ObjectiveC

I have a UIView. I am drawing a line inside the UIView programmativally. But when the line goes outside the UIView, the part of the line which goes out, is invisible. How can I resize the UIView so that whatever I draw inside the drawRect method is visible?
you can change the frame of view. If your line is horizontal then give width to view else increase height of view.
view.frame = CGRectMake(view.frame.origine.x, view.frame.origine.y,view.frame.size.width,lengthOfLine );
If the curve you are drawing is a subview, then you can make use of sizeToFit method. This will make the view's frame enclose the curve(and all subviews, for that matter). Then you can reposition and scale the view's frame to make it fit in the window.
You have mentioned in a comment that you are actually drawing a curve. From what I can tell, you will need to calculate the curve's bounding box yourself.
Based on the bounding box, update the UIView's bounds property (as Durgaprasad suggested). This also resizes the underlying CALayer, which also gives its underlying Core Graphics rendering context a larger bitmap.
Without knowing more about your curve, it's hard to help, apart from linking to some very generic discussion on quadratic Beziers.
You may want to update your question with a minimal implementation of -drawRect: that will allow someone to reproduce your issue.

Using setNeedsDisplayInRect still erases the underlying content

I've subclassed a UIView and overridden the touchesBegan, touchesMoved, touchesEnded, and drawRect methods to create an app that allows the user to draw by touching the screen. I'm using the Quartz 2D library to do the drawings.
In touchesBegan, touchesMoved, and touchesEnded, I keep track of the current and previous locations of the touch event. Each time the touch moves and when the touch ends, I call setNeedsDisplayInRect using the smallest rectangle that contains the previous and current location of the touch in order to preserve underlying drawings. (I want all drawings to add on to one another like layers.)
I've noticed a strange artifact: When creating a drawing that overlaps with another drawing, Quartz re-draws the rectangle passed into setNeedsDisplayInRect but erases everything below that rectangle.
I suspect that the issue is due to the blending mode, however I experimented with a number of different blending modes and none seemed to do the trick.
How do I draw a path that preserves the underlying content?
Quartz is not a canvas model. It does not keep track of what was drawn in previous loops. Every time drawRect: is called, it is your responsibility to deal with every pixel in the rectangle you are passed. By default (set in UIView clearsContextBeforeDrawing), Quartz will clear the rectangle for you, but it's your job to draw the content every time.
If you want to layer things, you either need to put each thing in its own CALayer or UIView, or you need to redraw any overlaps each time drawRect: is called.

How to resize a custom UIView and maintain its custom draw in proportion?

I have a custom view with some drawing on it.
I want to resize it to a new proportion and I want the pattern I drew in it's drawRect to also be resized by the same proportion.
Is there anyway I can accomplish this without refreshing and redrawing everything.
This should be happening for you automatically with the default contentMode, which is UIViewContentModeScaleToFill. contentMode determines how to adjust the cached bitmap without forcing a new call to drawRect:. Also see contentStretch which allows you to control which part of the view is scaled.
you will have to redraw it for the new proportion.
For that you have to store the points that made the CGPath and scale the points according to the new proportion and render it again.
Redrawing CGPath needs attention.
If you have used simple moveTopoint / AddlinePoint you can do it just by storing points in an array. You can scale and redraw it later.
If you can used functions like addcurveTopoint etc., storing points in array won't work.A general purpose way is needed.For that you have to use the CGpathApply function. You can see an example it here. http://www.mlsite.net/blog/?p=1312
If you need to zoom and no interation neeeded you can take a scrrenshot and and zoom the image.

Zoomable Graphics

I am trying to draw zoomable graphics onto the screen. I currently have a UIView inside of a ScrollView and I'm wondering what the best way is to go about handling/implementing zooming of the graphics I've drawn on the screen.
You'll probably want to use something along the lines of what I describe in my answer here.
During the pinch-zooming event, a transform will be applied to your UIView, which will zoom the content but will lead to blurring. Once the zooming event is finished, use the -scrollViewDidEndZooming:withView:atScale: delegate method to determine the new scale factor and resize and re-render your UIView appropriately. If you're doing your drawing using Core Graphics within the -drawRect: method of your UIView, this should be pretty easy to manage.

Resources