Drawing beyond a UIView's bounds - ios

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:.

Related

iOS: How to fill a rectangle except in one area?

I've used the CGContext based routine to fill a rectangle, but this time I actually want to fill all of a rectangle EXCEPT one part of it. I know this is possible in other drawing systems for other platofrm but can it be done with core graphics on iOS?
Both borderWidth and cornerRadius are animatable properties. So you could just animate them directly (using CABasicAnimation). In that rendering, you'd go from no border and no corners to having a border and corners in an animated way.
If you want to animate the rectangular tracing of the border, you'd need to use a CAShapeLayer (because the end of its path is animatable) and provide the illusion that way.

Resizing a rectangle drawn in drawRect

I have two UIViews. My aim is to draw the smallest rectangle which contains both these UIViews. I thought to draw a rectangle using the frame which I'll get out of
CGRectUnion(view1.frame, view2.frame);
But when I move any of the two UIViews, I need to update the frame of the outlining rectangle.
I thought I could do this by :
1) Resizing the previously drawn rectangle.
(or)
2) Deleting the previously drawn rectangle and drawing a new one.
The problem is that, I don't know how to get the instance of the previously drawn rectangle. So, I don't know how to update or delete it..
Can any of you guys help?
Is there any other solution to this problem?
Perhaps you can declare the following in your .h file:
CGRect *transformingRect;
Doing so should retain the rectangle and its properties so long as whatever view controller this is in is visible and loaded. This way you can have a method that resizes the same drawn rect. You would simply call this whenever you need to resize it.
-(void)resizeRect {
transformingRect = CGRectUnion(view1.frame, view2.frame);
}

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.

How to make irregular shaped UIScrollView?

I want to make irregular shaped UIScrollView(using CGPath or UIBezierPath).
The contents will be scrollable and zoomable. And scroll actions will be accepted only in these areas, not rectangular area. Any ideas?
Your could use a CAShapedLayer with a path to create a clipping path and apply this to the Scrollview's layer's mask. Use the same path in the view's hitTest:withEvent: to decide, if the UIView should response to a touch or not.

Is content drawn by drawRect able to animate using UIView animation?

On iOS, if there are two circles, both of which are UIView objects, then their center or frame can animate using UIView animation.
But the difficulty is, the container UITreeView containing these two circles, draw a line connecting the centers of the circles, using drawRect. In drawRect, I could use CG or UIKit to draw the line, and I chose to use UIBezierPath's moveToPoint and addLineToPoint to draw the line, which should actually just be CG calls underneath, but easier to use.
But when one circle animates to the other position, the line won't animate with it, so the animation can look kind of weird. Is there a way to make it animate?
I tried animating in the TreeView class instead of inside the UINodeView class (the circle), but that won't help. In fact, if I draw the circle using a random color in its drawRect method, when the circle moves slowly in the animation, the color won't change rapidly, suggesting that its drawRect isn't called. It probably is just CALayer that hold a cached image being animated.
So is there a way to make the line animate as well?
The other methods I can think of is:
1) Use a hack to use a UIView to hold the line also, so its frame can animate, but what if the circle moves so that the line needs to be drawn inside the UIView from (0, 0) to (200, 200), but now the line needs to slant the other way, drawing from (200, 0) to (0, 200), so in this case, it probably won't work. (But if I use some kind of transform to flip the image at the same time, it probably will work, but it seems complicated to consider when the transform should be used)
2) use CADisplayLink to do the animation, and just let it call [treeView setNeedsDisplay]; and in this case, the drawRect will be called for sure. (it can be an overkill, and since the whole background of the TreeView will be first erased, there might be a little flashing on the screen going on)
Or is there a simpler or better way?
You could assign your path to a CAShapeLayer (such as wrapping it in a UIView subclass that returns CAShapeLayer as its +layerClass). The path is assigned to the CGPath -path property (and note that UIBezierPath provides a CGPath property).
Then you have a line in a view that you can animate (such as a group animation using UIView +beginAnimations
.

Resources