How do I create a segmented circular progress bar in Swift? - ios

I wanted to create a progress bar as shown in the image:
I used the code mentioned in this blog
but I am unable to add separators and reduce the space between them.
I have managed to do like this through storyboard:
How can I change the code or is there any easier way to create?

You didn't specify what sort of animation you want on your progress indicator, but certainly achieving the drawing you've shown in your first screenshot shouldn't be any problem; I was able to throw this together in a couple of minutes:
Each thing in that drawing (other than the face) is a CAShapeLayer: the dark background circle a shape layer, the animated green circle in front of it is a shape layer, and each of the eight little lines that indicate the segments is a shape layer. So I have ten shape layers in total. They are added in that order, so that the little lines appear in front of everything else.
If the goal is to "fill" each segment in discrete steps, rather than a smooth animation through all values, that's a trivial modification of what I've already described.

Related

CALayer or other technique to actually modify the colors of layers behind, rather like clipping

Summary, in iOS how to have a view that modifies the pixels of all the views behind it.
Say you have a view, well any views, but let's consider a collection view which happens to just be some color blocks:
Say we added a view on top, CleverView, which either just blocks that view (so, white - trivial) or even "cuts a hole" in that layer (relatively easy to do, google).
No problem so far: so here's CleverView just a white square:
But what if we want to do this:
CleverView is changing all the saturation below it,
Or perhaps this:
CleverView is changing the hue or whatever below it.
Note that in the examples it's working in a pixel-wise fashion, it's not ("just") flagging each collection view cell to change all of the cell color.
So ideally CleverView would do this to anything at all that happens to be behind it (ie, whatever bunch of views it covers or partly covers, hence the collection view example which is just 'many views).
Naturally both the underneath stuff, and the shape of CleverView, can be animating, moving, in real time.
Is there a way this could be done in iOS?
(In that specific example, what I do is just, have two of the collection views: the bottom one and the top one has the new color values. Simply with care clip the top one to achieve the effect. But obviously that's not as Clever as a view that actually "modifies the values of all the pixels behind it".)
{Note too that, obviously, you can just make basically a screen shot, munge that image, and show it; not really a great solution.}
The CALayer has a property backgroundFilters where you could normally add a CIFilter that would do the job. But, documentation states that
Special Considerations This property is not supported on layers in
iOS.
That's annoying, but that's all that we have. Probably, it's due to performance considerations.
I would suggest to look into SceneKit, there the primitives are very similar to CoreAnimation, also animatable with CAAnimation, but provide advanced tools to configure and control many more aspects of the rendering.
For example, SCNNode has filters: https://developer.apple.com/documentation/scenekit/scnnode/1407949-filters?language=objc

iOS Circular Slider

I want to create a circular slider like below.
But i want two functionalities in addition.
1) I want to start the slider from any point,but in fig. it starts from 0.
2) I want to include multiple sliders in a single circular black plot.
I'm sharing the link of this project:
https://www.cocoacontrols.com/controls/circularsliderdemo
Can anyone help me to do these functionalities.
Thanks in advance.
Take a look at CAShapeLayer. You could create a path that is a full circle, and use the strokeStart and strokeEnd properties to only draw part of the circle. You could use core animation to animate between the beginning and the end.
There is an open source custom gesture recognizer on Github that is a one finger gesture recognizer. That would be a good start for detecting and responding to the twirl gesture that such a control would need. EDIT: It's called KTOneFingerRotationGestureRecognizer (link)
Those are some ideas to help get you started.
I have a project on github called iOS-CAAnimation-group-demo That includes a "clock wipe" animation. The clock wipe works by setting up a shape layer as the mask layer for an image view, installing a full-circle arc that's wide enough to completely fill a rectangular area, and then animate the strokeEnd property of the shape layer to reveal/hide the image view. The clock wipe is much more complex than what you need, but it would give you the seed of what you want. You'd use a shape layer with a much thinner line width, and you would use it as a content layer, not as a mask.

How to implement alternating colours animation on iOS

I've designed a custom indicator View for my application which consists of a row of 10 circles. The indicator indicates the progress of a task and the closer the task is to finishing, the more circles are filled. I would like to add two very basic animations to this indicator and, because this is my first iOS application, I'm not sure what the best way to implement them is.
Animation 1: While the task progress information is being fetched from the server, I want each dot to change color (from black to blue) in succession.
Animation 2: Let's say I get that a task is 80% complete from the server, I want to change the color of the first 8 dots from black to green with a decreasing delay.
My question is, is it okay to implement these animations in drawRect: or is there a more standard way of implementing something like this.
Thanks!
I wouldn't use drawRect: at all for this UI. I would create the circles using a UIShapeLayer with a circle for its path, and do the animations with
animateKeyframesWithDuration:delay:options:animations:completion; this method allows you to add animations for the individual circles (using addKeyframeWithRelativeStartTime:relativeDuration:animations:) with whatever delay and relative duration you need between the keyframes.

masking a background colour over the transparent region of a UIImage in objective C

Im a little bit lost on how to go about this, im really looking for the theory behind it im not 100% sure if the title is correct or not.
Im currently working on a iOS app and im a little stuck with the progress indicator thats been designed ive attached a image of it below
as you can see when the user progresses through the stages of the challenge the background of this image fills up with white so if they are in stage 1 of a 5 stage challenge its filled 20% stage 2 40% etc.
the issue I have is im not 100% sure how to go about this, if I was doing this in HTML i would create the image with the green background and leave the area for the rabbit and shape transparent and then create a div behind it that would change its height.
should I be applying the same principle to iOS development or should I be building it in a more programatic and efficient way.
thanks all for your help
The solution you are talking about sounds fine. Many programmatic solutions would involve masking and would probably be less performant (masking is actually quite expensive), other programatic solutions involve stroking different vector paths but that would get complicated if you want to cut them all of a the same line.
So, translating your idea into views. Create a container UIView with a light green background, and add to it a white UIView and an UIImageView (in that order to get the image on top). The image view would have the green image with transparency set as its image. The white view would start of being positioned below the light green view (have a frame with a higher y value) and as the stages progress you simply shift the white view upward by modifying it's center or frame properties. (note that y increases downwards).
This may be a childish way
Make an UIImageView and add that in your view where you place your rabbit view.
Make the width and x axis value as same of your rabbit view and change the height and y-axis value as the stages completes.
Add the rabbit view above your imageview.
In this way you can have not only color of your progress you can even assign a image in future to show the progress of the different changes.
-(void)completedStage:(int)stage
{
CGRect frame=rabbitimage.frame;
bgimageview.frame= CGRectMake(rect.orgin.x,rect.frame.orgin.y+rect.frame.size.height-stage*0.2,rect.frame.size.width,rect.frame.size.height-0*2)
}
Hope this helps !!!

How to apply 3d perspective transform only in one part of compound UIView?

I have UIView with UIImageViews, UILabels, UITextView.
My goal is to transform the middle part so it would look like folding a piece of paper:
- top and bottom parts remain the same only they slide towards eachother
- middle part folds towards the screen
(as in Clear app: http://blog.massivehealth.com/post/18563684407/clear?cbe4fc38)
My idea was to first load whole view, then split into 4 parts, make middle two parts into CGImage and somehow animate them with perspective while simultaneously transforming top and bottom parts, so they slide towards eachother (in the end, middle two parts should become invisible).
I also should be able to unfold this view and scroll UITextView.
I'm not looking for a ready-to-go answer, just pointers towards correct solution.
I have came across CALayer, CABasicAnimation and CGImage, but yet don't know how to solve this one.
I think your approach is sound. Since you cannot apply a transform to part of a view, you have to split your container view into separate parts. You can use the CALayer method renderInContext: to render a view into a static image. You can then split this image into the parts you need, place the image parts over the original view (or replace the view with the image) and animate the images. When the animation has finished, reinstate the view in its new form.
A few pointers:
convert your UIView into an image: see this post; either you take 4 "snapshots" of your view, or:
1.2 you take one, then crop the resulting image (see here for cropping);
create a new view and add 4 CALayers as sublayers of self.layer; each layer has its contents property set to the corresponding UIImage;
animate the view layers as you need; have a look at this file from the Leaves framework to see how this could be done; basically, this code uses a CATransaction and transformations to animate a property of the layers (which in this case represents the position of one layer respect another), so that when that property value changes, the layers are redrawn accordingly.
Hope it helps.

Resources