4

DrawInRect Behavior with the UIView Rotation Transform

 3 years ago
source link: https://www.codesd.com/item/drawinrect-behavior-with-the-uiview-rotation-transform.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

DrawInRect Behavior with the UIView Rotation Transform

advertisements

I have a problem understanding how the parameter passed to the drawInRect method is defined when a rotation transformation is performed on a UIView.

To give an example I have a UIView which I rotated with an angle of 307 degree. In the drawInRect method I log the following: self.frame: {{103.932, 273.254}, {64.3007, 84.3374}} rect (the variable passed as parameter:{{0, 0.102913}, {18, 89}}

The problem is that according to the documentation I should not draw outside of rect, but considering what I should draw, there is no way my images will fit there.

Can anyone explain to me how I am supposed to use drawInRect in the case my UIView is rotated ?


To give more detail about my problem, here is what I do:

I have a scrollview with a contentView inside (subclassed). I add my UIViews in the content view.

The views in question are composed of a handler image (bottom left) and the main image (top right). Users are supposed to grab the view by pressing the handler but that's not the point.

The drawInRect method of the UIView contains the following:

[_image drawInRect:CGRectMake(handlerSize.width, 0, _image.size.width, _image.size.height)];
CGSize size = CGSizeMake(kHandPickerWidth/self.scrollViewScale, kHandPickerHeight/self.scrollViewScale);
[_handPickerImage drawInRect:(0, _image.size.height, size.width, size.height)];

The UIViews objects are added at viewWillAppear in the content view doing the following:

first instanciate,

then addSubview:

then I set the scrollViewScale parameter,

then I set the frame parameter (according to the top right image displayed (which may vary)

then I rotate the UIView.

Starting from line three, the code is executed from the

- (void)scrollViewDidZoom:(UIScrollView *)scrollView

to make sure every variable is set properly when displayed is needed.

The line defining the size variable is to adjust the marker's size no mater the zoomScale value of the scroll view.


You basically just draw as you would normally, and the painting will be rotated by iOS for you. You can get this transformation information if you would want to.

You need to get a reference to the currect graphics context:

CGContextRef ctx = UIGraphicsGetCurrentContext();

Then query the transformation matrix directly:

CGAffineTransform tf = CGContextGetCTM(ctx);
NSLog(@"current ctm: %@",NSStringFromCGAffineTransform(tf));

or better, get the transfrom from your drawing function to the device:

CGAffineTransform tf = CGContextGetUserSpaceToDeviceSpaceTransform(ctx);
NSLog(@"user->device transform: %@",NSStringFromCGAffineTransform(tf));

And in drawRect: you should not rely too much on the passed CGRect, because it serves mostly as a hint to what piece of the view needs updating. (e.g. because you called -setNeedsDisplayInRect: on it). To get the actual bounds where your view lives in, use self.bounds.

Drawing outside of the CGRect is no real problem, but will only hurt performance a little.

edit ps. to clarify: self.frame is the frame of your view in the parent view coordinate system. It changes if you move, rotate or otherwise transform the view. self.bounds is the frame of your view in its own coordinate system, and (therefore) remains constant under changes of position or transformations.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK