UIInterpolatingMotionEffect works randomly

I am adding UIInterpolatingMotionEffect to some views in a UITableViewCell as follows:

 UIInterpolatingMotionEffect *horizontalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; UIInterpolatingMotionEffect *verticalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; horizontalEffect.minimumRelativeValue = @(-horizontal); horizontalEffect.maximumRelativeValue = @(horizontal); verticalEffect.minimumRelativeValue = @(-vertical); verticalEffect.maximumRelativeValue = @(vertical); UIMotionEffectGroup *effectsGroup = [UIMotionEffectGroup new]; effectsGroup.motionEffects = @[horizontalEffect, verticalEffect]; [view addMotionEffect:effectsGroup]; 

The problem is that the effect only appears randomly when some representations get the effect and some don't. After clicking the view controller and return, some others work, and some others do not.

Is there something I am missing? Should the effect be applied every time a cell is reused?

+6
source share
3 answers

I had the same problem. I fixed it by causing all cells to be redrawn - using reloadSections: withRowAnimation: will most likely work for most people (or a similar method), although for me I ended up having to write my own cells and code reuse, which allowed me to save link to each created cell in a mutable array, and then clear that array and build from scratch whenever I want. Hope this helps.

0
source

UPDATE: I had to completely delete my previous answer, because I finally found a better solution.

It seems that iOS7 / 8 will ruin the effects of the movement of the views inside the table / collection views when the cell is redrawn / deleted. You must make sure that your motion effect is tuned / updated after the cell has been deleted / tuned.

To do this correctly, you need to move the motion logic to the -layoutSubviews method. Then just send the message [self setNeedsLayout] to your constructor and the methods that you use to update the contents of the cell after deleting and updating the cell.

This solved the problem completely for me.

0
source

Using UICollectionView , I ran into the same problem. After clicking on the new controller, and then back to the UICollectionView , some of my UIInterpolatingMotionEffect cells stopped working, but were still specified in the motionEffects .

Solution: I called to configure the motion effects in -layoutSubviews , and whenever I set up the cell, I called -setNeedsLayout to ensure that -layoutSubviews was called.

In addition, every time I adjust the motion effects, I would delete the previous motion effects. That was the key.

Here is the method I called in -layoutSubviews :

 - (void)applyInterpolatingMotionEffectToView:(UIView *)view withParallaxLimit:(CGFloat)limit { NSArray *effects = view.motionEffects; for (UIMotionEffect *motionEffect in effects) { [view removeMotionEffect:motionEffect]; } UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.x" type: UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; effectX.minimumRelativeValue = @(-limit); effectX.maximumRelativeValue = @(limit); UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.y" type: UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; effectY.minimumRelativeValue = @(-limit); effectY.maximumRelativeValue = @(limit); [view addMotionEffect: effectX]; [view addMotionEffect: effectY]; } 

Hope this helps! Also works on iOS 9.

0
source

Source: https://habr.com/ru/post/955770/


All Articles