I am using Sketch 3 and I created a rectangle which I made the opacity 70% and gave it a background blur of 20%. When I add this image to my project and try to use it on Xcode the blur disappears from the image and I am left with something I did not create, a see through image with no blur. What can be possibly going on?
func createBlurImageView() {
guard let imageView: UIImageView = UIImageView(frame: self.window!.bounds) else {
return
}
imageView.tag = 1000
imageView.image = UIImage(named: "Rectangle136")
self.window!.addSubview(imageView)
self.window!.bringSubviewToFront(imageView)
UIView.animateWithDuration(0.4, animations: {() -> Void in
imageView.alpha = 0.8
})
}
func removeBlurImageView() {
guard let imageView = self.window?.viewWithTag(1000) as? UIImageView else {
print("No good")
return
}
UIView.animateWithDuration(0.4, animations: {() -> Void in
imageView.alpha = 0
}, completion: {(finished: Bool) -> Void in
// remove when finished fading
imageView.removeFromSuperview()
})
}
Related
how can I implement that when I click on button, my Image moves out of the screen with animation and when I click again on the button , comes back to its place?
On the button click event, simply animate the x coordinate of origin of the imageView according to your requirement.
Example:
#IBAction func onTapButton(_ sender: UIButton)
{
if sender.isSelected
{
UIView.animate(withDuration: 2.0, animations: {
self.imageView.frame.origin.x = 0.0
})
}
else
{
UIView.animate(withDuration: 2.0, animations: {
self.imageView.frame.origin.x = UIScreen.main.bounds.width
})
}
sender.isSelected = !sender.isSelected
}
The above code will work as follows:
when selecting button, imageView's x coordinate of origin is moved to extreme right of the screen (UIScreen.main.bounds.width)
when de-selecting button, imageView's x coordinate of origin is moved to extreme left of the screen (0.0)
Use this code to move left-
func moveToLeft()
{
var frame = imageView.frame
frame.origin.x = -imageView.frame.size.width //Adjust this value according to your need
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: {() -> Void in
self.imageView.frame = frame
}, completion: {(_ finished: Bool) -> Void in
/*done*/
})
}
Use this code to move right-
func moveToRight()
{
var frame = imageView.frame
frame.origin.x = 0 //Adjust this value according to your need
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseOut, animations: {() -> Void in
self.imageView.frame = frame
}, completion: {(_ finished: Bool) -> Void in
/*done*/
})
}
I'm using a custom library : CAPSPageMenu . Here I have one view controller and I programmatically add the name for that, the view has two tabs. When i click any tab that respective page will display below.
I have set the name and added the animation to swipe between two tabs. But now I need to add image on above of my label, how would I accomplish that?
Here is my code !:
var pageMenu : CAPSPageMenu? // pager object
var controllerArray : [UIViewController] = [] // number view pager
override func viewDidLoad() {
super.viewDidLoad()
pageSettings()
}
func pageSettings() {
tableView.dataSource = self
tableView.delegate = self
let controller1 : UIViewController = UIViewController()
controller1.title = "FAVOURITES"
controllerArray.append(controller1)
let controller2 : UIViewController = UIViewController()
controller2.title = "RECENT SEARCH"
controllerArray.append(controller2)
let leftRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.didLeftSwipe(_:)))
leftRecognizer.direction = .Left
self.tableView.addGestureRecognizer(leftRecognizer)
let rightRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.didRightSwipe(_:)))
rightRecognizer.direction = .Right
self.tableView.addGestureRecognizer(rightRecognizer)
}
Like this i need to add image.As i mention the box above the two labels
Seems you are used a custom library CAPSPageMenu, unfortunately what do you want to do is not available.
However with swift you can do extraordinary things such as expanding PageMenu directly in your code: (I've maded just an example but you can start from it):
Add this code at the bottom of your class or whatever you want:
extension UIView {
func fadeIn(duration: NSTimeInterval = 1.0, delay: NSTimeInterval = 0.0, completion: ((Bool) -> Void) = {(finished: Bool) -> Void in}) {
UIView.animateWithDuration(duration, delay: delay, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.alpha = 1.0
}, completion: completion) }
func fadeOut(duration: NSTimeInterval = 1.0, delay: NSTimeInterval = 0.0, completion: (Bool) -> Void = {(finished: Bool) -> Void in}) {
UIView.animateWithDuration(duration, delay: delay, options: UIViewAnimationOptions.CurveEaseIn, animations: {
self.alpha = 0.0
}, completion: completion)
}
}
extension CAPSPageMenu {
func addImageOverMyMenuItem(index:Int,imageName:String) {
if index>=0 && index<self.menuItems.count || self.menuItems[index].titleLabel!.frame.height>0 {
var labelFrame = self.menuItems[index].titleLabel!.frame
let image: UIImage = UIImage(named: imageName)!
let bgImage = UIImageView(image: image)
labelFrame.origin.y = self.menuItems[index].frame.origin.y
labelFrame.origin.x += (labelFrame.width/10)
labelFrame.size.width -= (labelFrame.width/10)*2
labelFrame.size.height = self.menuItems[index].titleLabel!.frame.size.height/3
bgImage.frame = labelFrame
bgImage.tag = 9999
bgImage.alpha = 0.0
self.menuItems[index].addSubview(bgImage)
bgImage.fadeIn(completion: {
(finished: Bool) -> Void in
if finished {
// image is showed, do whatever you want
}
})
} else {
print("Due to index out of range or titleLabel dont yet setted i cannot set image")
}
}
func removeImageOverMyMenuItem(index:Int) {
if index>=0 && index<self.menuItems.count {
if let bgImage = self.menuItems[index].viewWithTag(9999) {
bgImage.fadeOut(completion: {
(finished: Bool) -> Void in
if finished {
bgImage.removeFromSuperview()
}
})
}
}
}
}
You can easily use to add an image:
pageMenu?.addImageOverMyMenuItem(0, imageName: "search.png")
and to remove :
pageMenu?.removeImageOverMyMenuItem(0)
P.S. The result would be this:
So , finally following the official demo 1 project (PageMenuDemoStoryboard) in the ViewController at the method viewDidAppear i can add my images like this:
// Initialize scroll menu
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRectMake(0.0, 0.0, self.view.frame.width, self.view.frame.height), pageMenuOptions: parameters)
pageMenu?.addImageOverMyMenuItem(0, imageName: "search.png")
pageMenu?.addImageOverMyMenuItem(1, imageName: "search.png")
pageMenu?.addImageOverMyMenuItem(2, imageName: "search.png")
self.addChildViewController(pageMenu!)
self.view.addSubview(pageMenu!.view)
pageMenu!.didMoveToParentViewController(self)
...
And you obtain this result:
P.S.S. If it's not clear, I've made this example just using an image named "search.png" but you can use all images do you want to insert in your project.
You are using PageMenu, right?
Basically, PageMenu doesn't have the feature satisfy your needs.
If you want to use PageMenu, you have to modify this module.
Check MenuItemView Class in CAPSPageMenu.swift
I have also customised CAPSPageMenu , using the answer of #Alessandro Ornano that helped me to add the image above text, so anyone using can also set width,height of image and also can set the position of image as per device by using code below.Hope it will help someone.
extension UIView {
func fadeIn(duration: TimeInterval = 0.0, delay: TimeInterval = 0.0, completion: #escaping ((Bool) -> Void) = {(finished: Bool) -> Void in}) {
UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.alpha = 1.0
}, completion: completion) }
func fadeOut(duration: TimeInterval = 0.0, delay: TimeInterval = 0.0, completion: #escaping (Bool) -> Void = {(finished: Bool) -> Void in}) {
UIView.animate(withDuration: duration, delay: delay, options: UIViewAnimationOptions.curveEaseIn, animations: {
self.alpha = 0.0
}, completion: completion)
}
}
extension CAPSPageMenu {
func addImageOverMyMenuItem(index:Int,imageName:String) {
if index>=0 && index<self.menuItems.count || self.menuItems[index].titleLabel!.frame.height>0 {
var labelFrame = self.menuItems[index].titleLabel!.frame
let image: UIImage = UIImage(named: imageName)!
let bgImage = UIImageView(image: image)
labelFrame.origin.y = self.menuItems[index].frame.origin.y
labelFrame.origin.x += (labelFrame.width/9)
labelFrame.size.width -= (labelFrame.width/10)*5
labelFrame.size.height = self.menuItems[index].titleLabel!.frame.size.height/3
bgImage.frame = labelFrame
bgImage.tag = 9999
bgImage.alpha = 0.0
if UIDevice().userInterfaceIdiom == .phone {
switch UIScreen.main.nativeBounds.height {
case 480:
print("iPhone Classic")
case 960:
print("iPhone 4 or 4S")
bgImage.frame = CGRect(origin: CGPoint(x:20 ,y :0), size: CGSize(width:30, height: 30))
case 1136:
print("iPhone 5 or 5S or 5C")
bgImage.frame = CGRect(origin: CGPoint(x:20 ,y :0), size: CGSize(width:35, height: 35))
case 1334:
print("iPhone 6 or 6S")
bgImage.frame = CGRect(origin: CGPoint(x:30 ,y :0), size: CGSize(width:35, height: 35))
case 2208:
print("iPhone 6+ or 6S+")
bgImage.frame = CGRect(origin: CGPoint(x:35 ,y :0), size: CGSize(width:35, height: 35))
default:
print("unknown")
bgImage.frame = CGRect(origin: CGPoint(x:40 ,y :0), size: CGSize(width:30, height: 30))
}
}
self.menuItems[index].addSubview(bgImage)
bgImage.fadeIn(completion: {
(finished: Bool) -> Void in
if finished {
// image is showed, do whatever you want
}
})
} else {
print("Due to index out of range or titleLabel dont yet setted i cannot set image")
}
}
func removeImageOverMyMenuItem(index:Int) {
if index>=0 && index<self.menuItems.count {
if let bgImage = self.menuItems[index].viewWithTag(9999) {
bgImage.fadeOut(completion: {
(finished: Bool) -> Void in
if finished {
bgImage.removeFromSuperview()
}
})
}
}
}
}
extension UIDevice {
var iPhone: Bool {
return UIDevice().userInterfaceIdiom == .phone
}
enum ScreenType: String {
case iPhone4
case iPhone5
case iPhone6
case iPhone6Plus
case unknown
}
var screenType: ScreenType {
guard iPhone else { return .unknown }
switch UIScreen.main.nativeBounds.height {
case 960:
return .iPhone4
case 1136:
return .iPhone5
case 1334:
return .iPhone6
case 2208:
return .iPhone6Plus
default:
return .unknown
}
}
}
You can easily use to add an image in viewDidLoad():
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRect(origin: CGPoint(x: 0,y :70), size: CGSize(width: self.view.frame.width, height: self.view.frame.height)), pageMenuOptions: menuParam)
pageMenu?.addImageOverMyMenuItem(index: 0, imageName: "detail.png")
pageMenu?.addImageOverMyMenuItem(index: 1, imageName: "gallery.png")
pageMenu?.addImageOverMyMenuItem(index: 2, imageName: "time.png")
pageMenu?.addImageOverMyMenuItem(index: 3, imageName: "map.png")
Result :
I want the background color of my iOS app to change between four colors over x amount of seconds
This is what I have so far (it does exactly what I want when I specify just 2 colors)
I also need the animation to run in a loop infinitely.
ViewController.swift
UIView.animateWithDuration(X.0, animations: {
// Color 1
self.view.backgroundColor = UIColor(rgba)
// Color 2
self.view.backgroundColor = UIColor(rgba)
// Color 3
self.view.backgroundColor = UIColor(rgba)
// Color 4
self.view.backgroundColor = UIColor(rgba)
})
Try this out:
UIView.animateWithDuration(1.0, animations: { () -> Void in
self.view.backgroundColor = UIColor.blackColor()
}) { (Bool) -> Void in
UIView.animateWithDuration(1.0, animations: { () -> Void in
self.view.backgroundColor = UIColor.greenColor()
}, completion: { (Bool) -> Void in
UIView.animateWithDuration(1.0, animations: { () -> Void in
self.view.backgroundColor = UIColor.grayColor()
}, completion: { (Bool) -> Void in
UIView.animateWithDuration(1.0, animations: { () -> Void in
self.view.backgroundColor = UIColor.redColor()
}, completion:nil)
})
})
}
In case you want a continuous repeating animation, try this out:
UIView.animate(withDuration: 2, delay: 0.0, options:[UIView.AnimationOptions.repeat, UIView.AnimationOptions.autoreverse], animations: {
self.view.backgroundColor = UIColor.black
self.view.backgroundColor = UIColor.green
self.view.backgroundColor = UIColor.darkGray
self.view.backgroundColor = UIColor.red
}, completion: nil)
Below code helps to keep enable user interaction with animated view. A random color generation (use in case its needed).
UIView.animateWithDuration(7, delay: 1, options:
[UIViewAnimationOptions.AllowUserInteraction,
UIViewAnimationOptions.Repeat,
UIViewAnimationOptions.Autoreverse],
animations: {
self.yourView.backgroundColor = self.randomColor()
self.yourView.backgroundColor = self.randomColor()
}, completion:nil )
func randomColor() -> UIColor {
let randomRed:CGFloat = CGFloat(drand48())
let randomGreen:CGFloat = CGFloat(drand48())
let randomBlue:CGFloat = CGFloat(drand48())
return UIColor(red: randomRed, green: randomGreen, blue: randomBlue,
alpha: 1.0)
}
You have to use NSTimer:
let timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "update", userInfo: nil, repeats: true)
func update() {
let nextCollor = getNextColor()
UIView.animateWithDuration(X.0, animations: {
self.view.backgroundColor = nextCollor
})
}
func getNextColor() -> UIColor {
let currentColor = self.view.backgroundColor
if currentColor == smaple1 {
return UIColor.redColor()
} else if currentColor == smaple2 {
return UIColor.grayColor()
} else {
return UIColor.whiteColor()
}
}
NSTimer.scheduledTimerWithTimeInterval runs your code every 5 seconds
PS: do not forget invalidate timer when you done with it. Just call timer.invalidate() for it. Otherwise you get a crash.
Swift 5
override func viewWillAppear(_ animated: Bool) {
self.customButton.backgroundColor = .red
UIView.animateKeyframes(withDuration: 0.5, delay: 0, options: [.repeat, .autoreverse], animations: {
self.customButton.backgroundColor = .none
}, completion: nil)
}
i had a dynamic / unknown amount of colors to cycle through, so i refactored the Swift 5 answer a bit:
Swift 5
UIView.animate(withDuration: 1.0, delay: 0.0, options: [.repeat, .autoreverse]) {
// colors is the dynamic [UIColor] array previously defined
for color in colors {
self.colorView.backgroundColor = color
}
} completion: { (finished) in
}
this will nicely cycle through the colors with a fade-style animation -- and with the .autoreverse option, it won't "snap" to the starting color.
I want to fade in an UIImageView as a BackgroundView of an UITableView. It's not animating. The image is just there. Any ideas why?
Here is my code:
override func viewWillAppear(animated: Bool)
{
super.viewWillAppear(animated)
let backgroundImage = UIImage(named: "theImage")
let imageView = UIImageView()
imageView.image = backgroundImage
imageView.contentMode = UIViewContentMode.ScaleAspectFit
self.tableView.backgroundView = imageView
//Tried it this way
imageView.alpha = 0.0
//and that way
self.tableView.backgroundView?.alpha = 0.0
UIView.animateWithDuration(3.0, animations: { () -> Void in
//Both not animating
self.tableView.backgroundView?.alpha = 1.0
imageView.alpha = 1.0
})
}
Thanks
It doesn't work because you call it in viewWillAppear it happens before the view is loaded so the animation is invisible.
Try change it to viewDidAppear and it will work. You don't need to change
self.tableView.backgroundView?.alpha = 0.0
imageView.alpha is enough, try that:
override func viewDidAppear(animated: Bool)
{
super.viewDidAppear(animated)
let backgroundImage = UIImage(named: "theImage")
let imageView = UIImageView()
imageView.image = backgroundImage
imageView.contentMode = UIViewContentMode.ScaleAspectFit
self.tableView.backgroundView = imageView
imageView.alpha = 0.0
UIView.animateWithDuration(3.0, animations: { () -> Void in
imageView.alpha = 1.0
})
}
I'm trying to animate a label text so that if the value greater it will change the text color to blue and if the value less it will change the color to Red, else remain the same "Black color".
But UIView.animateWithDuration() it change the color to Blue permanently, all I am trying to do is if the value great or less than, I want to change the label color to blue or red for few seconds then return its color to black.
Here is my code:
#IBOutlet weak var label: UILabel!
let x = 10
let y = 20
if x > y
{
UIView.animateWithDuration(2,animations:
{ () -> Void in self.label.textColor = UIColor.blueColor(); })
}
else if y < x
{
UIView.animateWithDuration(2,animations:
{ () -> Void in self.label.textColor = UIColor.redColor(); })
}
else
{
self.label.textColor = UIColor.blackColor()
}
also I tried to use Sleep function as follow but it didn't work out
self.label.textColor = UIColor.blueColor()
sleep(3)
self.label.textColor = UIColor.blackColor()
UIView animation api cannot animate the textColor property of UILabel, for that you will need to use CAAnimation. Here is a implementation using CATransition.
func animate() {
let x = 10
let y = 20
var finalColor: UIColor!
if x > y {
finalColor = UIColor.blueColor()
} else {
finalColor = UIColor.redColor()
}
let changeColor = CATransition()
changeColor.type = kCATransitionFade
changeColor.duration = 2.0
CATransaction.begin()
CATransaction.setCompletionBlock {
self.label.textColor = UIColor.blackColor()
self.label.layer.addAnimation(changeColor, forKey: nil)
}
self.label.textColor = finalColor
self.label.layer.addAnimation(changeColor, forKey: nil)
CATransaction.commit()
}
Building on Acluda's answer, I'd recommend putting his code in the completion handler of the animateWithDuration:animations:completion variant.
UIView.animateWithDuration(2,
animations: { () -> Void in self.label.textColor = UIColor.blueColor(); },
completion: { (wentThrough: Bool) -> Void in
{ UIView.animateWithDuration(2,
animations: { () -> Void in self.label.textColor = UIColor.blackColor(); }) })
UIView.transitionWithView(myLabel, duration: 0.25, options: .TransitionCrossDissolve, animations: {() -> Void in
label.textColor = UIColor.redColor()
}, completion: {(finished: Bool) -> Void in
})
Try :)
There is no logic that tells the UIView to return back to UIColor.blackColor once the first animation is complete.
Consider adding this after animation calls for blue/red.
UIView.animateWithDuration(2,animations:
{ () -> Void in self.label.textColor = UIColor.blackColor(); })