I am trying to change the image on my button depending on the position of a switch. I am not sure how to do this. I am relatively new to code. I have managed to change the other things on the screen but not the button. I have attached my code. I put this function into the IBAction for the switch:
func updateMySwitchState(){
if darkModeSwitch.isOn {
self.view.backgroundColor = UIColor.black
removeAds.textColor = UIColor.white
aboutText.textColor = UIColor.white
about.textColor = UIColor.white
backButton.setImage(UIImage(named: "backinvert-40"), for: .normal)
} else {
self.view.backgroundColor = UIColor.white
removeAds.textColor = UIColor.black
aboutText.textColor = UIColor.black
about.textColor = UIColor.black
backButton.setImage(UIImage(named: "back-40"), for: .normal)
}
}
Did you connected the outlet of the button with the controller?
You can set both images button image in storyboard itself for normal & selected state respectively. After setting call
backButton.setSelected(true) for first image and
backButton.setSelected(false) for the second
Related
Unselected button looks like this:
Selected button looks like this:
Why are there two shades of blue? How do I get rid of that paler shade of blue on the inside? I want the entire button to be a single solid color.
I've looked at .backgroundColor, thought maybe there was a .foregroundColor, but I can't find what is doing it...
Here is what I'm using:
func buttonArrayUpdated(buttonSelected: UIButton) {
for b in buttonsArray {
if b == buttonSelected {
selectedButton = b
b.isSelected = true
// default colors for state
b.backgroundColor = .blue
b.setTitleColor(.white, for: .selected)
}
else {
b.isSelected = false
// default colors for state
b.backgroundColor = .white
b.setTitleColor(.blue, for: .normal)
}
}
}
You can do as follows to remove that background color:
button.tintColor = .clear
I add a custom button to the tabBar in my MyViewController.viewDidLoad(subclass of UITabBarController)
But I find it doesn't response the selector.
If I delay one second to add button(in DispatchQueue.main.asyncAfter closure) ,it works OK.
I think it's not the right way to resolve it.
func addButton() {
let button = UIButton(type: UIButton.ButtonType.custom)
button.bounds = CGRect(x:0,y:0,width:30,height:30);
button.backgroundColor = UIColor.red
button.center = CGPoint(x:self.tabBar.frame.size.width/2, y:self.tabBar.frame.size.height/2 - 20);
button.addTarget(self, action: #selector(click(button:)), for: UIControl.Event.touchUpInside)
tabBar.addSubview(button)
}
You have added button to UITabBar of UITabBarController as half of part of the button would appear above the Tabbar and half of below the Tabbar as per frame.
So I guess you will not get click on part of that button which is out of Tabbar(above Tabbar) would not get touch. I you will make button little big OR try to click with arrow in simulator, you will get idea.
If you need to have button at bottom but slightly upper, then please create custom Tabbar to achieve design like this. Or else you can add that button into UITabBarController’s view instead of Tabbar.
class MyTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.addButton()
}
func addButton() {
let button = UIButton(type: UIButton.ButtonType.custom)
button.bounds = CGRect(x:0,y:0,width:50,height:50); //1
button.backgroundColor = UIColor.purple
button.center = CGPoint(x:self.tabBar.frame.size.width/2, y:self.tabBar.frame.size.height/2 - 50 + self.tabBar.frame.origin.y); //2
button.addTarget(self, action: #selector(click(button:)), for: UIControl.Event.touchUpInside)
button.layer.cornerRadius = button.frame.size.height/2
button.layer.masksToBounds = false
button.layer.shadowColor = UIColor.black.withAlphaComponent(0.5).cgColor
button.layer.shadowRadius = 5.0
button.layer.shadowOffset = CGSize(width: 0.0, height: 5.0)
button.layer.shadowOpacity = 0.5
//tabBar.addSubview(button) //3
self.view.addSubview(button). //4
}
#objc func click(button: UIButton) {
print("Button get clicked")
}
}
I have marked four things with commented by numbers at the end of lines, that you can make to your code and try.
I have a UIButton created programmatically and I need to add a forward icon which has to be created using UIBezierPath as shown in the figure below. How do I do that . I am a beginner in iOS and I need help.
The end result I want is this
The code I have is this:
let forwardButton : UIButton = {
let fb = UIButton()
fb.translatesAutoresizingMaskIntoConstraints = false
fb.backgroundColor = UIColor(red:0.56, green:0.07, blue:1.00, alpha:1.0)
return fb
}()
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
forwardButton.bounds.size.width
forwardButton.layer.masksToBounds = true
}
I have code for circular button but I don't know how to draw forward icon using bezierpath inside the circular button. any help would be appreciated
You can add this code :
fb.setImage(UIImage(named: "yourImageName.png"), for: .normal)
If you are using xcasset you can use (no need .png):
if let image = UIImage(named: "Done") {
fb.setImage(image, for: .normal)
}
I recently asked a question here where I wanted to understand how to change the UIColor of a button's image. I followed #Dorian Roy's recommendation which was very clean and it worked well for my needs. While my specific question previously was around a single button, I would like to know how to change multiple UIBUttons. Can this be done? My thought would be to subclass a UIButton and initialize it to automatically change its image color. I can't quite grasp how to do this though.
Here is how I am currently performing this action and I am seeking a more elegant solution.
private func changeBtnColors() {
let ccStencil = creditCardBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let planeStencil = planeBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let towelStencil = towelBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let carStencil = carBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let trainStencil = trainBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let graphStencil = graphBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
creditCardBtn.setImage(ccStencil, for: .normal)
planeBtn.setImage(planeStencil, for: .normal)
towelBtn.setImage(towelStencil, for: .normal)
carBtn.setImage(carStencil, for: .normal)
trainBtn.setImage(trainStencil, for: .normal)
graphBtn.setImage(graphStencil, for: .normal)
creditCardBtn.tintColor = UIColor.white
planeBtn.tintColor = UIColor.white
towelBtn.tintColor = UIColor.white
carBtn.tintColor = UIColor.white
trainBtn.tintColor = UIColor.white
graphBtn.tintColor = UIColor.white
}
The simplest way is create one array of UIButton and loop through all the elements.
let buttonArray = [creditCardBtn, planeBtn, towelBtn, carBtn, trainBtn, graphBtn]
buttonArray.forEach { button in
let image = button.imageView?.image?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.white
}
You can also create extension of UIButton and put this settings code of Button in a function like this.
extension UIButton {
func setImageWithRandringMode() {
let image = self.imageView?.image?.withRenderingMode(.alwaysTemplate)
self.setImage(image, for: .normal)
self.tintColor = .white
}
}
And now simply call this function with forEach closure.
buttonArray.forEach { button in
button.setImageWithRandringMode()
}
I have a scrollview inside a view. Inside the scrollview I create programmatically 5 buttons. Every button loads a different image with a different tag each one. I added a function that is called when pressing the buttons.
let avatarsListScrollingView = avatarsListView(CGSizeMake(70.0, 55.0), avatarCount: 5)
func avatarsListView(buttonSize:CGSize, avatarCount:Int) -> UIView {
**CODE**
for i in 0...(avatarCount-1) {
let button = UIButton(type: .Custom)
**CODE**
button.setImage(UIImage(named: avatarsList[i]), forState: .Normal)
button.tag = i
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
avatarButtonView.addSubview(button)
}
return avatarButtonView
}
Then when pressing the buttons, I call to "avatarListSelected":
func avatarListSelected(sender:UIButton){
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
self.addAvatarView.reloadInputViews()
}
This function tints the image button to red, it is working fine, but the problem is that when I press some other button, I want the other one goes to the original color. Right now every button that I press gets in red.
I tried to add the call to "self.addAvatarView.reloadInputViews()" to try to "redraw" again all the buttons, but never gets called.
Do you guys know some way to do this?
Thanks to everybody!
This is the final code that solved the problem:
func avatarListSelected(sender:UIButton){
print(sender.tag)
if let image = sender.imageView?.image?.imageWithRenderingMode(.AlwaysTemplate) {
sender.setImage(image, forState: .Normal)
sender.tintColor = UIColor.redColor()
}
for view in self.avatarButtonView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn.tag != sender.tag {
btn.setImage(UIImage(named: avatarsList[btn.tag]), forState: .Normal)
}
}
}
}
Create a property selectedButton: UIButton? and keep a reference to the selected button there. Don't forget to update it in avatarListSelected method and before you change it, if it isn't nil, change its color to original (and then change it).
If the buttons have different original colors, subclass UIButton class and keep the original color there.
I don't know if is better approach or answer, but, i maybe could delivery this using this approach:
Create a method that will "fill" the color for your choice button and "clear" color to others , but its a method that loop through UIScrollView and look for each UIButton. Something like this :
func setBackgroundColorButton(color:UIColor , buttonTag:Int){
for view in self.scrollView.subviews as [UIView] {
if let btn = view as? UIButton {
if btn == buttonTag {
btn.tintColor = color
} else {
btn.tintColor = UIColor.whiteColor()
}
}
}
}
This is the concept, i didn't tested, but maybe just need adjust to search inside your scroll view or similar.
But with this will be work nice i believe :D
You could do it like this
for i in 0...5 {
let button = UIButton(type: .Custom)
let x = 50 * i + 10
let y = 50
button.frame = CGRectMake(CGFloat(x), CGFloat(y), 40, 40)
button.setTitle("\(i)", forState: .Normal)
button.tag = i
button.backgroundColor = UIColor.greenColor()
button.tintColor = UIColor.blueColor()
button.addTarget(self, action: "avatarListSelected:", forControlEvents: .TouchUpInside)
self.view.addSubview(button)
}
func avatarListSelected(sender : UIButton){
sender.backgroundColor = UIColor.orangeColor()
for view in self.view.subviews{
if(view.isKindOfClass(UIButton)){
let button = view as! UIButton
if button.tag != sender.tag{
button.backgroundColor = UIColor.greenColor()
}
}
}
}
The frame etc is just for demonstation purpose only, you should of course use your own value. The tintColor property is not valid for all button types. Read the documentation for more information.