how to hide/show a button in swift - ios

I'm trying to have an if statement that will make a button hidden when a label displays a certain status, and appears when the label says something else. The name of the label is Status, and when it shows "Closed", I want it hidden, and when it shows "Open", it will appear.
var query3 = PFQuery(className:"Status_of_game")
query3.findObjectsInBackgroundWithBlock{
(namelist3: [AnyObject]!, error : NSError!) -> Void in
for list3 in namelist3 {
var output = list3["StatusType"] as String
self.Status.text = output
println(output)
if self.Status.text == "Closed"
{
Purchase().enable = false
}
}
}

As #LAmasse says, you want to use button.hidden = true. button.hidden was renamed to button.isHidden in Swift 3
The code you posted doesn't make sense.
if self.Status.text == "Closed"
{
Purchase().enable = false
}
What is Purchase? From the capitalized name, it seems to be a class. If so, the expression Purchase() is likely creating a new instance of the Purchase class, which makes no sense. Why are you making a function call? If that is creating a new Purchase object then that code is pointless. (You would create a new object inside the if statement that would be discarded on the very next line since you don't keep a strong reference to it.)
You want to set up an IBOutlet for your button and connect it in Interface Builder.
The declaration might look like this:
Class MyViewController: UIViewController
{
#IBOutlet weak var theButton: UIButton!
//The rest of your view controller's code goes here
}
If the outlet is connected to your button, there should be a filled-in circle to the left of the line of code. It looks like this:
And then your code to show/hide the button might look like this:
func showQueryResults
{
var query3 = PFQuery(className:"Status_of_game")
query3.findObjectsInBackgroundWithBlock()
{
(namelist3: [AnyObject]!, error : NSError!) -> Void in
for list3 in namelist3
{
var output = list3["StatusType"] as String
self.Status.text = output
println(output)
if output == "Closed"
{
theButton.isHidden = false //changed to isHidden for Swift 3
}
}
}
}
It isn't clear to me why you'd loop though all of the results from your query and and show the button if the "StatusType" of any of the results is == "Closed".
Finally, I'm not very familiar with parse. If the completion block for the findObjectsInBackgroundWithBlock method doesn't get called on the main thread you will have to change that code to make the UI updates on the main thread.
EDIT:
I've since learned that Parse executes its completion handlers on the main thread, so you don't need to worry about UI calls from Parse completion handlers.

SWIFT 3
I created an
IBOutlet: loadingBDLogo
To Show:
loadingBDLogo.isHidden = false
To Hide:
self.loadingBDLogo.isHidden = true

The sample code for hiding a button in Swift:
import UIKit
class ViewController: UIViewController {
// Create outlet for both the button
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
//Set button2 hidden at start
button2.isHidden = true
}
//Here is the action when you press button1 which is visible
#IBAction func button1(sender: AnyObject) {
//Make button2 Visible
button2.isHidden = false
}
}
And
You have to make the UIButton a property of the class if you want to keep a reference to it. Then you can access it using self.takePhotoButton.

To hide a button, use button.hidden = true
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/index.html#//apple_ref/occ/cl/UIView

Related

How to move function with button sender to a separate file?

I have a difficulty in a simple task. I googled this topic, but other examples are complicated by additional syntax that I don't understand yet. Can you help me to solve it or give link if there is already was similar topic.
I need to move the function responsible for selecting the button to a separate file, because if the number of buttons increases, it will turn into a large sheet. So made a function in separate swiftfile, but naturally the new file does not know about any buttons in viewController and can't find it in scope. Also If i’m not mistaken i need give Bool and return String.
How can I transfer a function with button sender to a separate file so that it returns non-optional text value back in the ViewController?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Label1: UILabel!
#IBOutlet weak var BTC: UIButton!
#IBOutlet weak var ETC: UIButton!
#IBOutlet weak var LTC: UIButton!
var choice = "Choose coin"
var coinType = getCoinType()
#IBAction func optionSelected(_ sender: UIButton) {
BTC.isSelected = false
ETC.isSelected = false
LTC.isSelected = false
sender.isSelected = true
if BTC.isSelected == true{
ETC.isSelected = false
LTC.isSelected = false
choice = "BTC"
Label1.text = choice
}else if ETC.isSelected == true{
BTC.isSelected = false
LTC.isSelected = false
choice = "ETC"
Label1.text = choice
}else if LTC.isSelected == true{
ETC.isSelected = false
LTC.isSelected = false
choice = "LTC"
Label1.text = choice
}
}
}
new file, i can't understand how to get sender from buttons here
import Foundation
func getCoinType() -> String{
var choice: String
// my if else function
return choice
}
P.S. In general, is it possible to make it easier, without using UIPickerView?
On how to add functions in different swift file you have a few options. This a simple one: Create a new swift file and name it ViewController+Extenstions.swift (you can use any name though). Then add an extension to your ViewController class and add your function like this:
extension ViewController {
func getCoinType() -> String {
var choice: String
// my if else function
return choice
}
}
You can add as many functions as you need and in different files (all extensions to ViewController but of course with different file names).
PS, in your optionSelected function, you are setting:
BTC.isSelected = false
ETC.isSelected = false
LTC.isSelected = false
I don't know what you're trying to achieve, but by doing so, those if-else will never be executed since your are setting the three buttons as not-selected!
UPDATE:
For your button selection problem, you can do this:
1- Add tags to your buttons
You can do it inside viewDidLoad method. This way you can differentiate between different buttons.
override func viewDidLoad() {
super.viewDidLoad()
BTC.tag = 0
ETC.tag = 1
LTC.tag = 2
}
2- Connect the action of buttons
Although your three buttons can have three different handler functions, it's easier to connect all of them to a single handler. However, we can know which button is tapped based on the value of the tag we assign in the previous step. So, connect all buttons to optionSelected(_ sender: UIButton) through Storyboard (because you have used Storyboard.
3- Rewrite getCoinType function
func getCoinType(tag: Int) -> String? {
var choice: String?
switch tag {
case 0:
choice = "BTC"
case 1:
choice = "ETC"
case 2:
choice = "LTC"
default:
choice = nil
}
return choice
}
Buttons' handler
Now when a button is tapped we call getCoinType function with that button's tag as input argument. It will return the string and we assign it to the Label1:
#IBAction func optionSelected(_ sender: UIButton) {
let choice = getCoinType(tag: sender.tag)
Label1.text = choice
}
And you're done!

How to implement didTapCheckBox of BEMCheckBox IOS Library?

I am new in Ios and i am having hard time wrapping my head around protocols and delegates concept. I am implementing a library called BEMCheckBox https://github.com/Boris-Em/BEMCheckBox or https://cocoapods.org/pods/BEMCheckBox for implementing radio buttons. Its documentation is pretty descriptive using which i have successfully added checkboxes, grouped them together to work as radio boxes.
#IBOutlet var inarelashipcb: BEMCheckBox!
#IBOutlet var complicatedcb: BEMCheckBox!
#IBOutlet var singlecb: BEMCheckBox!
var groupbx:BEMCheckBoxGroup!
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
}
Now i want to use didTapCheckBox method but i donot understand how. The documentation is blurry there no snippets for that. For the record this is what the documentation states
"BEMCheckBox uses a delegate to receive check box events. The delegate object must conform to the BEMCheckBoxDelegate protocol, which is composed of two optional methods:
didTapCheckBox:
Sent to the delegate every time the check box gets tapped, after its properties are updated (on), but before the animations are completed."
Any snippets to help me use delgate so i can implement didTapCheckBox method?
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
for checkbox in groupbx {
checkbox.delegate = self
}
}
must call initialize in viewDidLoad of the viewController
override func viewDidLoad() {
// Do your work
initialize()
}
compiler will show you an error, error will be gone if you add this codes
extension ViewController : BEMCheckBoxDelegate {
func didTap(_ checkBox: BEMCheckBox) {
//do your work
// if you have multiple checkboxes, then do like that
//if checkBox == checkBox1 {
//do work for checkbox1
//} else if {
// ..
//}
}
}
Don't forget to add the following line
import BEMCheckBox
The outlet checkbox you have declared, set delegate to self.
For eg, if your checkbox outlet is checkbox1 set its delegate as
checkbox1.delegate = self
I solve it.
using this code
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
inarelashipcb.delegate = self
complicatedcb.delegate = self
singlecb.delegate = self
}
func didTap(_ checkBox: BEMCheckBox) {
print("here hello")
}
Also my uiviewcontroller inherited from BEMCheckBoxDelegate

How do I make two UIButtons perform like radio buttons in Swift?

I have two UIButtons that I want to use to set an A/B value to a variable before I save data to a database. I want a button to become selected when tapped, and deselected when the other button is tapped, and vice versa. What is a good solution for accomplishing this programmatically or in Interface Builder?
In order to set an "A/B value" as you mention, the easiest option would be to use a UISwitch or -in the general case of possibly more than 2 options- a UISegmentedControl (as #rmaddy suggested in the question's comments) .
These controls have built-in the "choose just one out of many" functionality that you are looking for.
The drawbacks of the switch are:
It has to be either on or off (does not support a selection state of "neither A nor B")
You can't have separate title labels for each state.
If you still want two separate UIButton instances, you can:
Have references to both buttons in your view controller (#IBOutlets wired using Interface Builder), e.g.:
#IBOutlet weak var leftButton: UIButton!
#IBOutlet weak var rightButton: UIButton!
Implement the action method for both buttons in such a way that it sets the selected state of the tapped button, and resets the other one. For example:
#IBAction func buttonAction(sender: UIButton) {
if sender == leftButton {
leftButton.isSelected = true
rightButton.isSelected = false
} else if sender == rightButton{
leftButton.isSelected = false
rightButton.isSelected = true
}
}
This is a quick-and-dirty solution for just two buttons. If you want a generic radio group of n-buttons, there are open source solutions on GitHub, etc...
Try this.
First create both button separate #IBOutlet.
#IBOutlet weak var btnYes: UIButton!
#IBOutlet weak var btnNo: UIButton!
Set Both Button Tag Like this and you also set tag using storyboard.
override func viewDidLoad() {
super.viewDidLoad()
btnYes.tag = 1
btnNo.tag = 2
}
Implement Common #IBAction method for both buttons
#IBAction func btnYesNoTapped(_ sender: UIButton) {
if sender.tag == 1 {
self.IsBtnSelected(isSelect: true, with: self.btnYes)
}else {
self.IsBtnSelected(isSelect: true, with: self.btnNo)
}
}
Create Custome Method
func IsBtnSelected(isSelect:Bool,with sender:UIButton){
self.btnYes.isSelected = false
self.btnNo.isSelected = false
sender.isSelected = isSelect
}
you can use following function for creating a radio button behaviour, you have to btn outlet to be selected and array of both outlets to this function. instead ofcolor you can also compare images and set images. for getting a required value yo can create a variable in viewcontroller and assign this variable a value in IBAction of btn and you can call this function from IBAction.
func radioButton(_ btnToBeSelected: UIButton, _ btnArray: [UIButton]) {
for btn in btnArray {
if btn == btnToBeSelected {
btn.backgroundColor = UIColor.black
//selected btn
//You can also set btn images by
//btn.setImage(<#T##image: UIImage?##UIImage?#>, for: <#T##UIControlState#>)
} else {
btn.backgroundColor = UIColor.red
//not selected btn
}
}
}
In iOS , you would have to do it manually.See the below approaches,
Use a switch . Using a UISwitch would be better if the option indicates a on/off state.
Use a same method when the button is pressed. Whenever the method gets called deselect the other button/buttons and select the pressed button. You can use tags or keep a reference of the buttons to differentiate between them.
Lastly , keep different methods for each buttons . Just deselect the other buttons whenever the button is pressed.
You can follow the above approaches by using interface builder or programmatically.
You can achieve it like below
I have implemented it for dates which are in TableView you just need to do little modifications
enum filterDateSelectableOptions:Int {
case AssignDate
case DueDate
case CompletionDate
}
//Assign Date selected by default
var currentSelectedFilterDate:filterDateSelectableOptions = .AssignDate
Now
func btnRadioButtonTapped(sender:UIButton) {
switch sender.tag {
case kTableViewRow.AssignDate.rawValue:
self.currentSelectedFilterDate = .AssignDate
case kTableViewRow.DueDate.rawValue:
self.currentSelectedFilterDate = .DueDate
case kTableViewRow.CompletionDate.rawValue :
self.currentSelectedFilterDate = .CompletionDate
default:
break;
}
//sender.isSelected = !sender.isSelected
self.tblFilterList.reloadData()
}
in cellForRow I have
// THIS IS DIFFERENT ENUM SO +1 is required in my case
case .AssignDate,.DueDate,.CompletionDate :
let button = buttonRadioCircle
button.tag = row.rawValue
cell.accessoryView = button
button.addTarget(self, action: #selector(btnRadioButtonTapped(sender:)), for: .touchUpInside)
button.isSelected = self.currentSelectedFilterDate.rawValue + 1 == row.rawValue
}

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 {
}
}

Prevent a view from being loaded or appearing

I have a tab bar controller as the starting point of my app, where one of the tab and what happens subsequently is meant for admins only. So I was password protecting a tab. I thought of adding a little modal dialogue in the viewDidLoad function of my view controller (which by the way is a UITableViewController),
Suppose I can get the text that the user entered in the dialogue box in the variable inputTextField.
The relevant section of the code from viewDidLoad():
if inputTextField?.text != "secret" {
return
}
super.viewDidLoad()
But it does not work. Any hint appreciated. Sorry if it is too basic, I am completely new to iOS and Swift programming, so pardon my ignorance folks.
Here is a simple example. Lots of ways. I dropped two UIViews in Storyboard on the first tab's VC. The one in the back I gave a dark color to simulate the hidden secret view (secretView). Inside of the view on top (entryView) I dragged a label "Enter Passcode" and a text field (passCode). I just hid the back view unless the secret code was correct.
import UIKit
class FirstViewController: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.passCode.delegate = self
entryView.hidden = false
secretView.hidden = true
}
#IBOutlet weak var entryView: UIView!
#IBOutlet weak var secretView: UIView!
let secretCode = "X"
#IBOutlet weak var passCode: UITextField!
func textFieldShouldReturn(textField: UITextField!) -> Bool {
if textField.text == secretCode {
entryView.hidden = true
secretView.hidden = false
} else {
self.passCode.text = "Try Again!"
}
textField.resignFirstResponder()
return true
}
}

Resources