I have an app with two switch controls to hide or show some textfield depending on their state on or off.
The problem is the first switch seems to control the second one.
If the first switch is off, the second switch is off also. I would like them to work independently from each other.
Any advice?
Thanks guys
#IBAction func switchP(_ sender: UISwitch) {
if (sender.isOn == true) {
textFieldP.isHidden = false
} else {
textFieldP.isHidden = true
}
}
#IBAction func switchT(_ sender: UISwitch) {
if (sender.isOn == true) {
textFieldT.isHidden = false
} else {
textFieldT.isHidden = true
}
}
First, replace
if (sender.isOn == true) {
textFieldP.isHidden = false
} else {
textFieldP.isHidden = true
}
by a simple single line:
textFieldP.isHidden = !sender.isOn
Second, use Connections Inspector (right panel, the arrow in the circle) and make sure your Referencing Outlets are not mixed or duplicated under the same IBAction.
Other than specifying the .isHidden = true using if/else statements, you should use an opposite property reference which is a lot nicer way of doing it.
#IBAction var switchP: [UIView] {
didSet {
textFieldP.forEach {
$0.isHidden = true
}
}
}
And to change based on a click:
#IBAction func switchP(_ sender: UISwitch) {
UIView.animate(withDuration: 0.2) {
self.switchP.forEach {
$0.isHidden = !$0.isHidden
}
}
}
That's the best I can generically answer without seeing all of your code.
Related
Likely a very simple rookie mistake going on here but I'm trying to make sure a button is disabled until a TextView has text in it.
I set
Button.isEnabled = false
and then added this code. I've tried variations of this code in various ways, I'm seemingly unable to attach it to the textView itself, I can't imagine why this wouldn't be working.
#IBAction func valueChanged(_ sender: AnyObject)
{
if(title.text != "")
{
Button.isEnabled = true
}
else
{
Button.isEnabled = false
}
}
Thanks StackedOverflow Community ...
set button's enabled with alpha to make the look better then set enabled/disabled through valueChanged
#IBOulet private weak var myButton: UIButton! {
didSet {
set(myButton, enabled: false)
}
}
#IBAction private func valueChanged(_ sender: UITextView) {
set(myButton, enabled: !sender.text.isEmpty)
}
private func set(_ button: UIButton, enabled: Bool) {
button.isEnabled = enabled
button.alpha = enabled ? 1 : 0.5
}
I have an array of buttons which will act like a selector menu. I want that when I press one of them, it changes its backgroundColor and all the other buttons go back to their initial color.
This is what I have at the moment
#IBAction func optionSelected(_ sender: UIButton) {
for button in selectButtons {
if button.tag == sender.tag {
if !button.isSelected {
button.backgroundColor = palette.importantColorObject()
button.isSelected = true
} else {
button.backgroundColor = palette.clearGrayColorObject()
button.isSelected = false
}
}
}
But I don't know how to make that only the last selected button have this importantColorObject and I'm also having the problem that when I select the button, not only its background color changes, but it looks also like if text inside was being selected (in blue). How can I solve this?
Thanks in advance
This will solve your only one selection problem, this will make sure that you always have a selected button, unless you to deselect selected one and all your button go to gray or not selected state.
#IBAction func optionSelected(_ sender: UIButton) {
selectButtons.forEach { (button) in
button.backgroundColor = palette.clearGrayColorObject()
button.isSelected = false
}
sender.backgroundColor = palette.importantColorObject()
sender.isSelected = true
}
if you want that functionality too use this one
#IBAction func optionSelected(_ sender: UIButton) {
if sender.isSelected {
sender.backgroundColor = palette.clearGrayColorObject()
sender.isSelected = false
} else {
selectButtons.forEach { (button) in
button.backgroundColor = palette.clearGrayColorObject()
button.isSelected = false
}
sender.backgroundColor = palette.importantColorObject()
sender.isSelected = true
}
}
Hope this will help.
I'm trying to create a calculator that displays a result to the user about their college grades. The user taps buttons and based on their selections, the UI view updates and displays the next question. My code works when up until I need it to access a previously tapped button that was selected previously and on a different view controller. The problem that I'm having specifically is on one view controller, the user can select if they want to know Calculation1 (associated with top button with sender.tag == 1) or Calculation2 (bottom button, sender.tag == 2). Regardless of which button is pressed, a segue is performed to the same question on a new view controller. After that mutual question is answered, there is only one button to press. I'm trying to code an if statement for if Calculation1 (from previous VC) was selected then update the view to the next question, and if Calculation2 was selected perform a segue to a different VC for the next question. The way I was trying to use the boolean was as a property from the previous VC. The if statement isn't working and instead, the same action happens regardless of the selection.
This is for an iOS app with Swift using Xcode. I attempted to create a boolean as a property so that when Calculation1 is tapped, findCalc1 = true and then accessing that boolean as a property in the next VC but it didn't work. I also tried preparing a boolean for the segue to the mutual question but it didn't work either. I feel like I have a gap in my understanding of what can and cannot be performed between different VCs.
// Here is my code for the first VC
#IBAction func lightButtonPressed(_ sender: UIButton) {
if sender.tag == 1 && lightViewPromptIndex == 1 {
desiredGpaText = textfield.text!
performSegue(withIdentifier: "goToDarkButtonVC", sender: self)
} else if sender.tag == 2 && lightViewPromptIndex == 1 {
performSegue(withIdentifier: "goToDarkButtonVC", sender: self)
}
// Here is my code for the second VC
#IBAction func darkButtonPressed(_ sender: Any) {
if aboveTopPromptIndex == 1 && lightViewObject().findCalc1 == true {
aboveTopTextPrompt.text = aboveTopPrompt2
topTextfield.placeholder = "Ex: 76.00"
besideTopTextLabel.isHidden = true
underTopTextLabel.text = "course credits"
aboveBottomTextPrompt.text = "that count toward my GPA."
bottomTextfield.isHidden = true
underBottomTextLabel.isHidden = true
bottomFloatingLabel.isHidden = true
darkButton.setTitle(nextTitle, for: .normal)
aboveTopPromptIndex = 2
} else if aboveTopPromptIndex == 1 && lightViewObject().findCalc1 == false {
performSegue(withIdentifier: "darkViewToABC", sender: TextfieldTwoLightButtonsViewController.self)
The mutual question has aboveTopPromptIndex == 1. What I would like to happen is if that question is asked and Calculation1 was previously selected, for the first chunk of code in the if statement to run... and if Calculation2 is desired, for the segue in the else if statement to occur. Instead, no matter which button is pressed, the first part of the if statement happens, regardless of if Calculation2 was selected previously.
This problem is about passing data from one view controller to another view controller. To pass data from one view controller to
another view controller you can use the methods of segue
func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) { }
Usage:
Add Extension to your first view controller i.e to your lightViewController
extension lightViewController {
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "goToDarkButtonVC") {
let destVC = segue.destinationViewController as! darkViewController
destVC. findCalc = sender as! Bool
}
}
#IBAction func lightButtonPressed(_ sender: UIButton) {
if sender.tag == 1 && lightViewPromptIndex == 1 {
desiredGpaText = textfield.text!
// In the sender set the value as per your need....
performSegue(withIdentifier: "goToDarkButtonVC", sender: true)
} else if sender.tag == 2 && lightViewPromptIndex == 1 {
// In the sender set the value as per your need....
performSegue(withIdentifier: "goToDarkButtonVC", sender: true)
}
}
}
In your second view controller access the value just like this :
class darkViewController : UIViewController {
var findCalc = false
#IBAction func darkButtonPressed(_ sender: Any) {
if aboveTopPromptIndex == 1 && self.findCalc1 == true {
//TODO: add your handling code here....
}
}
And that's how you can easily achieve your requirement.
Creating a new object lightViewObject() will create a new memory block and it will not contain the values stored in the previous viewController
Use Prepare for a segue to pass data from one view controller to another
class lightViewController : UIViewController {
override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
if (segue.identifier == "goToDarkButtonVC") {
let destVC = segue.destinationViewController as! darkViewController
destVC.findCalc1 = true // change the value here
}
}
#IBAction func lightButtonPressed(_ sender: UIButton) {
if sender.tag == 1 && lightViewPromptIndex == 1 {
desiredGpaText = textfield.text!
performSegue(withIdentifier: "goToDarkButtonVC", sender: self)
} else if sender.tag == 2 && lightViewPromptIndex == 1 {
performSegue(withIdentifier: "goToDarkButtonVC", sender: self)
}
}
}
Then use the value in darkViewController
class darkViewController : UIViewController {
var findCalc1:Bool = false
#IBAction func darkButtonPressed(_ sender: Any) {
if aboveTopPromptIndex == 1 && self.findCalc1 == true {
//Your Code here
}
}
I have a simple app with a loading screen. Here I check for some user details in NSUserDefaults and jump to either the login or the sign up screen.
The viewDidLoad() for the loading screen looks like this:
override func viewDidLoad()
{
super.viewDidLoad()
loadingVM = LoadingVM() as LoadingVM
print("LoadingVC")
checkStoredUser()
}
Here is the checkStoredUser()
func checkStoredUser()
{
storedUserStatus = loadingVM.returnStoredUserStatus()
if(storedUserStatus == true)
{
performSegueWithIdentifier("loadingToLoginVC", sender: self)
}
else
{
performSegueWithIdentifier("loadingToSignUpVC", sender: self)
}
}
As you can see, I decide where to go from here based on what the loadingVM.returnStoredUserStatus() returns. I am sure this returns what it's supposed to return but nothing happens.
Here is the prepareForSegue()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
print("prepareForSegue")
if(segue.identifier == "loadingToSignUpVC")
{
let signUpViewCotroller = (segue.destinationViewController as! LocalSignUpVC)
}
else if(segue.identifier == "loadingToLoginVC")
{
print("loadingToLoginVC")
let loginViewCotroller = (segue.destinationViewController as! LoginVC)
}
}
I did some digging and found a weird suggestion that seems to be working but It's not very practical not to mention right to do it like this:
func checkStoredUser()
{
storedUserStatus = loadingVM.returnStoredUserStatus()
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1.0 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue())
{
if(self.storedUserStatus == false)
{
self.performSegueWithIdentifier("loadingToSignUpVC", sender: self)
}
else
{
self.performSegueWithIdentifier("loadingToLoginVC", sender: self)
}
}
}
Can anyone explain to me what's going on here, why doesn't this work and how to make it work properly? It's the first time I encounter this and I can't seem to be able to find any info on this.
EXPLANATION:
Your View hasn't appeared yet when you call your checkStoredUser().
EASY FIX:
Put it in viewDidAppear() like this:
override func viewDidAppear(animated:Bool) {
super.viewDidAppear(false)
checkStoredUser()
}
I try to show a UIView when a button is clicked, but it seems that the UI can't get updated, because the button also activates a segue. When I delete the segue, the UI is updated and my UIView is drawn.
Can anyone help me on how to solve this problem?
override func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject!) -> Bool {
if identifier == "mySegue" {
if(myLocation == nil) {
/* Rest of code */
return false
}
else {
// These properties need to be set
box.hidden = false
actInd.startAnimating()
return true
}
}
return true
}
#IBAction func startComputing(sender: UIButton) {
//When I put the properties, nothing happens,
//but something like print("Button pressed") does happen.
}
Thanks in advance!
From what I understand, the view is within the view controller window hierarchy, so I'd do this without using segues:
#IBAction func startComputing(sender: UIButton) {
UIView.transitionWithView(self.yourView, duration: 0.5, options:UIViewAnimationOptions.TransitionFlipFromLeft, animations: {
}, completion: nil)
}
This will present your view when the button is clicked. Inside the block you can do the rest like updating UI etc.