UITextField not working in UIView.animateDuration in SWIFT - ios

This is iPad app by using SWIFT. It having two views.
1. starting_View
2. login_View
These two views are in same ViewController.
starting_View will be first view. By Clicking, NEXT button in first View, Starting View will move to left side by using animateDuration and same time, login_View will come from right. If we click Username/password fields (Any TextField), it will navigates to previous view.
Same time,,
if login_View will be first screen means, textField is working, keyboard is appearing.
But in animateDuration, i couldn't type. Kindly help me. Am using XCODE 6.1.
Code (from comment):
#IBAction func getStart_button(sender: UIButton) {
UIView.animateWithDuration(0.7, delay: 0.25, options: .CurveEaseOut, animations: {
self.clt_login_vw.frame = CGRectMake(450, 56, 574, 660)
}, completion:nil)
}

In General try to never change frames directly when using Autolayout.
The best way to move views have been for me to use CGAffineTransform.
let move = CGAffineTransformMakeTranslation(translation_X , translation_Y)
and inside your animation closure:
self.clt_login_vw.transform = move
Then to return it back just do inside the animation Closure:
self.clt_login_vw.transform = CGAffineTransformIdentity
Resume:
let moveOut = CGAffineTransformMakeTranslation(translation_X , translation_Y)
#IBAction func getStart_button(sender: UIButton) {
UIView.animateWithDuration(0.7, delay: 0.25, options: .CurveEaseOut, animations: {
[weak self] // Remember no not create cycles
self!.clt_login_vw.transform = moveOut
}, completion:nil)
}
Edit:
Im gonna add Noah Witherspoon's option.
Another way to do this is getting the constraint that is holding your view horizontally, once you get it, you change its constant and call layoutIfNeeded() inside the closure:
#IBAction func getStart_button(sender: UIButton) {
constraint.constant = newConstant // enough to make it off the screen
UIView.animateWithDuration(0.7, delay: 0.25, options: .CurveEaseOut, animations: {
[weak self] // Remember no not create cycles
self!.view.layoutIfNeeded()
}, completion:nil)
}
The way to get the specific constraint, I'm more friend of making IBOutlets, so I get easily its reference in Code.
That is if you didn't make it by code.

Related

UIView Animation and UIButton stop working b/c Home pressed - Swift 4

I have a playButton that performs a "breathing animation". The button works just fine when I press it. The problem occurs if I press the device's Home Button and then re-open the app. Upon re-opening, the playButton does not have the "breathing animation" and it does not work (nothing happens when it is pressed).
#IBOutlet weak var playButton: UIButton!
override func viewWillAppear(_ animated: Bool) {
UIView.animate(withDuration: 1.0,
delay: 0,
options: [.autoreverse, .repeat, .allowUserInteraction],
animations: {
self.playButton.transform = CGAffineTransform(scaleX: 1.175, y: 1.175)
},
completion: nil
)
}
I've dealt with this issue in a previous game app where I needed to save and pause the game if the user pressed the Home Button or if there was an interruption (incoming call). So, I am well aware of:
func applicationDidBecomeActive() {}
func applicationWillResignActive() {}
func applicationDidEnterBackground() {}
But, I am not dealing with a gameState, timer, the need to save data, etc. I simply want my button and its animation to work properly when the app re-opens after the Home Button is pressed.
I also tried using override func viewDidLayoutSubviews() {} instead of viewWillAppear. But that did not work.
First of all, if you have a multiple animations within the same ViewController (VC) that occur after playButton is pressed, then that may explain why the it is becoming disabled upon return from background. Why? I don't know. But I had a similar issue and resolved it by creating a new class and VC for the multiple animations that were originally set to occur when my UIButton was pressed. Inside of my button's IBAction, I simply created a segue to then new VC.
With regards to the animation, you could approach this two ways: 1) Pause and Resume the animation using CALayer OR 2) Simply use NotificationCenter without even having to touch any AppDelegate code. I prefer simple ways b/c it will save time and effort. So, try this code in the VC where the button animation is to occur:
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector:#selector(goingToBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector:#selector(openingApp), name: UIApplication.willEnterForegroundNotification, object: nil)
UIView.animate(withDuration: 1.0,
delay: 0,
options: [.autoreverse, .repeat, .allowUserInteraction],
animations: {
self.playButton.transform = CGAffineTransform(scaleX: 1.175, y: 1.175)
},
completion: nil)
}
#objc func goingToBackground(){
playButton.transform = .identity
}
#objc func openingApp(){
self.view.layoutIfNeeded()
UIView.animate(withDuration: 1.0,
delay: 0.3,
options: [.autoreverse, .repeat, .allowUserInteraction],
animations: {
self.playButton.transform = CGAffineTransform(scaleX: 1.175, y: 1.175)}, completion: nil)
self.view.layoutIfNeeded()
}

Allow UITapGestureRecognizer inside UIAnimations

I'm trying to show a custom view when I receive a notification from parse.
This view is showed with an animation and its hidden with another animation. This view also has a uitapgesturerecognizer that needs to be fired when the user taps the view.
My problem is that when the second animation gets fired the custom view's uitapgesture doesn't work :\
Any ideas? I paste the code.
Thanks!
func doManageObjectNotification(notification: COPushNotification){
mainView = UIApplication.sharedApplication().keyWindow!
customView = CustomNotificationView()
let height = customView.calculateViewHeight()
customView.frame = CGRectMake(0, -height, mainView.frame.width, height)
customView.targetMethod = notificationWasTapped
customView.setContent(notification)
customView.alpha = 0
mainView.addSubview(customView)
UIView.animateWithDuration(0.75, delay: 0, options: [UIViewAnimationOptions.CurveEaseInOut, UIViewAnimationOptions.AllowUserInteraction], animations: { () -> Void in
// Show the view
self.customView.frame.origin.y = 0
self.customView.alpha = 1
}) { (Bool) -> Void in
UIView.animateWithDuration(0.75, delay: 5, options: [UIViewAnimationOptions.CurveEaseInOut, UIViewAnimationOptions.AllowUserInteraction], animations: {
// Hide the view
self.customView.alpha = 0
}, completion: { finished in
self.customView.removeFromSuperview()
self.customView = nil
})
}
}
Im agree with Lion answer, but I want also focus your attention about customView.frame.origin.y = 0 during animation: if you use autolayout and you try to change frame dimensions or positions instead the correct constraints involved, you can disable you constraints effect causing warnings and unexpected view dimensions and movements. When you have this issue many times the UITapGestureRecognizer stop to responding.
The best way to do it is to create IBOutlets constraints and working with it (for example):
#IBOutlet weak var customViewTopConstraint: NSLayoutConstraint
...
UIView.animateWithDuration(0.75, delay: 0, options: [UIViewAnimationOptions.CurveEaseInOut, UIViewAnimationOptions.AllowUserInteraction], animations: { () -> Void in
// Show the view
self.customViewTopConstraint.constant = 0
For handling tap during animation you should implement touchesBegan method. by this you can detect touch and then check that touch is from your view,if yes then you can perform your desired task.
Hope this will help :)

blink UILabel text swift2 ios

I see code to make text in UILabel to blink, but I am using Swift 2, and what changes does one make to have such text blink in Swift?
I just need this style only to alert the user of my app to start the game, then I don't need any other text to blink.
If you have provided some code it were simpler to answer but without it it's I can do:
let foo = UITextField()
UIView.animateWithDuration(0.3, animations: {() -> Void in
foo.alpha = 0.0
},
completion: { finished in
UIView.animateWithDuration(0.3, animations: {
foo.alpha = 1.0
})
})
You can do this by using animateWithDuration.
Here i am writing in viewDidLoad(). you can use this according to your requirement.
override func viewDidLoad() {
super.viewDidLoad()
self.myLabel.alpha=0
UIView.animateWithDuration(1, delay: 0.2, options:[.Repeat,.Autoreverse],
animations:{ self.myLabel.alpha=1.0}, completion: nil)
}

UISlider set value

I have a UISlider and I want to set its value from 1 to 10. The code I use is.
let slider = UISlider()
slider.value = 1.0
// This works I know that
slider.value = 10.0
What I want to do is animate the UISlider so that it takes 0.5s to change. I don't want it to be as jumpy more smooth.
My idea so far is.
let slider = UISlider()
slider.value = 1.0
// This works I know that
UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseInOut, animation: { slider.value = 10.0 } completion: nil)
I am looking for the solution in Swift.
EDITED
After some discussion, I thought I'd clarify the differences between the two suggested solutions:
Using the built-in UISlider method .setValue(10.0, animated: true).
Encapsulating this method in a UIView.animateWithDuration.
Since the author is asking explicitly for a change that will take 0.5s---possibly triggered by another action---the second solution is to prefer.
As an example, consider that a button is connected to an action that sets the slider to its maximum value.
#IBOutlet weak var slider: UISlider!
#IBAction func buttonAction(sender: AnyObject) {
// Method 1: no animation in this context
slider.setValue(10.0, animated: true)
// Method 2: animates the transition, ok!
UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseInOut, animations: {
self.slider.setValue(10.0, animated: true) },
completion: nil)
}
Running a simple single UIVIewController app with just the UISlider and UIButton objects present yields the following results.
Method 1: Instant slide (even though animated: true)
Method 2: Animates transition. Note that if we set animated: false in this context, the transition will be instantaneous.
the problem with #dfri's answer is that the blue Minimum Tracker is moving from 100% to the value, so in order to solve that, you need to change the method a little bit:
extension UISlider
{
///EZSE: Slider moving to value with animation duration
public func setValue(value: Float, duration: Double) {
UIView.animateWithDuration(duration, animations: { () -> Void in
self.setValue(self.value, animated: true)
}) { (bol) -> Void in
UIView.animateWithDuration(duration, animations: { () -> Void in
self.setValue(value, animated: true)
}, completion: nil)
}
}
}

How do I segue through dates?

Imagine each view on the screen is to show some information about that particular day. Swiping right advances the date by one day, swiping left shows yesterday's data.
I've managed to achieve this by capturing the swipe gesture and updating the data on the screen, but I don't get the swipe animation. I'm guessing the proper way to do this is to segue the view controller to itself and update instead but I'm not sure. Can anyone advise on the proper way to do this?
You need a block like this for each direction. This one is for Swipe Right (go back). The other direction is reversed.
UIView.animateWithDuration(NSTimeInterval(0.1), animations: {
//swipes view off screen
self.calView.frame.origin.x = self.view.frame.width
})
UIView.animateWithDuration(NSTimeInterval(0), delay: NSTimeInterval(0.1), options: UIViewAnimationOptions(rawValue: 0), animations: {
//jumps to other side
self.calView.frame.origin.x = -self.view.frame.width
}, completion: { _ in
//reload data, subtract one, whatever
self.setCurrentDate()
self.collectionView?.reloadData()
})
UIView.animateWithDuration(NSTimeInterval(0.1), delay: NSTimeInterval(0.2), options: UIViewAnimationOptions(rawValue: 0), animations: {
//swipes back to center
self.calView.frame.origin.x = 0
}, completion: nil)

Resources