How to hide button after click - ios

I create Start_button and make #IBOutlet and #IBAction
#IBOutlet weak var Start_button: UIButton!
#IBAction func Start_button(sender: AnyObject)
Now, i want hide button after click. I try this, but this don't work:
#IBAction func Start_button(sender: AnyObject)
{
Start_button.hidden = true;
}
Error message:
fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb)
How i can hide this button?
Thanks for helping!

Its nil because you probably haven't connected it from your storyboard/nib. You need to connect the outlet, you can't just create an outlet in code and expect it to be connected to the visible element. The same goes for your action. #IBOutlet / #IBAction stands for Interface Builder Outlet/Action, which means you have to connect them in Interface Builder.
Also its better if your action uses the sender, and not a local variable (when its pointing to the same thing). And you shouldnt use ;at the end of the line.
#IBAction func Start_button(sender: UIButton) // Change to UIButton
{
sender.hidden = true
// OR
// (sender as! UIButton).hidden = true
}

#IBAction func button_nameA(sender: AnyObject) {
// show hidden buttons
self.Target_Object.hidden = false
}
So when you click the A buttons its automaticly send to you target and in target also you have to hide button if you working single view app

Related

Swift UIbutton is clicked add a string and when clicked again it removes it

I'm a beginner in swift, I'm making an app in storyboard UIKit, and I need some help basically I need to set up a view controller that has buttons on it that when clicked add a string on the bottom of the VC, and if clicked again it will remove that same string. On the VC there going to be multiple buttons like this for options also on the bottom of the VC I need the label to update during the app also it should display like this for example. "Football","Basketball","Golf". It needs to be displayed just like that on the bottom with quotes and commas. I've to turn to make action buttons with a global array and put that inside each button but I can't figure out how to remove it when the button clicked again, also if you click the button again it'll add the same thing again so in the array you'll have two of the same strings. Anything would help.
P.S I need to do this in UIkit and Storyboard
You can make list of outlets to an array UIButton, handle list of actions when click into UIButton with a function. Using 'isSelected' property of UIButton to distinguish 'delete' or not.
class ViewController: UIViewController {
#IBOutlet weak var descriptionLabel: UILabel!
#IBOutlet var allButtons: [UIButton]!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func didTapButton(_ sender: UIButton) {
sender.isSelected.toggle()
_updateDescription()
}
private
func _updateDescription() {
descriptionLabel.text = allButtons
.filter { $0.isSelected }
.compactMap { $0.titleLabel?.text }
.map { "\"\($0)\"" }
.joined(separator: ", ")
}
}

Connect Outlets to Tab View Controller Result in Nil Error

I've created a new window controller that hosts a tabViewController inside my app. I've added classes to the window controller, and have the same class across all the view controllers in the tab view.
I can connect buttons and give them an action and it works perfectly, however, I try to connect an outlet and attempt to change something via the outlet, it returns nil and crashes the program. For example, this exact code works in the pre-made viewController of my app, but returns:
Unexpectedly found nil while implicitly unwrapping an Optional value
when running it through the new tab view controller I created.
What's weird to me is I can use a regular view controller and the outlets connect fine, but if I want to use a tab view controller, these nil errors are happening.
I made sure that the nil was not related to grabbing the inputs for the button by printing the audio devices, and the audio devices are there and able to be printed. It seems as if the button is not there even though it is connected.
I have also tried to simply change an NSTextField color after connecting it to an outlet and this returns the same nil error.
Any idea what I might be doing wrong here? Thanks so much for the help.
class FirstLaunchViewController: NSViewController {
var FLWindow: FirstLaunchWindowController?
var selectedAudioDevice = [String]()
#IBOutlet weak var deviceListPopUpButton: NSPopUpButton!
#IBOutlet weak var visualizeButton: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
self.preferredContentSize = NSMakeSize(self.view.frame.size.width, self.view.frame.size.height)
populateDeviceList()
}
#IBAction func CloseStartupGuide(_ sender: Any) {
self.view.window?.windowController?.close()
}
#IBAction func popUpDidChange(_ sender: Any) {
print("changed")
}
//grab inputs for button
fileprivate func populateDeviceList() {
deviceListPopUpButton.removeAllItems()
for device in AudioDevice.allInputDevices() {
var teststring = ""
teststring = device.uid!
print(device.name)
deviceListPopUpButton.addItem(withTitle: device.name)
deviceListPopUpButton.lastItem?.tag = Int(device.id)
selectedAudioDevice.append(device.uid!)
}
}
}
}

Save and Load text on UITextField

I am struggling for some hours at a problem. Basically, I have a simple Swift app. It goes like this. In my 1st view controller I have 3 text fields I want to fill them with information and a "Next" button.
Pressing the "Next" button will send me to a new UIViewController where I will have a "Back" button. Upon pressing the back button, I will be send back to 1st page with the 3 text fields.
What I want is: if I complete the text fields with informations, press Next and then Back, I want the text fields to be filled with that information.
I managed to move between the views with buttons, but I can't save the information. Can you provide me a little help?
#IBOutlet weak var txtb1: UITextField!
#IBOutlet weak var txtb2: UITextField!
#IBOutlet weak var txtb3: UITextField!
#IBAction func next(sender: AnyObject) {
text1 = self.txtb1.text!
text2 = self.txtb2.text!
text3 = self.txtb3.text! }
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
if (!text1)
{
txtb1.text = text1
}
}
If you are wanting to pass variables to different views you will have to use the prepareForSegue function before you segue into that view controller.
This allows the variables to be accessed by the view controller.
Override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!)
{
if segue.identifier == "segue_name"
{
let theDestination = segue.destinationViewController as! newViewController
theDestination.variable = "testing"
theDestination.variable2 = "testing2"
}
}
Then inside your second view controller you will have to declare variable and variable2 as shown:
var variable:String!
var variable2:String!
These will then be able to be used in the second view controller inside the viewDidLoad method.
Ok. I managed to fix a little of the problem, that button wasn't linked accordingly so the function was not executing. Here it is the code:
var text1 = ""
#IBOutlet weak var txtb1: UITextField!
#IBAction func next(sender: AnyObject) {
text1 = self.txtb1.text! // text1 = "I am taking value"
}
// when i press the back button
override func viewDidLoad() {
super.viewDidLoad()
if (!numarInmatriculare.isEmpty)
{
txtb1.text = text1 //here text1 = Null. the value is not saved
}
}
I want the value to be saved and displayed back on text field.
I also tried to use static varibiles but I am prompet with error.
static var numar:String = ""
numar = text1
//static member 'numar'cannot be used on instance of type 'viewcontroller'
You no need to do anything for this case, once text field filed then you clicking next button you wrote some code below i shown
text1 = self.txtb1.text!
text2 = self.txtb2.text!
text3 = self.txtb3.text!
Please first you remove the code,Once data filled in text filed, its automatically retain, after you clicking next button then come back it automatically it will retain, when your current view is poping then only your data will deallocate.

How to use one IBAction for multiple buttons in Swift?

I have multiple buttons each one with the ability to switch the language of the app. Instead of having to create multiple IBActions for each button is there a way to have them all connected to one IBAction and change the language based on the button pressed? I'm thinking a switch statement would be good to use in this situation but not exactly sure how to set it up.
In Interface Builder, select the Attributes Inspector and set the Tag for each button with a unique number, then you can do something like this:
#IBAction changeLanguage(sender: AnyObject) {
guard let button = sender as? UIButton else {
return
}
switch button.tag {
case 1:
// Change to English
case 2:
// Change to Spanish
case 3:
// Change to French, etc
default:
print("Unknown language")
return
}
}
To connect the action to multiple buttons: in Interface Builder, right-click ViewController in the view hierarchy, then left-click to drag the action connection to each button.
Yes, a switch statement is the way to go here. For a UIButton, you link it to a selector that is called when the user interacts with the button, generally the TouchUpInside event. The addTarget method, and valid selector signatures (apple.com) Of these, you want to use a method in the format #IBAction func doSomething(sender: UIButton) or #IBAction func doSomething(sender: UIButton, forEvent event: UIEvent), so that a reference to the button that triggered the event is passed to the selector.
In your ViewController code, you'll have references to your UIButtons (possibly in a storyboard, or created manually.) Let's say you have
#IBOutlet weak var frenchButton: UIButton!
#IBOutlet weak var spanishButton: UIButton!
#IBOutlet weak var englishButton: UIButton!
You would connect all of them to the same method, and branch the logic based on which one was the sender. e.g.:
#IBAction func changeLanguage(sender: UIButton) {
switch sender {
case frenchButton:
// Change Language to French
print ("C'est si bon")
case spanishButton:
// or Spanish
print ("Muy Bueno")
case englishButton:
// or English
print ("It's pretty cool")
default:
break
}
}
Note: Case statements in Swift must be exhaustive, so you have to include a default case, even though it should never be called.
Do not set tag if you have reference to the button.
You can just compare the reference instead of tags. This way, you won't introduce a new bug, because unlike a tag that you type yourself, reference is created by compiler automatically.
#IBOutlet weak var firstButton: UIButton!
#IBOutlet weak var secondButton: UIButton!
#IBOutlet weak var thirdButton: UIButton!
#IBAction changeLanguage(sender: UIButton) {
if sender == firstButton {
} else if sender == secondButton {
} else if sender == thirdButton {
}
}

Creating a word game

I'm creating a word game using UIKit, and I want to represent the entire alphabet for the user in order to solve the puzzle, here is my code:
var emptyPos = [0]
#IBOutlet var pos1: UILabel!
#IBOutlet var pos2: UILabel!
#IBOutlet var pos3: UILabel!
#IBOutlet var pos4: UILabel!
#IBAction func btnA(sender: UIButton) {
letters(sender)
}
#IBAction func btnB(sender: UIButton) {
letters(sender)
}
#IBAction func btnC(sender: UIButton) {
letters(sender)
}
#IBAction func btnD(sender: UIButton) {
letters(sender)
}
func moveLetter (pos: UILabel, btn: UIButton) {
UIView.animateWithDuration(0.5, animations: { () -> Void in
btn.center = pos.center
})
}
func letters (btn: UIButton) {
switch emptyPos.count {
case 1:
moveLetter(pos1, btn: btn)
emptyPos.append(0)
println(emptyPos)
case 2:
moveLetter(pos2, btn: btn)
emptyPos.append(0)
println(emptyPos)
case 3:
moveLetter(pos3, btn: btn)
emptyPos.append(0)
println(emptyPos)
case 4:
moveLetter(pos4, btn: btn)
emptyPos.append(0)
println(emptyPos)
default:
println("Error")
}
}
The idea is the user has to click on a letter after letter to move them towards the empty labels and figure out the right word, and as you can see I went with making each letter a button and each empty space a label, but was wondering if there is a better way than creating 26 buttons for each letter. Linking all the buttons to a single function will not work because then I will have to rely on sender.tag which I cannot pass to my function in order to move the letter. So should I continue with what I'm doing or is there some better way to do this ?
if you make a custom UIButton you can add extra properties to the button, then change the sender of the #IBAction to your custom class, then just pass the button to your moveLetter and it can know what to do based on the information supplied by the button. then they can all share the same button press function
then if your buttons subclass has a #property string called ButtonLetter, you can define what its value is right in the storyboard instead of manually doing it in code for all of the buttons by giving it a runtime attribute like in the screen shot below
or you could be lazy and just get the text of the button and read what letter it is, but i would say this is a more proper way of going about it, cause this can apply to any type of button where maybe the text on the button isnt actually the value you want to use to do some computation when the button is pressed, but in your case it just so happens to be that way.

Resources