Imitation guest Brush Gift effects — code optimization

An article on the “imitation of the customer to brush the gift effect — the basic logic to achieve” in the analysis of the basic process and the realization of the brush gift code. However, there are some BUG and some of the optimization can not handle, and now we have to analyze these legacy issues. Of course, personal ability is limited, there must be a lot of I did not find the problem, if you have encountered in the use of other problems, we are welcome to point out that I am timely and perfect.

The optimized results are as follows:

Imitation guest Brush Gift effects --- code optimization
renderings.Png

nonsense not say, look at the problem.

One problem

Problem description

The results are as follows:

Imitation guest Brush Gift effects --- code optimization
problem a.Gif

can be seen from the chart: when a gift set of executing animation animation, then just received a gift of a new message with the same type, according to the normal logic, this new gift message should be used as a new animation group began to show. However, as can be seen from the GIF diagram, when the send button appears again, the new animation group does not begin to show up, and where is the new gift message?

Problem reason

If you hide the animation animation for a long time, repeat the above process. You will find that in fact received a gift message is not lost, but was judged to be a product of animation. So now is actually executed while hiding animation, again performing multiplication of animation, which leads to multiplication of animation were hard to see, resulting in the lost gift message received.

Problem solving

To know the cause of the problem, to solve the problem is very simple. The solution here is to let cell not be judged to be performing an animation while executing a hidden animation, so I set up a couple of animations for the cell, as shown in the following figure:

.Png animation state logic Imitation guest Brush Gift effects --- code optimization

has a state of animation, the animation can only be used to determine the conditions of the judge, the modified code is as follows:

- (PresentViewCell) examinePresentingCell: (id< PresentModelAble> obj) {for (PresentViewCell *cell in self.showCells if ([cell.sender) {isEqualToString:[obj sender]] & & [cell.giftName isEqualToString:[obj; giftName]]) {/ / currently display animation and animation is not if (cell.state! = AnimationStateNone & & cell.state! = AnimationStateHiding) return cell;} return nil};}

If the current is not idle and there is no hiding in animation, it is determined the cell can perform the multiplication of animation.
operating procedures, test again, you will find the same type when received a message cell is performing animation, the new message will be displayed in the new animation group, or a free cell in the show. (the specific effect of the modified can be verified in Demo, the same below)

Question two

Problem description

The results are as follows:

Imitation guest Brush Gift effects --- code optimization
problem two.Gif

can be seen from the chart: when repeatedly click fast with a send button, with the animation effect disappeared.

Problem reason

Obviously, the problem here because: click the last product animation is not executed, even animation begins next time, resulting in this effect.

Problem solving

From the cause of the problem is easy to think of the need to use the cache mechanism, that is, until the last animation to complete the next animation. First, we can easily think of is NSOperationQueue and dispatch_group_t, this is the two task queue system package, it is easy to achieve the above requirements, but also very simple, only shakeAnimationWithNumber: inside cache line. Here to introduce the implementation of the dispatch_group_t queue method, the code is as follows:

- (void) shakeAnimationWithNumber: (NSInteger) {if (_queue number & &!! _group) {_queue = dispatch_queue_create (com.shakeCache.queue, DISPATCH_QUEUE_SERIAL); _group = (dispatch_group_create); dispatch_group_notify (_group, dispatch_get_main_queue, dispatch_after (dispatch_time) (^{(DISPATCH_TIME_NOW, (int64_t) (3 * NSEC_PER_SEC)). Dispatch_get_main_queue ([self), ^{hiddenAnimationOfShowShake:YES];});});} dispatch_group_async (_group, _queue, ^{[self startShakeAnimationWithNumber:number completion:nil];}});

The code is very simple, is to create a global serial queue, if the group task is delay the implementation of animation, each call to add a product animation task in group.
run the program, you will find that the problem still exists, why is this? In fact, the reason is very simple, because: UIView animation is the implementation of the sub thread, and add the task is not in the same thread. Therefore, although the task is to add the order, but the implementation of the animation is not a serial execution. Here the
solution is: to achieve their own cache — even received the first animation cache, if there is a cache and not performing multiplication of animation, take cache, start animation, animation is completed to delete cache, go to the cache cache, only not so far. Specific implementation code is as follows:

- (void) shakeAnimationWithNumber: (NSInteger) number (number {if > 0) [self.caches addObject:@ (number)] if (self.caches.count; > 0; & & _state! = AnimationStateShaking) {NSInteger cache = [self.caches.firstObject integerValue] [self.caches; removeObjectAtIndex:0]; / / cannot delete the object, because it may have the same object (__weak typeof self) ws = self; [self startShakeAnimationWithNumber:cache completion:^ (BOOL finished) {[ws shakeAnimationWithNumber:-1]; / / -1 is to cache are not repeated to add}];}}

Run the application again, you will find even the animation is serial execution.

Question three

Problem description

At the beginning of the next animation to cache, then just received a cache with the same type of news, and will go to cache. In extreme cases, this will cause two identical types of gift animations to be displayed simultaneously.
because this is a particularly extreme case of logic, so there is no renderings.

Problem reason

This problem is actually because: take the cache to the animation starts this time to remove a cache and adduction of the same type of news, cause not detected the news on animation detection, so the new message may also serve as the new animation group began to show.

Problem solving

The solution here is to take the cache to the beginning of the animation to shorten the time, that is, before the start of the animation will be displayed on the cell animation from AnimationStateNone to AnimationStateShowing.
on this issue, are interested in self testing, test to remember to increase the cache to start the animation time. The specific operation is: to increase the cell display animation time, and so on the cell display animation to complete the cell animation from AnimationStateNone to AnimationStateShowing. If you have a problem, remember to share the GIF diagram of the problem! Thanks!)

Question four

Solve a problem, will bring new problems. What are some of the new problems that come up with so many caches! I tested should have been found: even send button has been concealed, but even this is certainly still performing animation, illogical.

For this problem, only the project has required even send button to appear, but there is not necessarily a problem (reflecting off did not solve this problem), so here is not to solve this problem, if required, provided here under the idea: for display animation and animation products animation time is determined, so it is easy to calculate the time required to perform the animation group. Then each received a product animation of this time update, and the time value delivered by proxy or other forms, according to the value of even send button on the control. (of course, have realized this idea or have a better idea, convenient for you, please share me again, thank!)

A good function should be in addition to ease of use, but also should have good scalability.

extend

Because of the different needs of the project, so the requirements of the animation and animation are also the same. Here is a custom interface for this animation, the interface name is as follows:

* / * * * * @param flag custom display animation animation is a product - * / (void) customDisplayAnimationOfShowShakeAnimation: (BOOL) flag; / * * * * * @param flag custom animation is a product of animation - * / (void) customHideAnimationOfShowShakeAnimation: (BOOL) flag;

If you want to make a simple definition of the two animation, you can rewrite the cell in the custom of the two methods. It should be noted that these two methods are in the UIView package in the animation of the callback animations call, so only to modify the cell frame is enough.

The general project by demonstrating that the method of the custom cell and animation can meet the demand, if the project really need more colorful animation, you need to showAnimationWithModel:showShakeAnimation:prepare:completion: method and modified hiddenAnimationOfShowShake: method in PrentViewCell animation code.

Of course, there are other places can be extended, for example: let the gift message show only in the specified cell, such as VIP users to send gift message displayed in the specific location; can also distinguish the message display priority, such as different levels of users show the priority of the message is not the same, so these are may need to project demand. Here is not one of these needs to achieve, on the optimization of the Demo, you can click here to download.

Finally, the opening or the sentence: personal ability is limited, there must be many problems that I have found, if you have some other problems in the process of use, welcome to promptly pointed out that I am in a timely manner to improve.