iOS - UIButton system selected image - ios

I have a UIButton with a transparent image with a toggle for selected.
In the current configuration I am using the system button type, because it inverts the button nicely. However with this inverting, I get an image with borders, and I want this image to fill the whole button. How can this be achieved? I would like to keep the transparent mask from system.
Here is the repository.
In the image below is what the selected system state looks like.

Create Subclass of UIButton and override the isSelected
For Example
class CustomButton: UIButton {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
override var isSelected: Bool {
didSet {
if isSelected {
self.backgroundColor = UIColor.blue
self.tintColor = UIColor.white
} else {
self.backgroundColor = .white
self.tintColor = UIColor.red
}
}
}
}
Change Color according to your requirements
And in view Controller Do Like this
class ViewController: UIViewController {
#IBOutlet weak var button: CustomButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
button.isSelected = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnTapped(_ sender: Any) {
button.isSelected = !button.isSelected
}
}
And there is one more thing you have to set Render option of image to Template

Related

Is it possible to define tint color for a disabled UIButton?

For some reason, I want to define my own tint color, when an UIButton is disabled.
I thought it is able to achieve so based on
https://stackoverflow.com/a/45835079/72437
import UIKit
class UIButtonEX: UIButton {
override var isEnabled: Bool {
didSet{
if self.isEnabled {
self.tintColor = UIColor.red
}
else{
self.tintColor = UIColor.red
}
}
}
}
class ViewController: UIViewController {
#IBOutlet weak var button: UIButtonEX!
#IBOutlet weak var disabledButton: UIButtonEX!
override func viewDidLoad() {
super.viewDidLoad()
button.isEnabled = true
disabledButton.isEnabled = false
//button.tintColor = .red
//disabledButton.tintColor = .red
}
}
The right button is disabled UIButton. I wish it would stay in red even it is disabled.
However, it is still painted as default system light grey.
May I know, what steps I have missed out? Is it possible to define tint color for a disabled UIButton?
Thanks.
You may have to try something like this, and this works when you are using the system named images.
class UIButtonEX: UIButton {
override func tintColorDidChange() {
if tintAdjustmentMode == .dimmed {
// modify subviews to look disabled
// In your case tou have to heep as it is
tintAdjustmentMode = .normal
} else {
// modify subviews to look enabled
}
}
}
Try this:
class UIButtonEX: UIButton {
override func didMoveToSuperview() {
super.didMoveToSuperview()
adjustsImageWhenDisabled = false
setTitleColor(tintColor, for: .disabled)
}
}

Delegation between two ViewControllers without segues

I am learning the concept of delegation and I am stuck in my project. I believe the solution is simple, but as this is something new for me I have no idea what is wrong.
Project concept is simple:
There are two views in the application. In the first view you press the button "change the color" and as a result second view appears. In the second view there are three text fields where user puts numbers respectively for R G and B values in RGB color. When the button is tapped, second view disappears and the first view's background should be changed with color based on the user's input. I assume that the user put correct numbers, therefore at this moment I use forced unwrapping for those values.
At this moment views appear correctly, but the background color of the first view does not change and I have no idea why.
Beneath is the code for two view controllers. I will appreciate any hints.
First VC: ViewController.swift
class ViewController: UIViewController, ColorChangeDelegate {
let secondStoryboard = UIStoryboard(name: "Second", bundle: nil).instantiateViewControllerWithIdentifier("SecondViewController") as UIViewController
var secondVC = SecondViewController()
#IBAction func changeColourButtonTapped(sender: UIButton) {
presentViewController(secondStoryboard, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
secondVC.colorDelegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func didChangeColor(controller: SecondViewController, color: UIColor) {
self.view.backgroundColor = color
}
}
and second VC: SecondViewController.swift
protocol ColorChangeDelegate {
func didChangeColor(controller: SecondViewController, color: UIColor)
}
class SecondViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var myRTextField: UITextField!
#IBOutlet weak var myGTextField: UITextField!
#IBOutlet weak var myBTextField: UITextField!
var colorDelegate : ColorChangeDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
myRTextField.delegate = self
myGTextField.delegate = self
myBTextField.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textFieldDidBeginEditing(textField: UITextField) {
textField.becomeFirstResponder()
}
#IBAction func goButtonTapped(sender: UIButton) {
let r = Int(myRTextField.text!)!
let g = Int(myGTextField.text!)!
let b = Int(myBTextField.text!)!
let color = UIColor(red: CGFloat(r), green: CGFloat(g), blue: CGFloat(b), alpha: 1.0)
self.view.endEditing(true)
colorDelegate?.didChangeColor(self, color: color)
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
}
}
You are assigning your delegate to secondVC but the view controller that is actually being presented is in secondStoryboard, so you should set the colorDelegate property of secondStoryboard.

Data can not be saved after the transition between ViewControllers

The purpose for my app
I have two ViewControllers,FrontSideViewController and BackSideViewController, in my little project.
I am about to flipping FrontSideViewController to BackSideViewController through using CATransition while each ViewController's data can be saved.
Describe of Problem
The views transited in the unexpected way which animation is not seem like the UIAnimationTransition.FlipFromLeft(or)Right thing.
After flipping views, the previous view's data can not be saved, which means when I flipped back the old view, its tiny data (something like textField's text) is just gone.
My Code
Same Logical function to flip between the views which be used in two Classes.
FrontSideViewController.swift
class FrontSideViewController: UIViewController {
var frontSideViewController: FrontSideViewController?
var backSideViewController: BackSideViewController?
var frontSide: Bool = true
#IBOutlet weak var flip_1Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
frontSideViewController = storyboard?.instantiateViewControllerWithIdentifier("FrontSideViewController") as? FrontSideViewController
backSideViewController = storyboard?.instantiateViewControllerWithIdentifier("BackSideViewController") as? BackSideViewController
flip_1Button.addTarget(self, action: "flipViews", forControlEvents: UIControlEvents.TouchUpInside)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func textFieldDoneEditing(sender: UITextField) {
sender.resignFirstResponder()
}
func flipViews() {
UIView.beginAnimations("ViewSwitch", context: nil)
UIView.setAnimationDuration(0.6)
UIView.setAnimationCurve(.EaseInOut)
UIView.setAnimationTransition(.FlipFromLeft, forView: view, cache: true)
backSideViewController?.view.frame = self.view.frame
frontSideViewController?.willMoveToParentViewController(nil)
frontSideViewController?.view.removeFromSuperview()
frontSideViewController?.removeFromParentViewController()
self.addChildViewController(backSideViewController!)
self.view.addSubview(backSideViewController!.view)
backSideViewController?.didMoveToParentViewController(self)
}
}
BackSideViewController.swift
class BackSideViewController: UIViewController {
var frontSideViewController: FrontSideViewController?
var backSideViewController: BackSideViewController?
#IBOutlet weak var flip_2Button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
frontSideViewController = storyboard?.instantiateViewControllerWithIdentifier("FrontSideViewController") as? FrontSideViewController
backSideViewController = storyboard?.instantiateViewControllerWithIdentifier("BackSideViewController") as? BackSideViewController
flip_2Button.addTarget(self, action: "flipViews", forControlEvents: UIControlEvents.TouchUpInside)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func flipViews() {
UIView.beginAnimations("ViewSwitch", context: nil)
UIView.setAnimationDuration(0.6)
UIView.setAnimationCurve(.EaseInOut)
UIView.setAnimationTransition(.FlipFromRight, forView: view, cache: true)
frontSideViewController?.view.frame = self.view.frame
backSideViewController?.willMoveToParentViewController(nil)
backSideViewController?.view.removeFromSuperview()
backSideViewController?.removeFromParentViewController()
self.addChildViewController(frontSideViewController!)
self.view.addSubview(frontSideViewController!.view)
frontSideViewController?.didMoveToParentViewController(self)
}
Please teach me how solve those two problems.
Thanks for your help.
Ethan Joe

missing return in a function expected to return swift

I want to make a button that makes the background switch between red and green but I get this error:
missing return in a function expected to return UIView
I'm pretty new to coding, I've googled a bit but I didn't find anything.
Language:Swift
my code:
var timeLeft = 0
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var buttonColor: UIView! {
timeLeft = 1
}
func update() {
if timeLeft > 0 {
view.backgroundColor = UIColor.greenColor()
}
else {
view.backgroundColor = UIColor.redColor()
}
timeLeft = timeLeft - 1
}
}
thanks for helping
You declare buttonColor as a computed property which in its body requires you to return a UIView instance (since its type is UIView).
Read here or here about computed property and make sure it fits your needs as posted in your case
Hi and welcome to stackoverflow
Remember to make an action connecting your UIButton to the code. Otherwise your code will not run when you click on the button. Also, consider using a Bool (true/false) variable to keep track of the background color.
Try the following code (remember to connect the 'click'-function to the button via the storyboard):
import UIKit
class ViewController: UIViewController {
var isGreen = true
#IBAction func click() {
if isGreen {
view.backgroundColor = UIColor.redColor()
isGreen = false
} else {
view.backgroundColor = UIColor.greenColor()
isGreen = true
}
}
}
var buttonColor: UIView! {
get() {
return (Object of UIView)
}
}

SWIFT function with parameters in viewDidLoad

I have an array of buttons and at the beginning of the program I want the user to pick one button and then it'll change its background.
I've written a switch-statement but I don't know how can I implement it into override func viewDidLoad(), namely, I have no idea what should I write as a parameter instead of UIButton
class ViewController: UIViewController {
#IBOutlet var cardsArray: Array<UIButton> = []
override func viewDidLoad() {
super.viewDidLoad()
self.playerMove(sender: UIButton)
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playerMove(sender: UIButton) {
switch (sender) {
case self.cardsArray[0]:
self.cardPressedAll(0)
case self.cardsArray[1]:
self.cardPressedAll(1)
case self.cardsArray[2]:
self.cardPressedAll(2)
default: break
}
}
func cardPressedAll (cardNumber: Int) {
self.cardsArray[cardNumber].enabled = false
self.cardsArray[cardNumber].setBackgroundImage(UIImage(named: "cross"), forState: UIControlState.Normal)
}
}
Instead of calling 'self.playerMove(sender: UIButton)' in your view did load you need to connect your buttons to your IBAction using storyboard.

Resources