I have a UIView that I draw a CGPath to and would like to draw an overlay onto the entire view itself, one z level above the rendered CGPath.
How is this done? Should I use a layer? I would like to draw or fill parts of the view repeatedly, so I am not sure if it might be better to use some kind of fill method. Is there a more efficient way to fill parts of the view other than drawing a new path?
I want to create the effect similar to a progress bar, extending the overlays width during runtime depending on a value.
You could use a subview (or, similarly, a sub-layer) for this. A subview of a view will appear above the content rendered in drawRect:.
If you can get away with using a UIImage background (say, one created with resizableImageWithCapInsets:), and simply changing the size of that view over time, it will likely be more efficient than redrawing in drawRect:.
Related
I am exploring the idea of drawing some custom primitives (using CGContext) on a view that is scrollable and larger than the phone screen width.
The idea would be to use the "power" of a UIScrollView by programmatically scrolling the content of the view as the content is added and decouple in this way the scrolling handling (and general UI interaction with the view) from the content drawing.
Is this a feasible approach in iOS?
Yes it is. The easiest approach AFAIK would be to add a UIView onto the UIScrollView. You would then draw on that UIView instance - after drawing another part of your graph/image you would need to inform the containing scroll view, via a delegate for example, that it needs to update its contentSize. This would of course be the size of the UIView upon which you drew. The update is needed, beacuse it seems that you may need to increase your drawing area size as you do it.
I wonder what the best way to create a horizontal line is?
I have a few labels / text and I would like to add a horizontal line between them. More or less like a when using twitter bootstrap.
Right now I am using a UIview and setting it as 1 in height with a black background color. But I guess this isnt the best way to do it?
That is the way to do it in iOS. UIView is the class which represent something to be shown on the screen. Every UI component is direct or indirect descendant of UIView. So, you should use UIView.
UIView is backed by CALayer to render the content to screen. You could also use CALayer, CAShapeLayer or other layer classes to create a border. But, I would not recommend to use CALayer just to show a border as it is simpler to use UIView with height of 1, on the top of that, you get some nice addition such as autolayout. If you use CALayer, you will have to set frame to layer at appropriate time when the view bounds change. It could also be tricky due to some intrinsic animation within CALayer.
Okay... so I am getting the hang of iOS, have created a UIView with a combination of widgets (buttons, UITableViews) content and some rendering in drawRect.
The rendering is actually to draw a rounded rectangle within the UIView frame, with circular corners. Then I add this view to my main view.
In the rotation animation, I change the position and aspect ratio of my UIView and called a layout method, and was pleased that it would smoothly change its shape and reposition its contents.... EXCEPT: something odd happens to my rendering... they sort of get squished, and my rounded corners are now elliptical/squished (even though the rendering code always makes circles) like the UIView applies a transform after the drawRect, but does;t re-render.
This is a very surprising effect, can someone give me a hint to what may be going on? I want the rendering to be consistent and sensitive to the current rectangle.
EDIT: Added pictures. The UIView onDraw renders framing and headers, and there are two UITableViews as children. It starts up in portrait mode (figure 1) and looks fine. When the parent view rotates I initiate an animation that changes the sizing of the subview to be suitable to landscape. The sub UITableViews resize fine, but the rendering is now squished (Figure 2).
You need to set the contentMode of your UIView to Redraw
I am trying to create a view to implicate a swiping feature in a table view like the picture below.
I just want to curve one side of a view in equally to imply a swiping gesture. Is this easy to do in code? Or is it better to mask an image over the view? Please suggest.
Subclass UIView, implement the drawRect: method and do that shape (either by drawing to the context, or by using a bezierPath).
Make sure you set the view to opaque, and the backgroundColor to clearColor.
I have a UIView subclass object that animates and therefore changes its position over time as a subview in my UIViewController's view. Actually my moving UIView subclass is just an image of a ball and it's moving as if it was hanging down from my devices screens top border. But to be a real pendulum I'd like to also draw a line between my ball and the CGPoint it hangs down from on top of my screen.
My idea was to just draw a line every time the UIView changes its position. But as the moving is done within an iOS API (I'm just calling something like [myBallView swing]) I can't do this at the same place the movement is happening. I'm actually not animating the view myself.
The only solution I have in my mind to solve my issue is pretty bad: subclassing UIView, adding it as a superview to my moving UIView and adding a line every time drawRect is called. But I'm not even sure drawRect is going to be called there. Either way, there must be a better solution for this.
Does anyone know a good solution to my problem?
Making a custom subclass of UIView as the superview is reasonable.
However, rather than drawing the line yourself, I would suggest implementing +layerClass in your custom view, and making the backing layer a CAShapeLayer.
Then you can create a CGPath in the view's shape layer that is a line, and manipulate the start and end points of the line when your other view's center moves. Shape layers are designed to draw as part of the screen update process, and you could even make the change animate by changing the endpoints of the path with a CABasicAnimation.