Resizing a rectangle drawn in drawRect - ios

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);
}

Related

Set corners of UIView (iOS)

I have the following problem: I'm scanning a QR Code with AVFoundation. This works quite well and I can also create a border around the code by adding a subview and set the frame attribute by subview.frame = qrCodeObject.bounds. This only has the problem that the border is only a rectangle and dismisses the perspective of the QR code.
I know that the qrCodeObject has a property corners which incorporates the top right, top left, bottom right and bottom left points of the QR code detected.
My question is now: how can I apply those corner points to the "border" view to make this border to have the same perspective as the QR code? Or in other words: how to "transform" the view according to the corner points?
Thanks a lot in advance!
UPDATE:
Here you can see the problem: the red box is a UIView, having it's frame property set to the QR codes bounds property. This misses perspective. I would like to transform the UIView (the red box) to following the corners property of the QR code, which includes the top right, top left, bottom right and bottom left points (CGPoint) of the QR code. It is important to apply this to a UIView, because I later want to apply it to an ImageView. Also a mask is not usable, as it just hides part of the view, but does not stretch or transform the content of the view.
I found a solution: AGGeometryKit did the trick: https://github.com/hfossli/AGGeometryKit/
Thanks everybody for helping!
You can't transform a CGRect that way, as far as I know. (At least I'm unaware of any framework that can do that kind of image processing.)
What you can do is to draw a polygon using the points of the qrCodeObject.
In drawRect of your UIView, change use CGContext and CGPath to draw the path you'd like.
You want your drawing UIView to be the same size as the one showing the QR code so that you don't have to translate the points onto a second coordinate space.
This answer has directions if you need more guidance on how to do that.
Ok, the problem you are facing is that a CGRect can only represent a rectangle that is not tilted or distorted. What you are dealing with is an image that has different kinds of perspective distortion.
I haven't tried to do this, but it sounds like AVFoundation gives you 4 CGPoint objects for a reason. You need to draw those 4 CGPoints using a UIBezierPath rather than trying to draw a CGRect. Simply create a bezier path that moves to the first point, then draws lines to each subsequent point, and finally, back to the first point. That will give you a quadrilateral that takes into account the distortion of your QR code.
CATransform3DRotate could be your friend, here.
https://guides.codepath.com/ios/Using-Perspective-Transforms might be a good starting point.

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

Setting the image of a UITableViewCell to a circle of a specific color

On my table view, I want to display small circles of certain colors that will provide context for the information. The circles should be in the location that the image would usually be in (the left hand side). Is there an easy way to do this? I was thinking that I could create a new image view and simply draw on it using some drawing routines. The problem is I don't know any of these drawing routines, or at least I don't know how to use them outside of a drawRect function.
Well, the easiest way would be to include the different images in your bundle and conditionally set them to the cell's imageView's image property in cellForRowAtIndexPath:.
However, if you're looking for alternative's you could subclass UITableViewCell, and use CAShapeLayers to draw them programmatically and add them to the cells layer in what ever position you want.
Here's an example of how to use CAShapeLayer to draw a circle:
iPhone Core Animation - Drawing a Circle

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.

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