UISlider making it square not rounded - swift

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
}

Related

Unable to get an image to fit inside the bounds of a UITextField

I'm trying to get the image to scale down to the size of the UITextField and to position itself to the left side of it, but I am only able to get this:
What am I doing wrong?
Here is the relevant code:
//MARK: - Add Left Image to UITextField
func addLeftImageTo(txtField: UITextField, image img: UIImage) {
let leftImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
leftImageView.image = img
txtField.addSubview(leftImageView)
txtField.leftView = leftImageView
txtField.leftViewMode = .always
}
let image1 = UIImage(named: "stopwatch")
addLeftImageTo(txtField: timerTextField, image: image1!)
timerTextField.anchor(top: repsTextField.bottomAnchor, leading: view.safeAreaLayoutGuide.leadingAnchor, bottom: notesTextField.topAnchor, trailing: view.safeAreaLayoutGuide.trailingAnchor, padding: .init(top: 50.adjusted, left: 100.adjusted, bottom: 50.adjusted, right: 100.adjusted))
Try wrapping the UIImageView in a UIView
Your code:
func addLeftImageTo(txtField: UITextField, image img: UIImage) {
let leftImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
leftImageView.image = img
txtField.addSubview(leftImageView)
txtField.leftView = leftImageView
txtField.leftViewMode = .always
}
Example:
func addLeftImageTo(txtField: UITextField, image img: UIImage) {
let height = txtField.frame.size.height
let wrapView = UIView(frame: CGRect(x: 0, y: 0, width: height, height: height))
let leftImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: height, height: height))
leftImageView.image = img
leftImageView.contentMode = .scaleToFill
wrapView.addSubview(leftImageView)
txtField.addSubview(wrapView)
txtField.leftView = wrapView
txtField.leftViewMode = .always
}
Also, I added some lines including height, contentMode just in case.
I hope it will be helpful for you.
first make below method for adding image in UITextField
func setleftPaddingInTextfieldwithImage(_ textfield : UITextField, padding :
CGFloat, strImgname : String)
{
let imageView = UIImageView(image: UIImage(named: strImgname))
imageView.frame = CGRect(x: 0, y: 0, width: 15 , height: 15)
imageView.contentMode = .scaleAspectFit
let paddingView = UIView.init()
paddingView.frame = CGRect(x: padding, y: 0, width: padding, height: textfield.frame.size.height)
paddingView.addSubview(imageView)
textfield.leftView = paddingView
textfield.leftViewMode = .always
}
call it in your viewcontroller
self.setleftPaddingInTextfieldwithImage(YourTextField, padding: padding, strImgname: "stopwatch")

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:

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.

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:

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