UIButton UIEdgeInsets doesn't work - ios

So I've looked at all projects on Stack Overflow for adding edge insets for UIImages in a UIButton but none of them worked. When I build the project, the image is just set through the bounds of the button - it's not set to the insets and I don't know why. Here is the code:
let Settingsbutton = AnimatableButton(frame: CGRect(x: 23, y: 30, width: 40, height: 40))
Settingsbutton.layer.cornerRadius = Settingsbutton.frame.size.height / 2
Settingsbutton.layer.backgroundColor = UIColor.white
let roundedButton3 = UIButton(type: .custom)
roundedButton3.frame = Settingsbutton.frame
let _border3 = CAShapeLayer()
_border3.path = UIBezierPath(roundedRect: roundedButton3.bounds, cornerRadius:roundedButton3.frame.size.width/2).cgPath
_border3.frame = roundedButton3.bounds
_border3.strokeColor = UIColor.white.cgColor
_border3.fillColor = UIColor.clear.cgColor
_border3.lineWidth = 3.0
Settingsbutton.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)
Settingsbutton.contentVerticalAlignment = .fill
Settingsbutton.contentHorizontalAlignment = .fill
Settingsbutton.layer.addSublayer(_border3)
self.view.addSubview(Settingsbutton)
self.view.bringSubview(toFront: Settingsbutton)
if PFUser.current() == nil{
Settingsbutton.setBackgroundImage(UIImage(named: "padlock"), for: .normal)
}else{
}

imageEdgeInsets are for positioning the image NOT the background image!
Use setImage instead of setBackgroundImage

If AnimatableButton is a UIButton why you want to add button inside button? I don't know really what's your purpose but you might try
Settingsbutton.contentEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)

Related

SetImage() method removes titleLabel for UIButton

My wish is to make centered image(left) and next to it(right) the label.
Without setting an image, there was a perfectly centered titleLabel:
btnWhatsapp.titleLabel?.adjustsFontSizeToFitWidth = true
btnWhatsapp.setTitle("WhatsApp", for: .normal)
Then I added this code to add an image:
btnWhatsapp.setImage(UIImage(named: "phoneIcon"), for: .normal)
btnWhatsapp.imageView?.layer.transform = CATransform3DMakeScale(0.5, 0.6, 0.5)
btnWhatsapp.imageView?.contentMode = .scaleAspectFit
, and this iswhat I got then:
, so the title disappeared.
Maybe the problem is that image uses more space than its actual size(the size shouldnt take more widht and height than the icon size). I saw this when changed images background(should be this much grey color):
btnWhatsapp.imageView?.backgroundColor = .gray
I tried to use the imageEdgeInsets but it is very hard to calculate it to fit perfectly on every iPhone.
This is the Attributes inspector of the button:
You can't set title and image at once by default, nor position them as you describe.
If you need to have a UIButton, I'd recommend to make a UIView (or possibly horizontal UIStackView) with UIImage and UILabel inside, position them with autolayout, then you can add this view to the UIButton as a subview.
let button = UIButton(type: .custom)
button.frame = viewFrame // This is the desired frame of your custom UIView or UIStackView
button.addSubview(customView)
You will be able to position the views easily for all sizes with this approach, but you will probably want to use autolayout in real word app, instead of hardcoded frames.
Example:
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImageView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
label.text = "text"
let stack = UIStackView(arrangedSubviews: [image, label])
stack.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
stack.distribution = .fillEqually
let button = UIButton()
button.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
button.addSubview(stack)
view.addSubview(button)
self.view.addSubview(button)
}
Set your button under your controller class like this:
let imageButton: UIButton = {
let b = UIButton(type: .custom)
b.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
b.layer.cornerRadius = 12
b.clipsToBounds = true
b.translatesAutoresizingMaskIntoConstraints = false
let imageV = UIImageView()
imageV.image = UIImage(named: "yourImage")?.withRenderingMode(.alwaysTemplate)
imageV.tintColor = .white
imageV.contentMode = .scaleAspectFill
imageV.translatesAutoresizingMaskIntoConstraints = false
imageV.widthAnchor.constraint(equalToConstant: 30).isActive = true
let label = UILabel()
label.text = "WhatsApp"
label.textColor = .white
label.font = .systemFont(ofSize: 16, weight: .regular)
let stack = UIStackView(arrangedSubviews: [imageV, label])
stack.distribution = .fill
stack.spacing = 4
stack.axis = .horizontal
stack.translatesAutoresizingMaskIntoConstraints = false
b.addSubview(stack)
stack.heightAnchor.constraint(equalToConstant: 30).isActive = true
stack.widthAnchor.constraint(equalToConstant: 120).isActive = true
stack.centerXAnchor.constraint(equalTo: b.centerXAnchor).isActive = true
stack.centerYAnchor.constraint(equalTo: b.centerYAnchor).isActive = true
return b
}()
Now in viewDidLoad add button and set constraints in your view (in my case on top)
view.addSubview(imageButton)
imageButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
imageButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
imageButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
imageButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
This is the result:

Material design Outline textfield with white background

Im trying to use material components library and make a textfield with outline and background color, but this is what I get
The white is outside the bounds.
Can you help me?
this is my code
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
imageView.image = UIImage(named: "user")
txtfieldEmail.placeholderLabel.textColor = UIColor.gray
txtfieldEmail.leftView = imageView
txtfieldEmail.leftViewMode = .always
//txtfieldEmail.backgroundColor = UIColor.white
//txtfieldEmail.translatesAutoresizingMaskIntoConstraints = false
//txtfieldEmail.clipsToBounds = true
txtfieldEmail.layer.backgroundColor = UIColor.white.cgColor
usernameTextFieldController = MDCTextInputControllerOutlined(textInput: txtfieldEmail)
After I kept editing the form and adding more content, I ended up finding that we should be defining the style in the MDCTextInputControllerOutlined
So all I had to do was usernameTextFieldController?.borderFillColor = UIColor.white

button does not work after adding uiview in swift 4

let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
After making a button, I wanted to move it little bit to the right. So, i made UI View to move the button inside the view. But, then, after this, the button does not work anymore. Can anyone tell me the solution?
Your code is working fine but need to clarify some points.
Reason Your button not working is below 4 lines
let WidthConstraint = Searchbutton.widthAnchor.constraint(equalToConstant: 30)
let HeightConstraint = Searchbutton.heightAnchor.constraint(equalToConstant: 30)
WidthConstraint.isActive = true
HeightConstraint.isActive = true
As you already set UIButton frame then no need to use of above lines of code.
Yellow color view is your SearchView and green color is your UIButton.
If you use Searchbutton frame like Searchbutton.frame = CGRect(x: -17, y: -20, width: 30, height: 30) then it happens something like below image.
You added UIButton as subview of UIView and when you click on green button which is inside yellow View will work but the area which is outside Yellow area doesn't work.
You need to start UIButton frame from 0,0,30,30
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
or you can directly set UIButton frame same as UIView frame then it looks like below image.
Searchbutton.frame = SearchView.frame
Below is your Working Code.
let SearchView = UIView()
SearchView.backgroundColor = UIColor.clear
SearchView.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: SearchView)
self.navigationItem.rightBarButtonItem = barButtonItem
SearchView.addSubview(Searchbutton)
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
//right search button
You're doing a lot of unnecessary things here. Firstly, you don't need to put your Button in a container view to put it as the right bar button item.
You also don't need to add constraints to your searchbutton, since you have given it a fixed frame.
let Searchbutton = UIButton(type: .system)
Searchbutton.setImage(UIImage (named: "SEARCH"), for: .normal)
Searchbutton.backgroundColor = .clear
Searchbutton.frame = CGRect(x: 0, y: 0, width: 50, height: 50)
Searchbutton.contentMode = .scaleAspectFit
let barButtonItem = UIBarButtonItem(customView: Searchbutton)
self.navigationItem.rightBarButtonItem = barButtonItem
Searchbutton.addTarget(self, action: #selector(viewanewcontroller(button:)), for: .touchUpInside)
Also as Pratik's comment said, you're meant to use lower camel case. so SearchView should be searchView and SearchButton as searchButton
As for moving it to the right, it seems like that isn't possible anymore without either subclassing the UINavigationBar and changing the implementation, or by making UIViews look exactly like the standard Navigation Bar.
Get rid of the space on the right side of a UINavigationBar

imageView in iOS 11 using Swift

I created 2 customs buttons in my navigation Controller. I have one left button and one right, and both have some text + an arrow icon. Since I updated to iOS 11, the size of icons has changed and I don't know why.
This this the difference between iOS 10 (Left) and iOS 11 (right):
How can I change that?
This is a piece of my code:
func addRightButton(){
rightButton = UIButton.init(type: .custom)
rightButton.setImage(UIImage(named: "back"), for: .normal)
rightButton.imageView?.contentMode = .scaleAspectFit
let width = UIScreen.main.bounds.size.width
if width < 375 {
rightButton.titleLabel?.font = UIFont.systemFont(ofSize: 13, weight: UIFont.Weight.bold)
rightButton.frame = CGRect.init(x: 0, y: 0, width: 75, height: 10)
} else {
rightButton.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
rightButton.frame = CGRect.init(x: 0, y: 0, width: 100, height: 10)
}
rightButton.imageView!.transform = rightButton.imageView!.transform.rotated(by: CGFloat((Double.pi / 2) * -1))
rightButton.setTitle(" Mixte",for: .normal)
rightButton.addTarget(self, action: #selector(self.switchSex(_:)), for: UIControlEvents.touchUpInside)
let barButton = UIBarButtonItem(customView: rightButton)
self.navigationItem.rightBarButtonItem = barButton
}
You need to add width constraint for your button in xCode 9. Like this:
let width = yourButton.widthAnchor.constraint(equalToConstant: 75)
let height = yourButton.heightAnchor.constraint(equalToConstant: 10)
heightConstraint.isActive = true
widthConstraint.isActive = true

How to resize an image inside an UIButton programmatically?

I have this UIButton and an image to fit in.
I don't want that the image take all the space inside the button but just a little part of it right in the center, but if I resize the button it will resize the image too.
How can I do that, is there an option to set whatever dimension I want independently from the size of the UIButton?
Thanks!
This can be done through code in the following way:
let imageSize:CGSize = CGSize(width: 20, height: 20)
let button:UIButton = UIButton(type: UIButton.ButtonType.custom)
button.frame = CGRect(x: 200, y: 200, width: 60, height: 60)
button.backgroundColor = UIColor.yellow
button.setImage(UIImage(named: "chat.png"), for: UIControl.State.normal)
// The below line will give you what you want
button.imageEdgeInsets = UIEdgeInsets(
top: (button.frame.size.height - imageSize.height) / 2,
left: (button.frame.size.width - imageSize.width) / 2,
bottom: (button.frame.size.height - imageSize.height) / 2,
right: (button.frame.size.width - imageSize.width) / 2)
self.view.addSubview(button)
This way, you can achieve what you wanted.
I couldn't get the button's imageView to resize until I used contentHorizontalAlignment and contentVerticalAlignment both set to .fill. Then using imageEdgeInsets I repositioned the image.
let button = UIButton()
let image = UIImage(systemName: "bag.badge.plus")
button.setImage(image, for: .normal)
button.contentHorizontalAlignment = .fill
button.contentVerticalAlignment = .fill
button.imageEdgeInsets = UIEdgeInsets(top: 6, left: 6, bottom: 10, right: 10)
Result:
You can experiment with image view insets. Every UIButton has a property imageView.
In Swift 3 you can do this like so:
//let button = UIButton()
button.imageView?.backgroundColor = UIColor.red
button.imageEdgeInsets = UIEdgeInsetsMake(10, 10, 10, 10)
red background is just so you know what is changing
I would do it this way:
A UIButton is just a UIView. You can simply add a UIImageView with a set image and call addSubview on the UIButton.
Taking into account what KVISH said before i have implemented this and it worked as expected. I posted this because Houman asked for an example.
//grab the image using the name of the pic
var image = UIImage(named: "picture")
//set the size for the image
image = image?.resize(toWidth: 18)
image = image?.resize(toHeight: 18)
//set the image to the button
buttonName.setImage(image, for: UIControlState.normal)
//adjust the position
buttonName.imageEdgeInsets = UIEdgeInsetsMake(8,16,9,0)
As of iOS 13, when using SF Symbols, I prefer this:
let button = UIButton()
let font = UIFont.systemFont(ofSize: 30) // <- make it larger, smaller, whatever you want.
let config = UIImage.SymbolConfiguration(font: font)
let image = UIImage(systemName: "bag.badge.plus", withConfiguration: config)
button.setImage(image, for: .normal)
These can be achieved by adding imageEdgeInsets to a UIButton.
In swift4.2
button.imageEdgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)

Resources