Tap is not detected on continuous scrolling of UICollectionView iOS? - ios

I have a UICollectionView continuous scrolling using NSTimer, here is the code
let timer = NSTimer(timeInterval: 0.1, target: self, selector: #selector(HomeViewController.scrollToNextCard), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer!, forMode: NSDefaultRunLoopMode)
func scrollToNextCard(){
UIView.animateWithDuration(0.1, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
// I am changing the contentOffset of collectionview for continuous scrolling
}, completion: {(finished:Bool) in
})
When tapping on any of visible cells when scrolling is in progress, delegate's method didSelectItemAtIndexpath is not being called. How do I achieve tapping detection at the same time maintaining scrolling of collection view. Please help thanks

I found the answer for the same, I had to add AllowUserInteraction flag on the animation block as in the code:
func scrollToNextCard(){
UIView.animateWithDuration(Constants.CardFlowTimeInterval, delay: 0.0, options: [.CurveEaseInOut,.AllowUserInteraction], animations: {
}, completion: {(finished:Bool) in
})
}

Related

UIView Animation Chaining Doesn't Work Properly

I am trying to animate a simple Loading label text to show 3 dots after it, with each dot having a second of delay.
Here is what i tried:
func animateLoading() {
UIView.animate(withDuration: 1, animations: {self.yukleniyorLabel.text = "Yükleniyor."}, completion: { _ in
UIView.animate(withDuration: 1, animations: {self.yukleniyorLabel.text = "Yükleniyor.."}, completion: { _ in
UIView.animate(withDuration: 1, animations: {self.yukleniyorLabel.text = "Yükleniyor..."})
})
})
}
But what i got is the all 3 dots appear in 1 second alltogether. Not in order. See here: https://streamable.com/yiz6s
What am i doing wrong with the chaining? Thanks in advance.
UIView animate is only for animatable view properties such as frame and background color. self.yukleniyorLabel.text is not an animatable property. So you get no animation.
Just use a Timer or delayed performance to change the text at time intervals.
You can use the scheduled Timer for showing text with three dots on the label with animation: ->
var i = 0
var timer : Timer?
loaderLabel.text = "Loading"
timer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector:#selector(ViewController.setText), userInfo: nil, repeats: true)
#objc func setText() {
loaderLabel.text = loaderLabel.text! + "."
i += 1
if i >= 3 {
timer?.invalidate()
}
}
output with animation: -> Loading...

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()
}

UIView.transition with delay

I have simultaneous animations going on, and I would like to transition the VC in the middle (it will fade so it will see some of the other animations). However, I can't find documentation how to delay a transition similar to UIView.animateWithDuration.
I want to achieve this...
UIView.transition(withDuration: 0.5, delay: 0.1, options: .transitionCrossDissolve, animations: {})
I can manually add a delay like so.. but was wondering if there's a more elegant way.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {}
Unfortunately no. Using a bunch of UIView transitions/animations can get a little hairy.
In the past, I've resorted to setting up an NSTimer that fires 1/30 seconds and I ended up managing all the start times on my own.
What you can do is series out the animations using the closure.
UIView.animate(withDuration: 1, animations: {
}, completion: {Do UIView transition here})
It seems no way except surrounding with Timer:
Timer.scheduledTimer(withTimeInterval: 5, repeats: true, block: { _ in
UIView.transition(with: self.myImageView, duration: 0.75,
options: [.transitionCrossDissolve],
animations: {
self.myImageView.image = newImage
})
})

Reset animation after removeAllAnimations()

With great help from the community I made an zoom in-and-out animation of a button image. The problem is, after the first run the button is disabled and wont work again before the app is relaunched. What I want is that after the button is clicked and the animation is finished it goes back to the starting point, and you can click it again. Anybody here that can help me with that?
#IBAction func coffeeButton(sender: UIButton) {
var timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "stopButtonAnimation", userInfo: nil, repeats: false)
let options = UIViewAnimationOptions.Autoreverse | UIViewAnimationOptions.Repeat | UIViewAnimationOptions.CurveEaseInOut
UIView.animateWithDuration(0.5, delay: 0, options: options, animations: {
self.button.transform = CGAffineTransformMakeScale(0.5, 0.5)
}, completion: nil)
}
func stopButtonAnimation(){
button.layer.removeAllAnimations()
}
Corrected your stopButtonAnimation function.
What applying transform does is setting the scale of your button to it's original value, so you are able to see your animation again.
func stopButtonAnimation(){
button.layer.removeAllAnimations()
button.layer.transform = CATransform3DIdentity
}
Animation in your original code was stopped at the scale value of 0.5 so next time you click the button you just don't see it (because it had been animating scale from 0.5 to 0.5).

better way to set alpha for a view after a few seconds in apple watch / watchkit in swift

I am trying to set alpha with animation to image view in swift for apple watch application.
to do that i have tried code below
UIView.animateWithDuration(1.5, animations: {
self.splashscreenImage.alpha = 1.0
return
})
but its iving error as
'WKInterfaceImage' does not have a member named 'alpha'
so i implemented code below in willActivate function
var timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: Selector("splashscreenAlpha"), userInfo: nil, repeats: false)
and
func splashscreenAlpha() {
self.splashscreenImage.setAlpha(0.0)
}
but in this scenario, view is like invisible, like image view has a black background. But i would like it to gone with animation. How can i do that?
You should try using
UIView.animateWithDuration(1.5, animations: {
self.splashscreenImage.setAlpha(1.0)
return
})
to make alpha animation.

Resources