How to set the alpha of an UIImage in SWIFT programmatically? - swift

I found a lot solutions here but not for Swift, and I know you can do this with a UIImageView, but in my case i need an programmatically set alpha transparent background image for an UIButton. Best would be an UIImage extension!
let img = UIImage(named: "imageWithoutAlpha")
var imgInsets = UIEdgeInsetsMake(0, 24, 0, 24)
image = image!.resizableImageWithCapInsets(imgInsets)
let myButton = UIButton(frame: CGRect(x: 50, y: 50, width: img!.size.width, height: img!.size.height))
myButton.setBackgroundImage(img, forState: UIControlState.Normal)
myButton.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 20)
myButton.setTitle("Startbutton", forState: UIControlState.Normal)
myButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
myButton.sizeToFit()
view.addSubview(myButton)
Current result:
Desired result:

Luckily I was able to help myself and would like to share with you my solution:
Swift 3
// UIImage+Alpha.swift
extension UIImage {
func alpha(_ value:CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: CGPoint.zero, blendMode: .normal, alpha: value)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
}
The above new Swift extension I added to my project and then I changed the UIButton example as follows, to have an alpha transparent background image with a transparency of 50%.
let img = UIImage(named: "imageWithoutAlpha")!.alpha(0.5)
let myButton = UIButton()
myButton.setBackgroundImage(img, for: .normal)

The easiest way is to put your UIImage inside a UIImageView and set the alpha there.
let image = UIImage(named: "imageWithoutAlpha")
let imageView = UIImageView(image: image)
imageView.alpha = 0.5
myButton.setBackgroundImage(image, forState: UIControlState.Normal)

Swift 5, iOS 10+
If your app doesn't support operating systems prior to iOS 10 then you can take advantage of the more robust UIGraphicsImageRenderer UIKit drawing API.
extension UIImage {
func withAlpha(_ a: CGFloat) -> UIImage {
return UIGraphicsImageRenderer(size: size, format: imageRendererFormat).image { (_) in
draw(in: CGRect(origin: .zero, size: size), blendMode: .normal, alpha: a)
}
}
}
Usage
let img = UIImage(named: "someImage")?.withAlpha(0.5)

I was able to set the alpha using the following code:
self.imageView.image = UIImageView(image: "image.png")
imageView.alpha = 0.5

Related

Show multiple images in ViewController in Swift

I have tried the following code to load multiple images in sequence in my ViewController.
import SwiftUI
class ViewController: UIViewController {
var ctrl = MainPageController()
override func viewDidLoad() {
super.viewDidLoad()
Thread.sleep(forTimeInterval: 4.0)
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
var backgroundImageView = UIImageView(frame: CGRect(x:0, y:0, width: width, height: height))
backgroundImageView.image = UIImage(named: "loading")
backgroundImageView.contentMode = .scaleAspectFill
self.view.addSubview(backgroundImageView)
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView.removeFromSuperview()
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView = UIImageView(frame: CGRect(x:0, y:0, width: width, height: height))
backgroundImageView.image = UIImage(named: "loading1")
backgroundImageView.contentMode = .scaleAspectFill
self.view.addSubview(backgroundImageView)
Thread.sleep(forTimeInterval: 5.0)
backgroundImageView.removeFromSuperview()
self.performSegue(withIdentifier: "MainViewSegue", sender: self)
But I see only the second image. I want to load the first image, show it for about 5 seconds, then replace it with the second image, display that for 5 seconds. I have removed the image from the Launch.storyboard. Currently I cannot see any image. The self.performSegue works. How do I fix this problem?
Thanks
Vyasa
It looks like you are creating new image views. If you goal is to simply change the image after 5 seconds you can simplify this code to be something more like:
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height))
imageView.image = UIImage(named: "Load 1")
imageView.contentMode = .scaleAspectFill
self.view.addSubview(imageView)
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
// the code in this block will only execute after 5 seconds
imageView.image = UIImage(named: "Load 2")
}

Change barbutton image

I try change my barbutton image when user load image from photoLibrary or camera. But my barbutton image all time resize and make very big. How i can fix that?
I try use outlet. And here my code
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
self.imageData = image.pngData()!
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 24, height: 24)
button.layer.cornerRadius = 0.5
button.clipsToBounds = true
button.setImage(UIImage(data: imageData!), for: .normal)
photoBarButton.customView = button
picker.dismiss(animated: true, completion: nil)
}
If i try make something like this:
photoBarButton.image = image.withRenderingMode(.alwaysOriginal)
i get
You need to resize picked image first. Add below function to resize image:
extension UIImage {
func resizedImage(newSize: CGSize) -> UIImage? {
guard size != newSize else { return self }
let hasAlpha = false
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(newSize, !hasAlpha, scale)
UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0)
draw(in: CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height))
let newImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
Add above extension in your code and try to set image in UIBarButtonItem:
addAppointmentButton.image = pickedImage.resizedImage(newSize: CGSize(width: 24, height: 24))?.withRenderingMode(.alwaysOriginal)
Hope this will help you.

Swift how to change backIndicatorImage's position and size

I have got this code in my AppDelegate
UINavigationBar.appearance().backIndicatorImage = #imageLiteral(resourceName: "backarrow")
And this code shows something like this
How can i resize and change the position of the image?
Hi you can implement it the following way: -
var backImage = UIImage(named: "backarrow")
backImage = resizeImage(image: backImage!, newWidth: 40) //the width that you want for the back button image
UINavigationBar.appearance().backIndicatorImage = backImage
And here is the image resize function
func resizeImage(image: UIImage, newWidth: CGFloat) -> UIImage? {
let scale = newWidth / image.size.width
let newHeight = image.size.height * scale
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
You have to change the button by a custom one.
Define a UIBarButtonItem and replace the default one by your custom button.
var customButton = UIBarButtonItem(image: closeButtonImage, style: .plain, target: self, action: #selector(YourController.backPressed(_:)))
self.navigationItem. backBarButtonItem = customButton
Just use a custom UIBarButtonItem and hide the default one.
let backButton = UIBarButtonItem(image: UIImage(named: "Your_Back_Button_Image", style: .plain, target: self, action: #selector(popCurrentViewController)
self.navigationItem.setHidesBackButton(true, animated: true)
self.navigationItem.leftBarButtonItem = backButton
To implement back functionality:
func popCurrentViewController(_ animated: Bool)
{
_ = self.navigationController?.popViewController(animated: true)
}

UISlider making it square not rounded

why does it do this? how can i change it? and is there anyway to change the slider so the progress slider is not rounded but square?
http://imgur.com/F9Ye24v
I would prefer it to be square, the code is just a normal UI slider implementation. I only edited the
override func trackRectForBounds(bounds: CGRect) -> CGRect {
return CGRectMake(0, 0, self.frame.width, 25)
}
to make the bar taller
You can set the minimum and maximum track image.
Just use an image (rectangle without corner radius) with a width of 1px and height of 25px.
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISlider_Class/#//apple_ref/doc/uid/TP40006798-CH3-SW21
Sample:
slider.setMinimumTrackImage(UIImage(named: "back"), forState: UIControlState.Normal)
slider.setMaximumTrackImage(UIImage(named: "back"), forState: UIControlState.Normal)
The back image is just a blue square image of size 25px.
The back Image: (just copy and paste)
slider.setMaximumTrackImage(UIImage.imageWith(color: .yellow), for: .normal)
slider.setMinimumTrackImage(UIImage.imageWith(color: .cyan), for: .normal)
UIImage extension:
static func imageWith(color: UIColor, size: CGSize? = nil) -> UIImage? {
let rect = CGRect(x: 0, y: 0, width: size?.width ?? 1, height: size?.height ?? 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Simple
slider.setMinimumTrackImage(getImageWithColor(color: .blue, size: slider.frame.size), for: .normal)
func getImageWithColor(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}

How to make tappable UIImages that run functions?(Swift)

(I just started using Swift a few days ago and am relatively new to programming, so please bear with me.) I am trying to make random blocks appear on the screen, and the user must tap them to make them disappear. I have been able to create the blocks, but I have no idea how to actually make them tappable. Can someone please help me? This is my code so far:
func createBlock(){
let imageName = "block.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: xPosition, y: -50, width: size, height: size)
self.view.addSubview(imageView)
UIView.animateWithDuration(duration, delay: delay, options: options, animations: {
imageView.backgroundColor = UIColor.redColor()
imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)
}, completion: { animationFinished in
imageView.removeFromSuperview()
self.life-=1
})
}
I want to make the block disappear when tapped; any suggestions on how I can do that?
It's extremely simple to do, just use a UITapGestureRecognizer. I typically initialize the recognizer as a global variable.
let tapRecognizer = UITapGestureRecognizer()
Then in your viewDidLoad:
// Replace with your function
tapRecognizer.addTarget(self, action: "removeBlock")
imageView.addGestureRecognizer(tapRecognizer)
func removeImage(gesture: UIGestureRecognizer) {
gesture.view?.removeFromSuperview()
}
func createBlock() {
let imageName = "block.png"
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: xPosition, y: -50, width: size, height: size)
imageView.userInteractionEnabled = true // IMPORTANT
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "removeImage:"))
self.view.addSubview(imageView)
UIView.animateWithDuration(duration, delay: delay, options: options, animations: {
imageView.backgroundColor = UIColor.redColor()
imageView.frame = CGRect(x: self.xPosition, y: 590, width: self.size, height: self.size)
}, { _ in
imageView.removeFromSuperview()
self.life-=1
})
}
Notice imageView.userInteractionEnabled = true it is really important because that will allow touch events on that view, it is set to false as defaul in UIImgageView.