Change barbutton image - swift

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.

Related

Change UIBarButton image from gallery

I have UIBarButton and user can change image just chose photo or gallery image with image picker. My problem is bad scale image.
If I use AspectFit my UIBarButton look like this:
If I use AspectFill my UIBarButton look like this:
and if I try first change size image and after set it, image all time scratched:
This is my code:
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
imageView.image = image?.resizedImage(newSize: CGSize(width: 35, height: 35))?.withRenderingMode(.alwaysOriginal)
// imageView.image = cropToBounds(image: image!, width: 35, height: 35)
// imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
And here func for resize image:
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
}
Help me plz find the right way to resolving my problem.
As I understand your question. I found a solution.
Try this
func createPhotoBarButton(image: Data) {
let barbtn = UIBarButtonItem()
let imageView = UIImageView(frame: CGRect(x: 0.0, y: 0.0, width: 35.0, height: 35.0))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")?.resize(maxWidthHeight: Double(imageView.frame.size.width))
}
imageView.image = image
imageView.contentMode = .scaleAspectFill
imageView.layer.cornerRadius = imageView.frame.size.height / 2
imageView.layer.masksToBounds = true
imageView.clipsToBounds = true
self.navigationItem.rightBarButtonItem = barbtn
barbtn.customView = imageView
barbtn.customView?.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(photoTapped(_:))))
}
Resize method
extension UIImage {
func resize(maxWidthHeight : Double)-> UIImage? {
let actualHeight = Double(size.height)
let actualWidth = Double(size.width)
var maxWidth = 0.0
var maxHeight = 0.0
if actualWidth > actualHeight {
maxWidth = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualWidth)
maxHeight = (actualHeight * per) / 100.0
}else{
maxHeight = maxWidthHeight
let per = (100.0 * maxWidthHeight / actualHeight)
maxWidth = (actualWidth * per) / 100.0
}
let hasAlpha = true
let scale: CGFloat = 0.0
UIGraphicsBeginImageContextWithOptions(CGSize(width: maxWidth, height: maxHeight), !hasAlpha, scale)
self.draw(in: CGRect(origin: .zero, size: CGSize(width: maxWidth, height: maxHeight)))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
return scaledImage
}
}
Output
Try to create a custom button with the code below:
func createPhotoBarButton(image: Data) {
let imageBtnContainer = UIButton()
let imageBtn = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
var image = UIImage(data:image)
if image == nil {
image = UIImage(named: "photoIcon")
}
imageBtn.setImage(image, forState: UIControlState.Normal)
imageBtn.frame = CGRectMake(0, 0, 53, 31)
imageBtn.imageView?.contentMode = .scaleAspectFit
imageBtnContainer.addSubview(imageBtn)
self.navigationItem.rightBarButtonItem = UIBarButtonItem(customView: imageBtnContainer)
...
}
You don't need anymore resizedImage(..) function
Here is working code (swift 4)
override func viewDidLoad() {
let containView = UIView(frame: CGRect(x: 0, y: 0, width: 35, height: 35))
let Button : UIButton = UIButton.init(type: .custom)
Button.frame = CGRect(x: 0, y: 0, width: 35, height: 35)
Button.Round = true
Button.setImage(UIImage(named: "photoIcon"), for: .normal)
Button.addTarget(self, action: #selector(btnTapped), for: .touchUpInside)
containView.addSubview(Button)
let rightBarButton = UIBarButtonItem(customView: containView)
self.navigationItem.rightBarButtonItem = rightBarButton
}
Button Action Here
#objc func btnTapped(_ sender: Any) {
print("Click Event")
}
Extension to Round
extension UIView{
#IBInspectable var Round:Bool{
get{
return false
}
set{
if newValue == true {
self.layer.cornerRadius = self.frame.size.height/2;
self.layer.masksToBounds = true;
}
}
}
}
Output:

Image selected from imagePickerController takes up whole screen instead of fitting inside of UI Image View [Swift]

I have an image view that is programmatically created within a container view as such:
Screen shot with circular profile image view inside container view
I have a button overlay on top of the profile image view to call the image picker controller. When an image is selected from the photo library, the image takes up the entire screen as below:
Screenshot after image is selected
Here is the code for this view controller's viewDidLoad() and imagePickerController():
override func viewDidLoad() {
super.viewDidLoad()
self.profileBackgroundView.backgroundColor = UIColor.init(red: CGFloat(69.0/255.0), green: CGFloat(171.0/255.0), blue: CGFloat(222.0/255.0), alpha: CGFloat(1))
//initializePrimaryUserData()
fullNameTextField.text = self.primaryUser.firstName + self.primaryUser.lastName
nickNameTextField.text = self.primaryUser.userName
//create profile image view
if hasProfilePic {
profileImage.image = self.primaryUser.image
} else {
image = UIImage(named: imageName)!
profileImage.image = image
}
profileImage.frame = CGRect(x: profileBackgroundView.bounds.midX, y: profileBackgroundView.bounds.midY, width: 100, height: 100)
profileImage.translatesAutoresizingMaskIntoConstraints = false
profileBackgroundView.addSubview(profileImage)
profileImage.centerXAnchor.constraint(equalTo: profileBackgroundView.centerXAnchor).isActive = true
profileImage.centerYAnchor.constraint(equalTo: profileBackgroundView.centerYAnchor).isActive = true
profileImage.layer.cornerRadius = profileImage.frame.size.width / 2
profileImage.layer.masksToBounds = false
profileImage.clipsToBounds = true
profileImage.contentMode = .scaleAspectFit
//create profileImageButton
let profileImageButton = UIButton(frame: CGRect(x: profileBackgroundView.bounds.midX, y: profileBackgroundView.bounds.midY, width: 100, height: 100))
profileImageButton.setTitle("Photo", for: .normal)
profileImageButton.addTarget(self, action: #selector(profileImageButtonClicked), for: .touchUpInside)
profileImageButton.translatesAutoresizingMaskIntoConstraints = false
profileBackgroundView.addSubview(profileImageButton)
profileImageButton.centerXAnchor.constraint(equalTo: profileBackgroundView.centerXAnchor).isActive = true
profileImageButton.centerYAnchor.constraint(equalTo: profileBackgroundView.centerYAnchor).isActive = true
// Do any additional setup after loading the view.
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
if let image = info[UIImagePickerControllerOriginalImage] as? UIImage {
self.primaryUser.image = image
self.hasProfilePic = true
self.profileImage.image = image
self.profileImage.contentMode = .scaleAspectFit
self.profileImage.clipsToBounds = true
}
self.dismiss(animated: true, completion: nil)
}
You can try this
self.profileImage.contentMode = .scaleToFill

Rounded corners for UITabBar

I would like to create a UITabBar with rounded corners. Is there a way I can make the UITabBar have rounded corners? It would take the shape of the second picture.
The app starts off with a tableView. When the user taps a topic, they are sent to a tabBar controller.
-----edit-----
This is my AppDelegate:
func application(_application: UIApplication,
willFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool{
let tabBarController = window?.rootViewController as! UITabBarController
let image = UIImage(named: "bar")
let tabBarImage = resize(image: image!, newWidth: tabBarController.view.frame.width)
tabBarController.tabBar.backgroundImage = tabBarImage
return true
}
func resize(image: UIImage, newWidth: CGFloat) -> UIImage {
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: image.size.height))
image.drawInRect( CGRect(x: 0, y: 0, width: newWidth, height: image.size.height))
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
Edit: Dec '21
Replaced image to omit name on project.
Hope this help you
self.tabBar.layer.masksToBounds = true
self.tabBar.isTranslucent = true
self.tabBar.barStyle = .blackOpaque
self.tabBar.layer.cornerRadius = 20
self.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
Its working fine for me
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.tabBarController?.tabBar.layer.masksToBounds = true
self.tabBarController?.tabBar.isTranslucent = true
self.tabBarController?.tabBar.barStyle = .default
self.tabBarController?.tabBar.layer.cornerRadius = 25
self.tabBarController?.tabBar.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}
Hey I used a simple property of the tabBar which is backgroundImage.
So, I added in the appDelegate in didFinisLaunchingWithOptions:
let tabBarController = window?.rootViewController as! UITabBarController
let image = UIImage(named: "bar")
let tabBarImage = resize(image: image!, newWidth: tabBarController.view.frame.width)
tabBarController.tabBar.backgroundImage = tabBarImage
and my custom method to change the size of the image:
func resize(image: UIImage, newWidth: CGFloat) -> UIImage {
UIGraphicsBeginImageContext(CGSize(width: newWidth, height: image.size.height))
image.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: image.size.height)) // image.drawInRect( CGRect(x: 0, y: 0, width: newWidth, height: image.size.height)) in swift 2
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
I used a png image as the background, the same that you posted but with clear color instead of the black color.
Hope this helps
self.tabBarController?.tabBar.layer.cornerRadius = 20
self.tabBarController?.tabBar.layer.masksToBounds = true
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
let path = UIBezierPath(roundedRect: CGRect(x: 0, y: 0, width: view.frame.width, height: tabBar.frame.height), cornerRadius: 15)
let mask = CAShapeLayer()
mask.path = path.cgPath
tabBar.layer.mask = mask
}
In my case works this way:
import UIKit
#IBDesignable
class CustomTabBar: UITabBar {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
private func setup() {
layer.masksToBounds = true
isTranslucent = true
barStyle = .blackOpaque
layer.cornerRadius = 44
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}
}
Then set class CustomTabBar for TabBar in storyboard:

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 set the alpha of an UIImage in SWIFT programmatically?

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