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.
Related
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.
My ImageView rotates but while it rotates it doesn't recognize touches on itself.
Do you think it's okay if I create a button via code that's over the ImageView that recognizes the touch?
When an animation is applied on any UIView or any subclass object of a UIView like UIImageView, UIButton etc then it does not detect touch events because when an animation is applied to a view, the animated property changes to its end value right away. what you are actually seeing on screen is the presentation layer of your views layer.
To answer your question, Yes, you can make a UIButton that covers up the area of the UIImageView to detect touch events on it. That sounds like the easiest to implement option in this case.
Apart from that, this link may also help you in the process. Hit testing animating layers
I am trying to create a custom iOS 7 Transition. At present I have a simple circle view like this:
I have a gesture recogniser on the custom view. When clicked the custom transition delegate is called
`-[CCZTTransitionDelegate animationControllerForPresentedController:presentingController:sourceController:]`
Which in turn calls the two methods on the transition animating class:
-[CCZTAnimatedTransitioning transitionDuration:]
-[CCZTAnimatedTransitioning animateTransition:]
At present I have just made the second controller zoom in and that is all working fine...
Desired Effect
What I would like to do when the circle is tapped is
1. have the circle increase in size until the screen is completed covered with its color.
2. Fade the second controller in
What is the best way to complete step 1? Can this be completed in the transition delegate/transition animating methods?
In this method - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext it looks like I have access to the view controllers but not the subview. Should the animation be done before somehow if so how?
Note: In time there will eventually be a group of the circles not just one.
EDIT:
It is also important to note that I am actually trying to zoom in from the center of the circle. So if the circle is positioned elsewhere (i.e. when there are more) the circle should zoom in/increase in size from its own center point.
Try using a CGAffineTransformScale animation on the circle view and expand it to fill the entire view. Once that is done scaling up (either through the UIView animation completion block or by using UIViewKeyFrameAnimation), present your next view controller behind the filled in view. Once presented, fade out the view to reveal the newly presented view controller by alpha-ing down the view in an animation block.
I have been looking to all the other similar topics here, using UIGestureRecognizers, using hitTest:withEvent, pointInside:withEvent: etc. but nothing seems to be ok for what I need to achieve.
Basically I have a main view (self.view of a common UIViewController) and a small rectangular UIScrollView attached onto it at the bottom: the scrollView is filled with some UIImageViews and the user can scroll it as usual.
But the user should also be able to drag one UIImageView (or a copy of it) from the UIScrollView to the main view, and, this is what I am finding really difficult, with the SAME dragging gesture, hence I need a way to:
1) Distinguish between normal horizontal scrolling gesture, which should be handled by the UIScrollView the usual way and a dragging gesture over the image view.
2) Once identified a dragging gesture, should propagate the touch to the superview, which will host a copy of the UIImageView and WITH the SAME dragging gesture continue the dragging over the main view even out of the bounds of the UIScrollView.
Please note that I know that if the UIScrollView has userInteractionEnabled = NO the touch is propagated to the subviews, but 1) I want to propagate it to the superview not the subviews, 2) the userInteractionEnabled property apparently becomes active only once the initial gesture is terminated, while I need to use a single dragging gesture.
Thank you very much for any help.
So, so far I have ended up implementing the touchesShouldBegin:withEvent:inContentView: method of my UIScrollView subclass but with delayContentTouches set to YES (default) instead of NO as #nhahtdh was suggesting.
Strangely enough even only implementing the method was sufficient for my subviews to intercept the dragging, and still my scrollview is scrolling properly, while with delayContentTouches set to NO I was not able to scroll it as all the subviews were starting to move around.
Really the credit for this is #nhahtdh, so man, if you post an answer I will accept it, thank you very much for your help.
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!