How stop another function from an UIButton function using Swift? - ios

I got two functions running called updatePrice and updateTime, and I want to stop them when I click an UIButton.
func updateTime() {...}
func updatePrice() {...}
// ..
#IBAction func Button(sender: UIButton) {
// What should I write here?
}

Do something like NSOperations do: make a boolean and periodically check it in those functions. Something like:
var stopFuncs = false
and later in functions at sensitive moments insert that:
if stopFuncs { return }
and add this to button code:
stopFuncs = true

Related

How can i handle the multiple click action to single button for api calling and get the true response from api

i just want to know the method to handle multiple click event on single button.(e.g FACEBOOK like button if i tapped multiple time then it may work perfect)
below code give you some idea and if there is any appropriate solution then give me as soon as possible.
class LikeViewController: UIViewController {
//MARK:- Outlets
#IBOutlet weak var btnLike: UIButton!
#IBOutlet weak var lblDescription: UILabel!
//MARK:- Variables
var objModelWatchList:WatchListModel?
var objUser = WatchListModel()
//MARK:- Lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
getWatchList()
}
//MARK:- Functions
//Function for prepare UI
func prepareUI() {
btnLike.isSelected = isLike()
}
//Function for prepare data from api
func getWatchList() {
objUser.videoId = 216
objUser.type = "VIDEO"
APIService.sharedInstance.getWatchList(parameters: objUser.toDictionary() as [String : AnyObject], success: { (dataSuccess) -> (Void) in
self.objModelWatchList = dataSuccess
DispatchQueue.main.async {
self.prepareUI()
self.lblDescription.text = self.objModelWatchList?.message
}
}) { (resultFailure) -> (Void) in
print(resultFailure)
}
}
//Function to varify the status of like
func isLike() -> Bool {
return objModelWatchList!.status == 1 ? true : false
}
//MARK:- Actions
#IBAction func btnLikeClicked(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
self.getWatchList()
}
}
Thank You.
You have to disable your button when API call and when u will get right response after the processing on that response you have to enable it.
Its works for me. I have a same issue.
if you refer to manage several events taps...I recommend that use tapGestureRecognizer or variants, these can manage events that you comment for example...:
Single tap,double tap or more taps to trigger function event
Hold tap [UILongPressGestureRecognizer]
if you refer to same button called severals function in diferents situations i recommend the use un tag button for example:
function examplefunctionA(){
//Another Proccess
//Another Proccess
self.button.tag = 2
}
function examplefunctionB(){
//Another Proccess
//Another Proccess
self.button.tag = 1
}
func buttonclicked(sender: UIButton) {
if sender.tag == 1 {
examplefunctionA()
}else if sender.tag == 2 {
examplefunctionB()
}
}

Selectors in Swift 4.0

I was wondering if there is a more 'swift 4' way of creating a selector and calling a function? I am wanting to have the click of the Status Bar Button to call a simple print command from a function, but is this outdated or is there a more efficient 'swift' way of doing this?
button.action = #selector(myFunction)
#objc func myFunction (sender: NSStatusBarButton) {
print("Hi")
}
I am not sure if there's any good way to avoid using the target/action pattern under the hood, but you can definitely try to hide it.
Personally I use ReactiveSwift for all callbacks so I never have to use this awkward objc syntax. Another way to do it would be to hide this inside an extension. For instance, you can try something like:
extension UIButton {
private struct AssociatedKeys {
static var TouchUpClosure = "touchUpClosure"
}
internal var onTouchUpInside: ((UIButton) -> ())? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.TouchUpClosure) as? (UIButton) -> ()
}
set {
objc_setAssociatedObject(
self,
&AssociatedKeys.TouchUpClosure,
newValue as? (UIButton) -> (), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
button.action = #selector(executeTouchUpInside:)
}
}
#objc func executeTouchUpInside(sender: UIButton) {
self.touchUpInside(sender)
}
}
Which allows you to use a "more swift" syntax (no #objc or #selector):
button.onTouchUpInside = { _ in print("Hi") }
Disclaimer - I haven't checked if this exact code compiles, this post is more about sharing an idea.

Swift - Sum function error

I'm trying to make some view controllers that save a variable of a label every time and sum it to a total var. At the last view controller, show the result.
My code is:
FirstViewController
#IBAction func playSystemSoundV1(sender: UIButton) {
// Other code...
puntsLocal = 3
}
#IBAction func playSystemSoundRet(sender: UIButton) {
// Other code...
puntsLocal = 5
}
This code is similar for 5 controller. At the end of the controller I have a button to pass from one viewController to another. When I click I do the code above:
#IBAction func puntuacioAction(sender: UIButton) {
let puntuacion = Sum()
puntuacion.sumPoints(puntsLocal)
}
Sum Class
import Foundation
class Sum {
var points = 0
// Method to sum points from every question.
func sumPoints(num: Int) {
self.points += num
}
func getPoints() -> Int {
return points
}
}
The problem is that returns only the last number without do any kind of sum. What can I do? In other languages it's very easy to resolve but in Swift I cannot reach the answer. Help please!
Thanks.
You need to declare your variable outside the function:
let puntuacion = Sum()
#IBAction func puntuacioAction(sender: UIButton) {
puntuacion.sumPoints(puntsLocal)
}
Your original code created a new Sum everytime the function was called, explaining the behavior you are seeing. In Swift, variable declarations are bound to the scope they appear (e.g., inside a function, inside a class, etc).
If, besides that, you want to share this Sum object across many view controllers, this might help:
class Sum {
static let shared = Sum()
...
}
and use it like this:
#IBAction func puntuacioAction(sender: UIButton) {
Sum.shared.sumPoints(puntsLocal)
}
Of course, you should then delete the let puntuacion = Sum() line.

pass a UIButton into a function

I have a function that runs when a button is pressed.
Inside that function is another function.
I would like to pass the pressed button into the inner function so that I can change the text of the button depending on stuff in that inner function.
#IBAction func newItem(sender: AnyObject) {
let urlFetch:String = urlField.text!
self.service.createNewItem(urlFetch, I_WANT_BUTTON_HERE)
}
How do I pass the button into the function?
If it helps this is the function that I am passing it to:
func createNewItem(item_url: String, plus_button: UIButton) {
let dataDictionary = ["url" : item_url]
self.post("item/create", data: dataDictionary).responseJSON { (response) -> Void in
plus_button.titleLabel!.text = "success"
}
}
Later I will add an if statement that changes the text depending on what the response is.
The object passed into newItem method is actually the button you tapped so you can securely convert the type of parameter sender into UIButton like below:
#IBAction func newItem(sender: UIButton) {
...
self.service.createNewItem(urlFetch, sender)
}
There is also one thing though. Setting the text of titleLabel is not the right way of updating the title of button. You should be using setTitle:forState instead:
func createNewItem(item_url: String, plus_button: UIButton) {
...
plus_button.setTitle("success", forState: .Normal)
}
Instead of sending AnyObject as parameter in the newItem function, pass a UIButton.
#IBAction func newItem(sender: UIButton) {
let urlFetch:String = urlField.text!
self.service.createNewItem(urlFetch, sender)
}

Calling IBAction from another method without parameter

In my program 2 functions (IBAction player.Move(UIButton) and autoMove()) are supposed to be called by turns till all of the fields (UIButtons) has been clicked. For this I've created a function play(). However, I don't know how can I put the IBAction playerMove inside of play() function, because I need no parameter here.
I've found some answers and tried self.playerMove(nil) and self.playerMove(self) but it doesn't work.
import UIKit
class ViewController: UIViewController {
#IBOutlet var cardsArray: Array<UIButton> = []
var randomCard = 0
override func viewDidLoad() {
super.viewDidLoad()
self.play()
// Do any additional setup after loading the view, typically from a nib.
}
func play () {
self.autoMove()
self.playerMove(self) // <----- here is my problem
}
#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)
case self.cardsArray[3]:
self.cardPressedAll(3)
default: break
}
}
func cardPressedAll (cardNumber: Int) {
self.cardsArray[cardNumber].enabled = false
self.cardsArray[cardNumber].setBackgroundImage(UIImage(named: "cross"), forState: UIControlState.Normal)
self.cardsArray.removeAtIndex(cardNumber)
}
func autoMove (){
self.randomCard = Int(arc4random_uniform(UInt32(self.cardsArray.count)))
self.cardsArray[self.randomCard].enabled = false
self.cardsArray[self.randomCard].setBackgroundImage(UIImage(named: "nought"), forState: UIControlState.Normal)
self.cardsArray.removeAtIndex(self.randomCard)
}
}
Either you have to call playerMove: without a button, in which case you have to declare the sender parameter as an optional. Like:
#IBAction func playerMove(sender: UIButton?) {
UIButton means that you have to pass in a button. nil is not a button, but with UIButton?, that is to say Optional<UIButton>, nil is a valid value meaning the absence of a button.
Or you have to work out which button you want to pass to playerMove: to make it do what you want. Sit down and work out what you want to have happen, and what the code needs to do in order to make that happen.
Try
self.playerMove(UIButton())
Your func playerMove has parameters expecting sender to be of type UIButton, self or nil would be an unexpected object.
Edit:
You could us optional parameters by placing ?. This would allow you to call self.playerMove(nil) if needed.
#IBAction func playerMove(sender: UIButton?) {
if sender != nil {
//handle when button is passed
} else {
//handle when nil is passed
}
}
doSomeTask(UIButton()) in swift 5.0 and onward worked for me

Resources