How to delay flipping a UIView containing an updating UIButton having a gradient background - uiview

I have two views that flip based on a button press within the view. The view has two CAGradientLayers as sublayers. If I flip immediately after the action method fires, the button is in the process of changing the opacity of the gradients and so you see stuttering (the UIVIew flip animation is having to accommodate the button that is itself changing.)
I can hack a solution by doing a performWithSelection:withObject:afterDelay:0.1f, but it feels like such a hack. I tried setting the layer's needsDisplay property and testing for when it was clears, but probably this is insufficient to tell me the screen itself has redrawn.
Dav

In the end this has no solution. I have since found that when animating a view there are severe performance implication if you also try to animate the super views. You can see this in many iOS apps where the app animates an image in a scrolling list - the scrolling stumbles.
So what I learned is either animate something, or it's view, but not both!

Related

UIScrollView is using an unrelated UIViewPropertyAnimator when it shouldn't

I'm using a UIScrollView whose content is a simple UIView subclass whose size is set using auto layout and which uses drawRect: to render its content rather than having subviews of its own.
If the content (and the size) of the UIView changes then everything works as intended. The new content instantly appears and the scrollability of the UIScrollView enables/disables if the size of the content now needs / no longer needs scrolling.
However, if there's an animation going on somewhere else on the screen things no longer work as intended.
In that case the change to the UIView is animated along with that other animation.
So if that other animation takes say, 2 seconds, the new UIView content is instantly redrawn but at a scale so that it fits in the old content's size. Then it animates the content, growing (or shrinking) over a period of 2 seconds so that at the end of the animation its size is what it should be.
The "interfering" animator in question is owned by a ViewController quite a bit further up in the food chain and the UIScrollView and its content UIView are never told about the UIViewPropertyAnimator.
The problem only happens if the content change overlaps the animation. If that other animation has completed (or hasn't started yet) the content in the scroll view is updated instantly.
Does anyone have insight into this, or perhaps could suggest a way to force UIScrollView and/or its content view to always do their own thing and not tag along for the ride if some unrelated UIViewPropertyAnimator is chugging along elsewhere?
EDIT: A bit of extra info
The animation code is older and originally made use of UIView.Animate and some swipe gestures were triggering the animation. In that case even if the animation and the content size change overlap (using the exact same repro scenario), the new (scrolled content) size appears immediately and doesn't get linked to the UIView.Animate animation. Swapping in UIViewPropertyAnimator code (and without any gesture recognizers getting involved) the problem is triggered and content size change becomes animated.

Animated UIWebView does not respond to touches during animation

At the moment, I'm animating a UIWebView from the bottom of the screen to the top. As the UIWebView animates upwards it becomes untouchable for 50-80% of the duration time.
If I tap the UIWebviews ending destination, or model layer, the taps are registered and the Webview responds appropriately.
Why is this? And what solutions are there for tapping moving/animating UIWebViews?
To further exemplify this, I have created a side project that shows a UIWebView animating upwards. The purple squares represent touch events on the presentation layer, while the blue squares represent touch events outside of the presentation layer.
https://github.com/AdamBCo/UIWebView-Animation-Issues
As seen in the example, UIViewAnimationOptionAllowUserInteraction is set in the UViewAnimation block.
A UIWebView is complicated layout of web elements. To redraw that during animation there is simply not enough time available to entirely redraw the UIWebView, keep the controls in it available for interaction and do the animation.
However there are some settings for this inside a CALayer on what to do with its contents when animating it. I would start looking into that.

Moving UIView and subviews periodically

I am building a word tetris kind of an app. Now I have to move a Uiview containing 8 uibuttons towards the bottom of the screen based on time and also track the position of uibuttons as the user taps specified button.
Am I suppose to use Block based animation or core animation to do the task.
Currently if I am animating frame and center of superview it seems like I have to do the same for the subviews as well inside the block.
Any input would be handy.
You can use UIView block animation to animate a view and it's subviews quite simply.
However, neither UIView animation nor core animation will let the user click on buttons as they are animating. Button actions don't work at all on "in flight" animations. There's no automatic way to do that. (At least none that I know of.)
Instead, you have to add a tap gesture recognizer to the parent view, and do hit testing on the presentation layer of your parent view to see which sublayer of the presentation layer is tapped.

Fast custom animation using CADisplayLink causes stroboscopic effect. How to avoid it?

Scenario:
Horizontally scrolling UIScrollView with reused page views (so that there are only few page viewcontrollers which are being reused similar way like UITableView cells). So that they are able to be updated with new content and reused I need to know exact position of UIScrollView's content view (offset). This works great.
Now I need to implement custom scrolling animation - I mean to programatically move the content view, so that user touches some buttons, and the scroll view scrolls to desired position with this custom animation. The movement can be very quick and very far. I can not use Core Animation for this, as I could not track position during animation (CA reports you only start and end of the movement). So I decided to use CADisplayLink, and calculate each UIScrollView content for each position. This works great too.
The only problem is, that sometimes I see stroboscopic effect - say I am moving the content to the right, and it looks like it is moving to left. If I look at builtin animation within UISCrollView using setContentOffset:animated:, the animation is smooth and nice. Does anyone know, how to get rid of this stroboscopic effect?
Most likely your issue is that timestamp is a double and you're assigning it to a float
Floats have 7 digits while Doubles have 15-16 digits.
So in other words you're experiencing data loss. By using double you should see a silky smooth animation.

Fade UIImageView as it approaches the edges of a UIScrollView

I have a UIScrollView over an image at the bottom of my app that acts as a dock with icons that can be scrolled through horizontally. Instead of the harsh edges of the UIScrollView, I would like the icons to fade out for a more aesthetically pleasing look. Being new to iOS development, I don't know if either of these would be valid options:
Create a faded image to use as an overlay on the scrollview so the
icons only appear through the visible portion.
Actually change the
alpha of the images based on their distance from the center (or from
each edge).
I suspect the first idea would be the most simple, but I'd like to throw this out there for any other ideas.
Note: I did see this tutorial, however that technique assumes that the background is a solid color. If I were to do it programatically, I would probably need to fade the individual images.
You can definitely implement something along the lines of #2. It'd be something similar to what the tutorial describes. The alpha transition however won't be as smooth as using the gradient layer mentioned in the tutorial or using an image since the entire icon would have the same alpha. How much discernible the difference is depends on the size of your icons. Smaller icons, very few will be able to tell the difference. Larger icons the difference would be quite clear.
You'd have to implement the
(void)scrollViewDidScroll:(UIScrollView *)scrollView
method in your scroll view's delegate class. This method will get called every time the scroll view changes the location of its content. In this method you can call its subviews and adjust their alphas as required. To optimize it a bit instead of calling the alpha adjustments on all the elements you can just update the subviews which are still partially/completely visible.
EDIT: to figure out which views to adjust you'll use the contentOffset property of the scrollView that gets passed as a parameter in the above method.

Resources