iOS animation - window view (end of 3)

This article is the third in a series.

Friends who have read the previous article already know that "view" in the title refers to view and "window" refers to view view.mask , the window view chapter is combing mask and mask animation. If you are not familiar with iOS mask, it is recommended to take a look first Part I.

In the first two articles, we introduced some usage of mask and mask animation.

As the end of this article, let's achieve an effect to practice,
With this effect, we can recall a simple truth: complex effects can be equivalent to the combination of simple effects.

1, Effect

The effect is shown in the figure below:

We intercept a representative frame, as shown in the following figure:

As you can see from the figure, waves are composed of two colors, each part of which has different colors.

This effect seems a little complicated. If you are not familiar with mask, you may not have any idea for a while.
But friends who have read the first two articles may have been thinking secretly, is the window moving? Or is the scene moving? Will there be multiple windows?

Next, let's look at the principle through a simple effect.

Note: the realization of wave animation has little to do with this article, which will not be covered in this article.
There are mature wave animation tutorials on the Internet, and the WaveView class in this demo also has brief comments.

1, A simple effect

The effect is as follows:

As you can see from the picture, part of a black-and-white picture is colored.
Of course, we can achieve this effect through image processing, but in this article, we still use mask to achieve it.

Let's recall a picture in the previous article:

By adding a circle mask to frontView, the effect in the figure is formed.

Some friends may have thought that changing the backView image in the figure above to the same black-and-white image as frontView is the effect of this example, as shown in the figure below:

In other words, the effect looks like part of the black-and-white picture has turned into color,
But in fact, only two pictures with the same content are overlapped. Black and white pictures are in the back, color pictures are in the front, and the color pictures in the front are imposed with a circular mask.

This effect is very simple, but it can make us realize one thing: it looks like a picture, but it may be a combination of multiple pictures.

In this case, in the wave animation of this paper, are the waves with different colors only a wave?

Yes, the waves in this example are also composed of multiple waves. Next, let's take a look at them in detail.

2, Combination of multiple scenes

Like the effect of overlapping black and white and color pictures, multi-color waves are also composed of a set of overlapping wave view s.

There is only one color for each layer of view. The wave animation of each layer of view is the same. For each frame, all waves are completely coincident.

Each wave view has its own mask. Under the control of the masks, each wave view only shows a part of the wave. The multi-color wave we see is the combination of the visible parts of each wave view.

Let's take two layers for illustration, as shown in the figure below:

It can be seen from the figure that the red wave view with white background has a top semicircle mask and the blue wave view with black background has a bottom semicircle mask. The wave progress of the two views is exactly the same, and the combination becomes the most right effect.

After breaking the window paper, the principle is so simple.

Knowing the principle, you can actually do it yourself to achieve the effect,
Of course, if we are not in a hurry, let's go through the process together.

3, Create a 4-tier view

This step is very simple. Create a completely consistent 4-layer view of the frame. In this example, WaveView is used as the view,
Set different background colors (black, white) and wave colors (red, blue) as needed.

After this step, the wave view of the 4th floor is as shown in the figure:

The schematic codes are as follows:

// A3WaveViewController
private func addSubViews() {
    // Upper semicircle view
    // Upper and lower semicircle view
    // Bottom half circle view
    // Bottom small semicircle view

4, Set mask for the 4-tier view

This step is to make the right mask.
In this example, HalfCircleView is used as the mask, and two large semicircles and two small semicircles are set for each layer view.

After this step, under the influence of mask, the 4-layer view is as shown in the following figure. You can compare it with the 4 views in the previous figure:

The schematic codes are as follows:

// A3WaveViewController
private func makeLayout() {
    // Set the mask of 4 view s
    // Great upper semicircle
    let width: CGFloat = 200
    let marginX = (UIScreen.main.bounds.width - width) / 2
    bigTopView.frame = CGRect(x: marginX, y: 200, width: width, height: 200)
    // Big top semicircle mask
    let bigTopMask = HalfCircleView()
    bigTopMask.part = .top
    bigTopMask.frame = CGRect(x: 0, y: 0, width: bigTopView.bounds.width, height: bigTopView.bounds.height / 2)
    bigTopView.mask = bigTopMask
    // Small upper semicircle (radius is half of the larger semicircle)
    smallTopView.frame = bigTopView.frame
    // Small upper semicircle mask
    let smallTopMask = HalfCircleView()
    smallTopMask.part = .top
    smallTopMask.frame = CGRect(x: smallTopView.bounds.width / 4,
                                y: smallTopView.bounds.height / 4,
                                width: smallTopView.bounds.width / 2,
                                height: smallTopView.bounds.height / 4)
    smallTopView.mask = smallTopMask
    // Large lower semicircle
    bigBottomView.frame = bigTopView.frame
    // Big bottom half circle mask
    let bigBottomMask = HalfCircleView()
    bigBottomMask.part = .bottom
    bigBottomMask.frame = CGRect(x: 0,
                                 y: bigBottomView.bounds.height / 2,
                                 width: bigBottomView.bounds.width,
                                 height: bigBottomView.bounds.height / 2)
    bigBottomView.mask = bigBottomMask
    // Small lower semicircle
    smallBottomView.frame = bigBottomView.frame
    // Small bottom semicircle mask
    let smallBottomMask = HalfCircleView()
    smallBottomMask.part = .bottom
    smallBottomMask.frame = CGRect(x: smallBottomView.bounds.width / 4,
                                   y: smallBottomView.bounds.height / 2,
                                   width: smallBottomView.bounds.width / 2,
                                   height: smallBottomView.bounds.height / 4)
    smallBottomView.mask = smallBottomMask

5, Let the 4-level view perform the animation consistently

In order to make the wave animation of each layer completely consistent, we start a CADisplayLink externally to change the progress of four wave view s at the same time (as an example, when the progress is 0.5 in the previous figure).

It also realizes the effect at the beginning of this article:

The schematic codes are as follows:

// A3WaveViewController
func start() {
    if let displayLink = displayLink {
        self.displayLink = nil
        progress = 0
    // Start CADisplayLink
    let displayLink = CADisplayLink(target: WeakProxy(self), selector: #selector(work))
    displayLink.add(to: RunLoop.current, forMode: .common)
    self.displayLink = displayLink

@objc private func work() {
    if progress < 1 {
        progress += 0.0025
        progress = min(progress, 1)
    } else {
        progress = 0
    // When CADisplayLink callback, set the progress of 4 wave view s
    bigTopView.progress = progress
    bigBottomView.progress = progress
    smallTopView.progress = progress
    smallBottomView.progress = progress

So far, the effect is complete.

Of course, you can replace WaveView with your own animated view, change the number of views, use other mask s, etc,
To achieve the splicing effect you want.

Of course, the performance of this animation method is not evaluated and may not be suitable for use in production environment.
This example is more to remind you of a simple truth:

Complex animation can be equivalent to the combination of simple animation; as long as you still feel complex, you can continue to split.

If you want to split and don't know where to start, try this:

As long as the animation of one part is different from other parts, it can be split.

Once the simple animation is realized, the complex animation will be completed when it is combined.

Combination is our common method, such as the double waves in the following figure:

Of course, we can write a double wave class directly, but we can also combine two wave view s to form a double wave.

The combination looks a bit silly, but it also has its advantages,
For example, when we want to reuse the source code with complex effect and hard to rewrite, or we don't have the source code with the effect at all, combination may be the simplest way.


This series only shows the common mask effect. After all, the window is infinite, the scene is infinite, the combination is infinite, and the effect is infinite.

If you find interesting mask animations, please leave a message in the comment area and hope we can make progress together.

All examples in this article are shown in GitHub Library There is complete code in it.

This is the end of the series. Thank you for reading.


Tags: Swift iOS github Windows

Posted on Sat, 27 Jun 2020 22:30:29 -0400 by varghesedxb