Resizing CAShapeLayer - objective-c

I have a simple test app on which my rootViewController's UIView contains a bunch of UIView subviews. Each one of those UIView subview is backed by a CAShapeLayer.
I want the composition created by those subviews ( the four shapes that are within the dotted area .. ) to always stay vertically and horizontally centered with respect to my
UIWindow. (the minimium size of the left/right, top/bottom margins will be subject to be changed at runtime at each orientation change )
So for example when i rotate to portrait i will have to
resize and reposition those single shapes so that the whole figure will be mantained centered and each CAShapeLayer sublayer stays sharp ( i want their path to be resized not just a raster resize )
what would be the best technique to resize/move the shapes to always have a centered composition while maintaining path crisp appearance for the shapes?
Ultimately for me it will be good to have an answer to this: how can i shrink the subviews as a whole? i mean their sizes and relative positions?
Thanks

You can use CGPathCreateMutableCopyByTransformingPath() or -[UIBezierPath applyTransform:] to recalculate all points in the path.

Related

Completely transparent UIButton with irregular hit area

I know how to use a background image with alpha channel to create a UIButton with an irregular tap area. But with this solution, only the ignore-tap area is transparent; the tap area consists of the opaque.
What I want is a totally transparent UIButton, with an irregular tap area. (It triggers an animation behind the button.)
It seems that some sort of extra UILayer with some hit-testing could work, but I don't quite see how. Suggestions welcome.
Here's my solution. The problem: A UIImageView (call it the base view) to which I want to attach an irregularly-shaped tap area. The area corresponds to something in the image, let's call it a river. It could be a non-connected region.
In the Finder, duplicate the view's image, and make all the non-river pixels transparent, using your favorite graphics app. Call this the mask image.
When the base view is tapped, check to see if the corresponding pixel in the mask image is or is not transparent. (Solution left to reader; examples abound.)
So the mask image is never actually rendered, it is just used as a reference.
Note that if the base view gets resized or moved around (as it does in my app, via animating its constraints) then you have to "move" the mask image too, or in some other way manage the coordinate translation between view and mask. The easiest way to do this is to make the mask image a hidden subview of the base view, with its left, top, leading and trailing anchors constrained to be equal to those of the base view. Then they move around together, and the coord translation between the two is the identity.
I wrapped all this up in a subclass of UIImageView so that it manages its own mask, and calls a delegate if the "river" (or whatever) is tapped.

OS X chat app with resizable bubbles

I'm building chat application for Mac OS, similar to iMessage. I wonder, how can I implement resizable text views in bubbles. I mean, when I resize chat window bubbles with text will resize to. Any ideas, links will be very useful. Thank you for help)
For text resizing, you use auto layout. If you have an NSScrollView containing MYBubbleViews containing NSTextViews, you can add NSLayoutConstraints using the leftAnchor and rightAnchor properties of the scroll view's content view and those of the bubble view, and add constraints between all edges of the text view and bubble view. Then pin the bubble views to the top/prev view.
Also make sure you set the NSTextView to wrap. The width of the intrinsic size of the text view will be set so that it fills the width and the intrinsic height will be set to fit the whole text.
I previously thought it was about drawing the bubbles, so I first gave this answer:
If you look at Messages.app, you'll see that they're not circular bubbles. They are basically composed of several shapes overlaid on each other. A rectangle with rounded corners, plus a bezier path of the tip.
So you should be able to take a NSTextView for the text, make it a subview of a custom view that draws a rounded rectangle and the tip in its drawRect method, and then use auto layout constraints to make your bubble view resize with the text view and the text view to the window width.
You could probably also have the bubble view host a CALayer with fill and rounded corners, plus one with an image for the tip (or aCAShapeLayer for the tip), but drawRect is the easier approach.

Keep text on an image readable while rotating the image

I have an image view that looks like a wheel. This view detects touch events on each of the colored sections.
The problem I have is that when I rotate this wheel, the UILabels on top of the view need to also be rotated so that the text is still horizontal and human readable.
What is the best way to rotate the labels while the parent view is being rotated?
This is what I am trying now and it does not rotate correctly...
CGAffineTransform textTransform = CGAffineTransformRotate(newTransform, newAngle * -1);
Presumably you are applying a rotation transform to rotate the wheel. If the labels are subviews of the wheel view, their centers are pinned in the right places to the wheel (because a view is located in its superview by its center), and they will travel around with it. At the same time, apply the inverse rotation transform to the labels. The rotation takes place around the center of each label. So each label stays in the right place and stays upright.
An afterthought - also make sure you're not using autolayout on these labels. Autolayout breaks view transforms.

cache drawing in a uiview

I have a UIView that allows the user to draw a line (myLine) on the screen. This UIView is directly above another UIView that has several shapes drawn with CGPaths. When the user taps on one of these shapes I need to erase any portion of myLine that is above one of these other shapes as if I was erasing the pixels with an eraser.
What would be the best way to approach this?
I need the light blue part of the line to be erased leaving the dark blue portion
1) (current approach partially works) I'm able to use the path shape from the bottom view as a mask in the top view but it is only masking the UIView. If I later need to change the mask location the vector strokes are still there. (I know this is because all off my lines are being redrawn in the drawrect of the view)
2) After I draw each line should I somehow cache the drawing as an image and THEN
slice out the parts inside the triangle?
3)Is there a better approach to this?
This link provided the answer:
Building a Simple Drawing App
I cache the drawing to a bitmap context and then clip out
the unneeded parts of the bitmap.

Rounded corners on NSTableView

I have a custom view subclass similar to NSBox that draws a rounded box background. The problem is that if I place a view like an NSTableView in the box view, it does not clip to the rounded corners. Is there any way to round the corners of NSTableView and its parent scroll view?
I haven't tried this with a table view but have with other controls.
In a subclass of NSTableView (or whatever view/control you want to clip)
Override drawRect:
Create an NSBezierPath with the shape you want (probably appendBezierPathWithRoundedRect:xRadius:yRadius: just remember to use the view's bounds as the size)
Send the path the addClip message to add that shape to the view's clipping path
Call super's drawRect:
If the table view has a header you may need to clip the top corners by subclassing NSTableHeaderView. And if you have scrollbars you may have to do the same thing to them except only clip certain corners. Hopefully you don't have scrollbars because I doubt that would look right. Basically you want to clip the view/control that draws that part, clipping the parent will not cause subviews to be clipped.
If you look at Apple's Welcome to Xcode window they get away with it by drawing a custom header at the top and a text block at the bottom so they don't have to round the table view itself. If you can do something like that I would.