Inside a UIViewController, I call a .xib file and present it over the current UIView.
// initiate the pop up ad view and display it
let popUpAdView = PopUpAdViewController(nibName: "PopUpAdView", bundle: nil)
popUpAdView.displayIntoSuperView(view)
There is a button inside that .xib file that should remove itself from the screen when it's touched. However it doesn't perform so.
What exactly am I missing?
class PopUpAdViewController: UIViewController {
#IBOutlet weak var popUpAdView: UIView!
#IBOutlet weak var closeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// adjust the view size from the device's screen size
let screenSize = UIScreen.mainScreen().bounds
view.frame = CGRectMake(0, 64, screenSize.width, screenSize.height-64)
// cosmetically adjust the view itself
view.backgroundColor = UIColor.blackColor().colorWithAlphaComponent(0.6)
view.userInteractionEnabled = true
closeButton.userInteractionEnabled = true
// style the pop up ad view
popUpAdView.layer.cornerRadius = 5
popUpAdView.layer.shadowOpacity = 0.8
popUpAdView.layer.shadowOffset = CGSizeMake(0.0, 0.0)
closeButton.addTarget(self, action: #selector(removeOutOfSuperView), forControlEvents: .TouchUpInside)
}
func displayIntoSuperView(superView: UIView!) {
superView.addSubview(self.view)
// define the initial cosmetical values of the items
popUpAdView.transform = CGAffineTransformMakeScale(0.3, 0.3)
popUpAdView.alpha = 0.0
closeButton.alpha = 0.0
// animate...
UIView.animateWithDuration(0.8, delay: 0.0, options: .CurveEaseIn, animations: {
self.popUpAdView.alpha = 1.0
self.popUpAdView.transform = CGAffineTransformMakeScale(1.0, 1.0)
}) { (Bool) in
UIView.animateWithDuration(0.6, delay: 1.5, options: .CurveEaseIn, animations: {
self.closeButton.alpha = 1.0
}, completion: { (Bool) in
})
}
}
func removeOutOfSuperView() {
UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseIn, animations: {
self.closeButton.alpha = 0.0
self.popUpAdView.transform = CGAffineTransformMakeScale(0.1, 0.1)
}) { (finished) in
UIView.animateWithDuration(0.8, delay: 0.0, options: .CurveEaseIn, animations: {
self.view.alpha = 0.0
self.view.removeFromSuperview()
}, completion: nil)
}
}
#IBAction func closePopUpAdView(sender: AnyObject) {
print("Closing the pop up ad...")
removeOutOfSuperView()
}
}
Update
.xib structureL:
Related
I have created simple animation show a coin pulsating and it worked pretty fine, until I added viewcontroller before the one with animation on storyboard.
I wanted to have menu screen in my game before showing the screen with this animation.
This is the code of the animation:
let imageView: UIImageView = coinImageView[0]
UIView.animate(withDuration: 0.5,
delay: 0.1,
options: [
.repeat,
.autoreverse,
.curveEaseIn,
.allowUserInteraction
],
animations: {
imageView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
}
)
The first view (with menu) looks like this:
class MenuViewController: UIViewController {
#IBAction func newGameButton(_ sender: Any) {
let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! ViewController
self.present(viewController, animated: true, completion: nil)
viewController.newGame()
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
and the second viewcontroller (the one with animation) looks like this:
class ViewController: UIViewController, SavingViewControllerDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
var coinImageView: [UIImageView] = []
func grantCoins(n: Int) {
let coinCount = coin.count
for i in coinCount...(coinCount+n) {
coin.append(UIImage(named: "coin.png")!)
coinImageView.append(UIImageView(image: coin[i]))
coinImageView[i].isUserInteractionEnabled = true
coinImageView[i].addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(_:))))
coinImageView[i].frame = CGRect(x: 147, y: -100, width: 60, height: 60)
view.addSubview(coinImageView[i])
let finalPoint = CGPoint(
x: 177,
y: 278
)
generateNewCoin(gestureView: coinImageView[i])
}
view.bringSubviewToFront(coinImageView[0])
}
func newGame() {
animateFirstCoin()
}
func animateFirstCoin() {
let imageView: UIImageView = coinImageView[0]
UIView.animate(
withDuration: 0.5,
delay: 0.1,
options: [.repeat, .autoreverse, .curveEaseIn, .allowUserInteraction],
animations: {
imageView.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
})
}
}
Is there any obvious explanation for the problem?
After a day of fruitless research I have found it finally.
When first coins were generated the view was not visible yet, to the animation didn't work. Another batch of coins was animated fine.
I just put this code in my function to check this out:
if (view.window == nil) {
print("view is not visible")
} else {
print("view is visible")
}
Thanks
I have UIImageView with moon image.
And moonImageContainerView is a superView for UIImageView
And I added swipe gesture to moonImageContainerView.
If swipe to up,
self.titleLabel.isHidden = false
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: {
self.moonImageContainerView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
self.moonImageContainerView.center.y = self.view.center.y
}, completion: nil)
you can see the result with gif
https://imgur.com/a/ftShkpO
And now, If I add just self.titleLabel.text = "MY TOPIA"
My animation is break.
self.titleLabel.text = "MY TOPIA" // Just added this line.
self.titleLabel.isHidden = false
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: {
self.moonImageContainerView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
self.moonImageContainerView.center.y = self.view.center.y
}, completion: nil)
You can see the result with gif
https://imgur.com/a/y57fPlA
Why does the moonImageContainerView disappear to the bottom?
How can I fix it?
Well, I use the rest setting and did not see your case.
import UIKit
class ImageViewController: UIViewController {
#IBOutlet var moonImageContainerView: UIView!
#IBOutlet var titleLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let pan = UISwipeGestureRecognizer.init(target: self, action: #selector(pp(_:)))
pan.direction = .up
moonImageContainerView.addGestureRecognizer(pan)
}
#objc func pp(_ pan: UISwipeGestureRecognizer){
self.titleLabel.text = "MY TOPIA"
self.titleLabel.isHidden = false
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseIn, animations: {
self.moonImageContainerView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5)
self.moonImageContainerView.center.y = self.view.center.y
}, completion: nil)
}
}
In all devices the table view needs to be display only 70% of the screen irrespective of all devices and it should need to display only from bottom to top with animation and if I select anywhere on screen it should go to below and hide with animation I tried but unable to implement it can any one help me how to implement this ?
Here is my code
#IBAction func addtoCartButtonAction(_ sender: Any) {
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.addToCartTableView.isHidden = false
self.addToCartTableView.delegate = self
self.addToCartTableView.dataSource = self
self.addToCartTableView.reloadData()
self.addToCartTableView.frame.origin.y = 200
}) { (Bool) in
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
UIView.animate(withDuration: 1, delay: 0.3, options: .autoreverse, animations: {
}) { (Bool) in
self.addToCartTableView.isHidden = true
}
}
#IBAction func AddtoCartTableViewCloseButtonAction(_ sender: Any) {
self.addToCartTableView.isHidden = true
}
For this you can use CGAffineTransform.
For example :
in viewWillAppear() do this :
addToCartTableView.alpha = 0.0
addToCartTableView.transform = CGAffineTransform(translationX: addToCartTableView.bounds.origin.x, y: self.view.bounds.height)
And in you button action addtoCartButtonAction do this :
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.addToCartTableView.delegate = self
self.addToCartTableView.dataSource = self
self.addToCartTableView.reloadData()
self.addToCartTableView.transform = .identity
self.addToCartTableView.alpha = 1.0
}) { (Bool) in
}
And a tap gesture to your view and whenever you want to hide it again do this :
UIView.animate(withDuration: 0.5, delay: 0.0, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.addToCartTableView.transform = CGAffineTransform(translationX: addToCartTableView.bounds.origin.x, y: self.view.bounds.height)
self.addToCartTableView.alpha = 0.0
}) { (Bool) in
}
Also you should not assign self.addToCartTableView.delegate = self self.addToCartTableView.dataSource = self in button action. Do that in viewDidLoad() or in storyboard only.
I have having a nightmare with a simple problem. On my app I have clouds moving in the background (currently from left to right).
However with the background they need to be right to left.
Eddited for the more of the page code below. Hopefully this will be easier to work out where I have gone wrong.
#IBOutlet var cloud1: UIImageView!
#IBOutlet var cloud2: UIImageView!
#IBOutlet var cloud3: UIImageView!
#IBOutlet var cloud4: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
cloud1.alpha = 0.0
cloud2.alpha = 0.0
cloud3.alpha = 0.0
cloud4.alpha = 0.0
}
override func viewDidAppear(_ animated: Bool) {
UIView.animate(withDuration: 2.0, delay: 0.1,
options: [],
animations: {
self.cloud1.alpha = 1.0
}, completion: nil)
UIView.animate(withDuration: 2.0, delay: 0.1,
options: [],
animations: {
self.cloud2.alpha = 1.0
}, completion: nil)
UIView.animate(withDuration: 2.0, delay: 0.1,
options: [],
animations: {
self.cloud3.alpha = 1.0
}, completion: nil)
UIView.animate(withDuration: 2.0, delay: 0.1,
options: [],
animations: {
self.cloud4.alpha = 1.0
}, completion: nil)
animateTheClouds(cloud: cloud1)
animateTheClouds(cloud: cloud2)
animateTheClouds(cloud: cloud3)
animateTheClouds(cloud: cloud4)
}
func animateTheClouds(cloud : UIImageView) {
let cloudMovingSpeed = 60.0/view.frame.size.width
let duration = (view.frame.size.width - cloud.frame.origin.x) * cloudMovingSpeed
UIView.animate(withDuration: TimeInterval(duration), delay: 0.0, options: .curveLinear, animations: {
// Animate the origin to be off the left side of the screen.
cloud.frame.origin.x = cloud.frame.size.width
}, completion: {_ in
// Reset back to the right edge of the screen
cloud.frame.origin.x = -self.view.frame.size.width
self.animateTheClouds(cloud: cloud)
})
If you want to move them from right to left then you simply need to change the starting and ending x origin.
func animateTheClouds(cloud : UIImageView) {
let cloudMovingSpeed = 60.0/view.frame.size.width
let duration = (cloud.frame.origin.x + cloud.frame.size.width) * cloudMovingSpeed
UIView.animate(withDuration: TimeInterval(duration), delay: 0.0, options: .curveLinear, animations: {
// Animate the origin to be off the left side of the screen.
cloud.frame.origin.x = -cloud.frame.size.width
}, completion: {_ in
// Reset back to the right edge of the screen
cloud.frame.origin.x = self.view.frame.size.width
self.animateTheClouds(cloud: cloud)
})
Also make sure the initial x origin is set to self.view.frame.size.width.
I have a label in xCode that I want to infinitely fade between a word and then the current time.
I've had a look online and can find a single fade but am new to Swift so I'm struggling to adapt this to my need.
Any help would be amazing, Thanks!
Here is an example of how to do this:
#IBOutlet weak var label: UILabel!
#IBAction func fade_out(sender: AnyObject) {
fade(label)
}
#IBAction func reset(sender: AnyObject) {
label.text = "label"
}
func fade(label : UILabel) {
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
label.alpha = 0.0
}, completion: nil)
UIView.animateWithDuration(2.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
label.alpha = 1.0
label.text = String(NSDate())
}, completion: nil)
}
What I do is that I fade out the label first with UIViewAnimationOptions.CurveEaseOut and then fade it in again with todays date with UIViewAnimationOptions.CurveEaseIn.
Here is a test project I created for you so that you can see how I have done it.
Edit
To do it infinity, you can do it like this and without a button
var timer = NSTimer()
var b = false
override func viewDidLoad() {
super.viewDidLoad()
self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(ViewController.fade), userInfo: nil, repeats: true)
}
func fade() {
if b{
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.label.alpha = 0.0
self.label.text = "Label"
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.label.alpha = 1.0
self.label.text = String(NSDate())
}, completion: nil)
b = false
}
else{
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: {
self.label.alpha = 0.0
self.label.text = String(NSDate())
}, completion: nil)
UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.label.alpha = 1.0
self.label.text = "Label"
}, completion: nil)
b = true
}
}
A much Elegant way will be to use CAAnimation ->
class YourClass: UIViewController , ..{
#IBOutlet weak var fadingLabel: UILabel!
var a = true
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: #selector(ViewController.swapText), userInfo: nil, repeats: true)
let anim : CABasicAnimation = CABasicAnimation(keyPath: "opacity")
anim.fromValue = 1
anim.toValue = 0
anim.duration = 0.5
anim.autoreverses = true
anim.repeatCount = Float.infinity
fadingLabel.layer.addAnimation(anim, forKey: "flashOpacity")
}
func swapText(){
if a == true{
fadingLabel.text = String(NSDate())
a = false
}else{
fadingLabel.text = String("My Text")
a = true
}
}
}
All you gotta do now is manipulate anim.duration and timeInterval in NSTimer() accordingly ...