UITextField editing issue - iPhone SDK - iphone

I am having an issue with my UITextFields in my iPhone app that I am hoping someone here may have seen before.
I have a few UITextField's on my screen, and when they are tapped and they keyboard appears they are covered. To overcome this, I animated the view to move up with:
-(void)moveViewUpFromValue:(float)fromOldValue toNewValue:(float)toNewValue keep:(BOOL)keep {
CABasicAnimation *theAnimation;
theAnimation=[CABasicAnimation animationWithKeyPath:#"transform.translation.y"];
theAnimation.duration=0.25;
theAnimation.repeatCount=1;
if(keep) {
[theAnimation setRemovedOnCompletion:NO];
[theAnimation setFillMode:kCAFillModeForwards];
}
theAnimation.fromValue=[NSNumber numberWithFloat:fromOldValue];
theAnimation.toValue=[NSNumber numberWithFloat:toNewValue];
[self.view.layer addAnimation:theAnimation forKey:#"animateLayer"];
}
This, visually, works great, however, when I go to edit (hold the screen down to get the magnifying glass), it doesn't appear. The interaction are is retained in the position before it moves.
Any ideas what could be going on here?
Many thanks,
Brett

This is an interesting way to animate such a thing, but not the most common one.
You're actually animating a transformation of a view - not the actual position of the view. Appearantly the magnifying glass doesn't obey the transformation (quite logical, for it would sheer, stretch and skew with the view otherwise).
So rather animate the position, i.e. self.view.frame or self.view.center (which boils down to the same thing). Furthermore I usually use [UIView beginAnimations...] etc but if your approach works, it's probably just as fine.

You've made the view appear to be in a different place, but because you haven't actually changed its position it is still effectively in the old location for things like hit testing, etc.
I would start by animating your view's center instead of its transform. This you can do with just a UIView animation instead of a CABasicAnimation. Additionally, your view will actually end up at the correct position when the animation is complete so things should work as you expect.

Related

Xcode warning: "This will cause the effect to appear broken until opacity returns to 1"

I have a prototype cell and I put a UIVisualEffectView inside its ContentView. Visual Effect View's Blur Style is Dark and Vibrancy is off. Then I set the alpha of the Visual Effect View to 0,5 using the IB.
Then on runtime, I get a warning that says:
<UIVisualEffectView ...> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.
I couldn't understand why this warning is there and how I can set this alpha property properly.
The question is what do you want to animate. If it's the effect, you cannot animate it via the alpha property. However, since iOS 9, you can animate it with setting the effect in animation block.
UIVisualEffectView* view = [[UIVisualEffectView alloc] initWithFrame:self.view.bounds];
view.effect = nil;
[UIView animateWithDuration:0.3 animations:^{
view.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
}];
Alternatively, you can animate the effect by animating the alpha of the wrapper view, as proposed in the other answers (working even on iOS 8).
If you want to animate the content of the visual effect view (the subviews), animate the contentView property instead (which you should use to add subviews of the effect view).
[UIView animateWithDuration:0.3 animations:^{
view.contentView.alpha = 1.0;
}];
So to sum up, you should never change alpha of the UIVisualEffectView itself as it's most likely not what you want.
As far as I can remember you cannot change the alpha of a visual effect view. The alpha always has to be one.
The desired effect can be achieved by setting alpha of the background color rather than the Visual Effect View. The subviews should be added to View of Visual Effect View and they are not affected by the background blur.
The Vibrancy effect must be selected in View Effect View options above.
See image:
user1179321 definetely right. According to UIVisualEffectView Documentation;
When using the UIVisualEffectView class, avoid alpha values that are
less than 1. Creating views that are partially transparent causes the
system to combine the view and all the associated subviews during an
offscreen render pass. UIVisualEffectView objects need to be combined
as part of the content they are layered on top of in order to look
correct. Setting the alpha to less than 1 on the visual effect view or
any of its superviews causes many effects to look incorrect or not
show up at all.
https://developer.apple.com/library/ios/documentation/uikit/reference/UIVisualEffectView/index.html
My solution:
Duplicate the layer behind the visual effect view. (In my case an UIImageView)
Animates the alpha value the the duplicated view. (e.g. alpha form 1 to 0, shows the blurred Image)
If u presenting viewcontroller modally, try to disable animation checkbox in segue.
You never know if the delay is long enough; so a bit of a cleaner solution is to just do the presentation in the next run loop.
dispatch_async(dispatch_get_main_queue(), ^(void){
[self presentViewController:yourPopoverr animated: YES completion: nil];
});

Stop a UIImageView from returning to its original location in a View?

I was working through a very simple Ray Wenderlich iOS "dragging" example, where 2 UIImageViews (a monkey and a banana) can be dragged around the screen. It utilizes a UIPanGestureRecognizer in the ViewController implementation file:
- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {
CGPoint translation = [recognizer translationInView:self.view];
recognizer.view.center = CGPointMake(recognizer.view.center.x + translation.x,
recognizer.view.center.y + translation.y);
[recognizer setTranslation:CGPointMake(0, 0) inView:self.view];
}
That works fine, and the monkey and banana stay at whatever position you drag them to. However, I wanted to have whichever UIImageView is clicked (touched) to become to top most view. I fooled around a little and came up with this line of code:
[self.view bringSubviewToFront:recognizer.view];
I put that in the handlePan method, and it does bring whatever image clicked on (touched) to the front, but it resets the previous image to its original location on the screen. It doesn't do that if I omit the line of code which brings the touched subview to the front.
What is it about bringing the selected subview to the front that resets the other image to its original location? How would this be prevented in a UIPanGestureRecognizer? Without going the touchesBegan, touchesEnded, etc method route?
Obviously I'm new to ios programming, but I couldn't find an answer to what is probably a simple problem. Thanks guys...any help is appreciated...
I recreated your source here. The problem is the autolayout, you will need to disable it. Because when you bring the view to front, it will apply the rules to the other view to check the position, repositioning it in the original place.
So, why it not happens while you are changing the frames ? When you are only changing frames it does not apply the autolayout rules every time you change the center of one view, it will only apply when your view container hierarchy change or when the view container frame change.
Like you told you are doing a Ray Wenderlich tutorial, I will recomend you to check the tutorial about autolayout. The material in the Ray Wenderlich site is a good starting point.
--
Just a little help to disable the auto layout, at .xib and story boards, select the view and disable the checkbox:

UIView 3D transform final frame location

I have a UIView which has an X origin that makes it off screen to the right. Then, I do a keyframe animation with CATransform3D:
[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-view.width, 0, 0)]
The problem is, after the animation completes, the view's frame is visually in the correct place, but it still thinks it's off screen, so I can't interact with it. Logging its frame property also shows that it's offscreen, but visually, it's not.
The fill mode for the animation is kCAFillModeForwards, so the final value of the animation sticks.
What is the solution to this problem, that is, interacting with this view after the animation and notifying the view that it is indeed visible?
You can use CAAnimation delegate method -animationDidStop:finished: to fix it when the animation done:
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
...
}
The better answer is to use UIView animation methods like animateWithDuration:animations:completion: (and variants on that method.)
Those methods let you do animations on the actual view properties, and when the animation is complete, the view is at it's actual destination location.
The center property is the easiest way to move views around. The frame property isn't valid if you've applied a transform, but the center property IS always valid for both reading and writing.
Core Animation only creates the illusion that your views move. The animation takes place on a display-only copy of the layer tree. You can query the properties of an animating layer by reading those same properties from the layer's presentationLayer. However, the view objects will not respond to the user interaction at their apparent location. The views still think they are at their original locations.
As the other poster said, you could use the animation completion delegate method to move the view to it's final location once the animation is over, but that's a lot of fussy work to do something that UIView animation does for you much more cleanly and simply.
Can you interact with the view even before you animate it?
is the view.userInteractionEnabled is set to YES??

emulate bounce effect in iphone app without UIScrollView

I am using a pan gesture to drag an item in my app. I know I could use a UIScrollView to get that "bounce" effect when dragging to an edge. However, that seems like a hack, so I'd like to find a way to get that effect when manually dragging an item (setting its frame or center point). I'm curious if there's a standard way, or a physics library in the Accelerate framework, something like that which wouldn't require me implementing my own physics engine.
The standard UIView animation curve is one that uses the accelerate / decelerate curve, which should gives a nice "bounce back" action.
It's really easy to use. Once you decide you want to "snap back" to a location, do this:
[UIView beginAnimations:nil context:nil];
CGRect newFrame = viewToAnimate.frame;
newFrame.origin.x = snapBackXcoordinate;
viewToAnimate.frame = newFrame;
[UIView commitAnimations];
to entirely emulate the UIScrollView you'll also need to set a "maximum stretch" distance before you stop stretching more.
But why re-invent the wheel? The UIKit components you're given are there to use. If putting your view into a UIScrollView does the trick, go ahead and use it. Saves you develop and debug time.

Problems with auto-rotation and UIImageView animations

I am rotating a UIImageView in place periodically. My view is very basic, a view inside of a UITabBar view set. If I happen to rotate my iPad while my rotation is animating then my image becomes skewed. I have checked everything I can think of in my xib file for my image, the autoresizing is turned completely off and I am not auto-resizing subviews on the parent view.
Here is my animation code:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
transform = CGAffineTransformMakeRotation(convertToRadian(myDegrees));
myImage.transform = transform;
[UIView commitAnimations];
If I take my animation out then everything works as I would expect. This rotation code appears to work fine if I do not rotate my device.
What can I do to keep the built-in rotation animation from altering my animation and skewing my images?
After many different attempts, what I ended up doing here is adding a clear view with my rotating images inside of it and setting the "auto-resize sub views" to off in interface builder. You can also do this in code as needed. I had to add the UIView placeholder because the super view containing my rotating images needed to auto-resize other view objects on rotation, but this fixed the funky skewing of my images due to animation of orientation change at the same time as animating a manual rotation in place.
Hope this helps someone.
The coordinate system gets changed. I've figured this much out too... thought I had a bug. If you save the CG ... GState, then you can revert back to the coordinate system initially used. This is in Deitel and Deitel's book. I just found it. Wanted to post it for anyone also looking.
You got a clever trick though! I might use it if this won't work.