Xcode / Swift | Knowing if a UISwitch is turned on at any time - swift

Basically, what we got right now is a button that changes its colors (gray & green) based on if the TextFields are filled out or not... Now I would like to add a switch that also has to be switched on to let the button color change to green and change back to gray if not.
How exactly do I implement this part?
PS: setupAddTargetIsNotEmptyTextFields() is called within the viewDidLoad()
func setupAddTargetIsNotEmptyTextFields() {
self.textField_username.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged)
self.textField_eMail.addTarget(self, action: #selector(textFieldsIsNotEmpty),
for: .editingChanged)
self.textField_password.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged)
self.textField_confirmPassword.addTarget(self, action: #selector(textFieldsIsNotEmpty),
for: .editingChanged)
}
#objc func textFieldsIsNotEmpty(sender: UITextField) {
sender.text = sender.text?.trimmingCharacters(in: .whitespaces)
guard
let username = self.textField_username.text, !username.isEmpty,
let eMail = self.textField_eMail.text, !eMail.isEmpty,
let password = self.textField_password.text, !password.isEmpty,
let confirmPassword = self.textField_confirmPassword.text,
password == confirmPassword
else
{
//button is gray
self.button_register.backgroundColor = UIColor(red:0.20, green:0.29, blue:0.37, alpha:1.0)
return
}
//button is green
self.button_register.backgroundColor = UIColor(red:0.10, green:0.74, blue:0.61, alpha:1.0)
}

When I just add the switch to the list, I first type in everything in the textFields and then enable the switch. At this moment the button is still gray. Then I have to first change something again in the textfields to make it work.
It sounds like what's happening is that the switch isn't set to trigger the textFieldsIsNotEmpty action the way the text fields are. You can fix that easily enough: just configure the switch to call the action too:
func setupAddTargetIsNotEmptyTextFields() {
self.textField_username.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .editingChanged)
// ...yada yada yada...
self.switch_selfDestructEnable.addTarget(self, action: #selector(textFieldsIsNotEmpty), for: .valueChanged)
}
Now the switch will send a textFieldsIsNotEmpty when it's value changes just like the text fields do. Next, modify textFieldsIsNotEmpty() to check the state of the switch along with the state of the various text fields, and you should get the behavior you want.

Related

How can I change the placeholder (label) color for MDCOutlinedTextFields?

I'm having a hard time changing the text color for the placeholder label that is used as a hint when not in focus and as a label on top when in focus. (Photo below)
The is reason I'm switching out all my MDC-TextFields and MDC-TextInputControllers is because they are all being deprecated for the New MDC-Outlined Textfields.
The code below is a function within an extension that would simply setup the general background & sub-label colors for all MDC-Outlined Textfields throughout the app.
I have tried a number of functions with no luck(commented out below).
extension MDCOutlinedTextField {
func setUpGeneralBackgroundColors(){
//Text color
self.setTextColor(UIColor.white, for: .normal)
self.setTextColor(UIColor.white, for: .editing)
//Border color
self.setOutlineColor(UIColor.white, for: .normal)
self.setOutlineColor(UIColor.white, for: .editing)
//self.setFloatingLabelColor(UIColor.white, for: .normal)
//self.setFloatingLabelColor(UIColor.white, for: .editing)
//self.setFloatingLabelColor(UIColor.white, for: .disabled)
// self.setNormalLabelColor(UIColor.purple, for: .normal)
// self.setNormalLabelColor(UIColor.purple, for: .editing)
// self.setNormalLabelColor(UIColor.purple, for: .disabled)
// self.label.tintColor = UIColor.purple
//self.label.textColor = UIColor.systemPink
//self.label.shadowColor = UIColor.cyan
//self.label.backgroundColor = UIColor.red
//Changes icon colors within the text field if any
self.tintColor = .green
}
}
I figured the problem, in the storyboard where I have these new textfields I had a raw string for the placeholder which override the swift code behind the scenes and prevented me from changing colors.
Note: This problem will NOT occur with the now deprecated MDC-Textfields.
If you guys have a placeholder value in the storyboard when using these MDC-Outlined Textfields in storyboards, (not to mixed up with the swift code) then get rid of them.

Swift UIButton titleColor change when highlighted?

I would like to titleColor of my UIBUtton to change when the user taps on the button, with the below code currently the color of the UIBUtton title changes if the user press and hold on the button, however, not when tapped quickly, could you please let me know what do I need to change in the below code to make the titleColor change upon a tap detection only:
var resetFiltersButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Clear Filters", for: .normal)
button.titleLabel?.font = UIFont(name: "AppleSDGothicNeo-Bold", size: 20)
button.setTitleColor(.blue, for: .normal)
button.setTitleColor(.red, for: .highlighted)
button.titleLabel?.numberOfLines = 1
button.tag = 1
button.addTarget(self, action: #selector(buttonPressed(_:)), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
#objc func buttonPressed(_ sender: UIButton) {
// MARK: - Clear Filters button pressed:
if sender.tag == 1 {
}
}
Why don't you try implementing that inside the buttonPressed function?
#objc func buttonPressed(_ sender: UIButton) {
sender.setTitleColor(color: UIColorUI, for: UIControl.State)
}
This issue is that you are using setTitleColor for .normal and .highlighted states.
.normal is when the button is not clicked.
.highlighted is while the button is being clicked on.
Instead you could:
Just updated the .normal color when pressed (in buttonPressed); or
setTitleColor for .selected for after it's clicked and handle the selection state within buttonPressed (add sender.isSelected = !sender.IsSelected)

Is it possible to use an array entry in a #selector?

I'm adding labels and buttons to a TextView dynamically. This is driven by looping through arrays containing label names, button names, and button function names. For brevity and simplicity, I've changed the code here to use hard-coded indexes rather than a loop, and I did not include the label- and button-creation functions. The labels are created just fine. The first button is also created just fine, since I specify Button1Clicked as the #selector argument. The second button is created correctly only if I specify Button2Clicked as the #selector argument. If I attempt to reference an array in the button #selector argument, I receive the compiler error "Argument of '#selector' does not refer to an '#objc' method, property, or initializer". Assuming it is possible to use an array containing the #objc function name as an argument to the #selector, can someone please provide the appropriate syntax for me? I'm using Swift 5 and Xcode 11.2. Thank you in advance for your assistance.
#objc func Button1Clicked(sender: UIButton) {
print("You pressed button 1")
}
#objc func Button2Clicked(sender: UIButton) {
print("You pressed button 2")
}
.
.
.
var labelNames = [UILabel]()
let Label1:UILabel = UILabel()
let Label2:UILabel = UILabel()
labelNames = [Label1, Label2]
var buttonNames = [UIButton]()
let Button1:UIButton = UIButton()
let Button2:UIButton = UIButton()
buttonNames = [Button1, Button2]
let buttonSelectorNames = ["Button1Clicked", "Button2Clicked"]
configureLabel(labelNameIn: labelNames[0],
textIn: "aaaaa",
textColorIn: appColorWhite,
backgroundColorIn: appColorBlue,
yPositionIn: 0)
statusTextview.addSubview(labelNames[0])
configureLabel(labelNameIn: labelNames[1],
textIn: "-- bbbbb",
textColorIn: appColorWhite,
backgroundColorIn: appColorBlue,
yPositionIn: 25)
statusTextview.addSubview(labelNames[1])
configureButton(buttonNameIn: buttonNames[0],
xPositionIn: 0,
yPositionIn: 50,
textIn: "B1",
textColorIn: appColorBlack,
backgroundColorIn: appColorBrightGreen,
textViewIn: statusTextview)
buttonNames[0].addTarget(self,
action: #selector(Button1Clicked),
for: .touchUpInside)
statusTextview.addSubview(buttonNames[0])
configureButton(buttonNameIn: buttonNames[1],
xPositionIn: 100,
yPositionIn: 50,
textIn: "B2",
textColorIn: appColorBlack,
backgroundColorIn: appColorBrightGreen,
textViewIn: statusTextview)
buttonNames[1].addTarget(self,
action: #selector(buttonSelectorNames[1]),
for: .touchUpInside)
statusTextview.addSubview(buttonNames[1])
you don’t need to define button click event for each button.you can define common function and assign it to all buttons in the loop.then you can specify through button tag
in your loop assign the current index as button tag
buttonNames[currentIndex].tag = currentIndex
buttonNames[currentIndex].addTarget(self,
action: #selector(didButtonClicked(_ :)),
for: .touchUpInside)
button click function
#objc func didButtonClicked(_ sender : UIButton){
switch sender.tag{
case 0: //clicked button with tag 0
case 1: //clicked button with tag 1
default: break
}
}
In the past, I have a deal with the same type of requirement. I was doing it by storing the selector in Array.
Please refer to the code snippets. I am sure it will help you.
Code:
class ViewController: UIViewController {
let selector = [#selector(Button1Clicked),#selector(Button2Clicked)]
override func viewDidLoad() {
super.viewDidLoad()
let btn = UIButton(frame: self.view.bounds)
self.view.addSubview(btn)
btn.addTarget(self, action: selector[0], for: .touchUpInside)
}
#objc func Button1Clicked(){
print("Button1Clicked")
}
#objc func Button2Clicked(){
}
}
Output:

QRCodeReader.swift toggleTorchButton selected image dont work

I'm using QRCodeReader.swift and the possibility to change layout is good, but the selected option of button don't work.
toggleTorchButton?.setImage(UIImage(named: "ic_light_on"), for: .normal)
toggleTorchButton?.setImage(UIImage(named: "ic_light_off"), for: .selected)
If I test the .highlighted state this works fine, but .selected never.
Why?
I'm create a target and this change the selected state.
toggleTorchButton?.addTarget(self, action: #selector(self.toggleTorchButtonHandler), for: .touchUpInside)
func toggleTorchButtonHandler() {
toggleTorchButton?.isSelected = !(toggleTorchButton?.isSelected)!
}

how to change bordercolor when Button.isHighlighted

I wonder how I get my border around my UIButton to change opacity together with the text inside it, when it is either clicked or highlighted.
My logic tells me, that it should be something like this.. but it doesn't seem to work:
//BTN STYLING
btnstd.layer.cornerRadius = 5
btnstd.layer.borderWidth = 1.5
btnstd.layer.borderColor = UIColor.white.cgColor
//Change bordercolor when highlighted
if(btnstd.isHighlighted) {
btnstd.layer.borderColor = UIColor(white:1,alpha:0.3).cgColor
}
This is by the way put inside my ViewDidLoad() function
The actions you are looking for are .touchDown and anything .touchUp:
override func viewDidLoad() {
super.viewDidLoad()
theButton.setTitle("Normal", for: .normal)
theButton.setTitle("Highlighted", for: .highlighted)
theButton.layer.borderColor = UIColor.red.cgColor
theButton.layer.borderWidth = 1
theButton.addTarget(self, action: #selector(startHighlight), for: .touchDown)
theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpInside)
theButton.addTarget(self, action: #selector(stopHighlight), for: .touchUpOutside)
}
func startHighlight(sender: UIButton) {
theButton.layer.borderColor = UIColor.green.cgColor
theButton.layer.borderWidth = 1
}
func stopHighlight(sender: UIButton) {
theButton.layer.borderColor = UIColor.red.cgColor
theButton.layer.borderWidth = 1
}
It depends on what you are trying to do.
Case #1: You want this change to happen when the button is highlighted, but in a normal state have a different set of properties.
let theButton = UIButton()
// set common properties and layout code
theButton.setTitle("Normal", for: .normal)
theButton.setTitle("Highlighted", for: .highlighted)
In addition, you have setTitleColor(), setAttributedTitle, setTitleShadowColor(), setImage(), and setBackgroundImage() that you can code directly.
Border color in this case would need a subclass (not an extension, you want public properties) where you will check self.layer.hitTest() after wiring up a tap gesture on self.
Case #2: You want the button state to change when clicked, and stay changed.
You are part way there. If you supply the button in IB, make sure you add an IBAction for event touchUpInside. If you are working in code, here's the Swift 3 syntax.
theButton.addTarget(self, action: #selector(changeButton), for: .touchUpInside)
func changeButton(sender: UIButton) {
sender.setTitle("New Title", for: .normal)
sender.layer.borderColor = UIColor.red.cgColor
}
My preference (but only that) is to more strongly-type the sender (I think that's the correct term) for my actions. I'm sure there are pros and cons for using a specific sender (like UIButton) over AnyObject, but in this case I think the biggest reason is you don't need to force-cast the sender to UIButton.