Make button disappear from 3 seconds then reappear (swift3) - ios

Every time I hit the button I would like the button to be hidden for 3 seconds then after the 3 seconds are up I would like the button to not be hidden.
#IBOutlet var save: UIButton!
#IBAction func button(_ sender: Any) {
}

You can just schedule a closure to be executed on the main thread with a 3second delay that unhides your button.
#IBOutlet var save: UIButton!
#IBAction func button(_ sender: Any) {
save.isHidden = true
DispatchQueue.main.asyncAfter(deadline: .now()+3, execute: {
save.isHidden = false
})
}

You can use CGD:
#IBOutlet var save: UIButton!
#IBAction func button(_ sender: Any) {
self.button.alpha = 0.0
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.button.alpha = 1.0
}
}
or you can use perform(_:with:afterDelay:)
#IBOutlet var save: UIButton!
#IBAction func button(_ sender: Any) {
self.button.alpha = 0.0
perform(#selector(showButton), with: nil, afterDelay: 3)
}
#objc func showButton() {
self.button.alpha = 1.0
}

Actually if you use Google, you will find a lot of examples. Use something like this:
var timer: Timer!
#IBOutlet var save: UIButton!
#IBAction func button(_ sender: Any) {
save.isHidden = true
timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(runTimedCode), userInfo: nil, repeats: false)
}
func runTimedCode() {
save.isHidden = false
}

Related

xcode ios - updating scheduled timer whenever slider is adjusted

So I have a slider and a startTimer button that calls a nextFood() function via a Timer.scheduledTimer interval based on the slider's value.
What I'm trying to do is even after I pressed the startTimer button, if I move the slider to a different value, the scheduledTimer should adjust to the new value and call the nextFood function according to the new interval without trying to press the startTimer button again.
My code:
#IBOutlet var sliderVal: UISlider!
#IBAction func slider(_ sender: UISlider) {
delayLabel.text = "Delay: " + String(Int(sender.value)) + "s"
}
//start timer according to slider val
var timer = Timer()
#IBAction func startTimer(_ sender: UIButton) {
//print(Int(sliderVal.value))
startButton.isEnabled = false
timer = Timer.scheduledTimer(timeInterval: Double(Int(sliderVal.value)), target: self, selector: #selector(ViewController.nextFood), userInfo: nil, repeats: true)
}
So far my code only works for the value the slider is set when the startTimer button is pressed initially but doesn't adjust when I move the slider. Any help is much appreciated!
Short Answer: You can't change the time interval of the timer once it has started.
What you can do is this: Upon slider action, invalidate the previous timer, create a new timer, and fire it with the new interval.
This is also related to your issue.
You don't need to create two #IBActions. You can create one common #IBAction and connect the button and slider action to that.
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
#IBOutlet weak var startButton: UIButton!
#IBOutlet weak var slider: UISlider!
var timer: Timer?
#IBAction func updateTimer(_ sender: Any) {
label.text = "Delay: " + String(Int(slider.value)) + "s"
startButton.isEnabled = false
timer?.invalidate()
timer = nil
timer = Timer.scheduledTimer(timeInterval: Double(Int(slider.value)), target: self, selector: #selector(ViewController.nextFood), userInfo: nil, repeats: true)
}
#objc func nextFood() {
///
}
}
Note: Before initialising new Timer instance, invalidate the previous instance. Else multiple timer instances will be calling the nextFood method
You can do that with a DispatchSourceTimer which can be restarted without recreating the timer instance
var timer : DispatchSourceTimer?
#IBOutlet var sliderVal: UISlider!
#IBAction func slider(_ sender: UISlider) {
let delay = Int(sender.value)
delayLabel.text = "Delay: \(delay) s"
startTimer(with: delay)
}
//start timer according to slider val
#IBAction func startTimer(_ sender: UIButton) {
//print(Int(sliderVal.value))
startButton.isEnabled = false
startTimer(with: Int(sliderVal!.value))
}
func startTimer(with delay: Int) {
let interval : DispatchTime = .now() + .seconds(delay)
if timer == nil {
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline:interval, repeating: TimeInterval(delay))
timer!.setEventHandler {
DispatchQueue.main.async {
self.nextFood()
}
}
timer!.resume()
} else {
timer!.schedule(deadline:interval, repeating: TimeInterval(delay))
}
}

Is hidden not working on image views in Swift 3?

#IBOutlet weak var allStocksSelected: UIImageView!
#IBOutlet weak var shortStocksSelected: UIImageView!
#IBOutlet weak var longStocksSelected: UIImageView!
#IBOutlet weak var myStocksTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myStocksTableView.delegate = self
myStocksTableView.dataSource = self
}
override func viewDidAppear(_ animated: Bool) {
self.shortStocksSelected.isHidden = true
self.longStocksSelected.isHidden = true
self.allStocksSelected.isHidden = true
}
#IBAction func allStocksButtonPressed(_ sender: Any) {
print("ALL!")
self.stockTypeChanged(stockType: allStocksSelected)
}
#IBAction func shortStocksButtonPressed(_ sender: Any) {
print("SHORT!")
self.stockTypeChanged(stockType: shortStocksSelected)
}
#IBAction func longStocksButtonPressed(_ sender: Any) {
print("LONG!")
self.longStocksSelected.isHidden = false
self.shortStocksSelected.isHidden = true
self.allStocksSelected.isHidden = true
//stockTypeChanged(stockType: longStocksSelected)
}
#IBAction func addNewStockButtonPressed(_ sender: Any) {
}
#IBAction func signOutButtonPressed(_ sender: Any) {
}
private func stockTypeChanged(stockType: UIImageView) {
let stockTypes: [UIImageView] = [allStocksSelected, shortStocksSelected, longStocksSelected]
for (stock) in stockTypes {
if (stock == stockType) {
stock.isHidden = false
} else {
stock.isHidden = true
}
}
}
As shown from my code above, I am basically just trying to hide and show certain image views when buttons are pressed.
I am 100% sure that all of the buttons actions and IB outlets are properly connected, yet the image views are still not hiding and showing, and I cannot figure out why.
I was running into this same issue. Placing your isHidden code to execute on the main thread should solve the problem.
DispatchQueue.main.sync {
}

How to use one button to add scores for different integers (swift3)

Right now i have a purple and red score. I would like to use the 1 and 2 buttons to add the score for the colors. I know how to do this by creating just a sets of buttons to the specific color but doing this again and again will create problems. So what I am trying to do is if purple is selected and if and only if 1 is pressed then the total score of purple will = 1. I guess what I am trying is perform a switch statement for the buttons.
Before purple/red button is pressed.
After purple/red button is pressed.
import UIKit
class ViewController: UIViewController {
var purpleScore = 0
var redScore = 0
#IBOutlet var plus1: UIButton!
#IBOutlet var plus2: UIButton!
#IBOutlet var addRed: UIButton!
#IBOutlet var addPurlple: UIButton!
#IBOutlet var totalScorePurple: UILabel!
#IBOutlet var totalScoreRed: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
plus1.isHidden = true
plus2.isHidden = true
}
#IBAction func enteringRed(_ sender: Any) {
plus1.isHidden = false
plus2.isHidden = false
}
#IBAction func enteringPurple(_ sender: Any) {
plus1.isHidden = false
plus2.isHidden = false
}
#IBAction func plus1(_ sender: Any) {
}
#IBAction func plus2(_ sender: Any) {
}
}
If I understand correctly as the comment above, this should work
Create 2 Bool for red and purple to see weather they are checked or not, this is easiest way, else you can just check the redButton color got changed (if it does) or .selected = true
var redChecked = false
var purpleChecked = false
#IBAction func enteringRed(_ sender: Any) {
redChecked = !redChecked
//change color etc..
}
#IBAction func enteringPurple(_ sender: Any) {
purpleChecked = !purpleChecked
//change color etc..
}
#IBAction func plus1(_ sender: Any) {
if redChecked {
redScore+=1
}
if purpleChecked {
purpleScore+=1
}
}
#IBAction func plus2(_ sender: Any) {
if redChecked {
redScore+=2
}
if purpleChecked {
purpleScore+=2
}
}

Swift Timer App

I was trying to build a simple ios timer app using swift3. I successfully created an app using the following code. It has three buttons, one to start the timer, one to stop the timer which means reset and one to pause the timer. all the buttons are working but when I click on start once again while the timer is running, the timer interval speeds up (means calls the selector function twice within a second). how to solve this problem.
Here is my code
#IBOutlet weak var lbl: UILabel!
var time = 0
var timer = Timer()
#IBOutlet weak var start: UIButton!
#IBOutlet weak var stop: UIButton!
#IBOutlet weak var pause: UIButton!
#IBAction func start(_ sender: AnyObject) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
}
#IBAction func stop(_ sender: AnyObject) {
//timer.invalidate()
time = 0
lbl.text = "0"
}
#IBAction func pause(_ sender: AnyObject) {
timer.invalidate()
}
override func viewDidLoad() {
super.viewDidLoad()
}
func action() {
time += 1
lbl.text = String(time)
}
If your start method runs while a timer is already active, you create a second timer. Now you have two timers calling the same action, which accounts for your problem. Scheduled timers are retained by their run loops, so even though you don't have a reference to the old timer, it's still there.
At a minimum you need to either invalidate the old timer or else just keep using the one you have. But there are some things that would help make the code better:
Your timer attribute should probably be a Swift optional. Initializing it as Timer() doesn't do anything useful. It would make more sense if timer could be nil when no timer should be running.
You should probably disable your "start" button when a timer is running. It doesn't make sense for it to be active when the timer has already started. You could do this by setting up an IBOutlet for the button and changing the value if the button's isEnabled property.
One Mistake in Source code.
First Stop exist timer then start new timer.
Code for that is below.
#IBAction func start(_ sender: AnyObject) {
timer.invalidate()
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
}
And for stop timer use invalidate timer function.
#IBAction func stop(_ sender: AnyObject) {
timer.invalidate()
}
I think what you need to do is invalidate if there is a timer running
#IBAction func start(_ sender: AnyObject) {
if (timer) {
timer.invalidate()
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
}
#IBOutlet weak var lbl: UILabel!
var time = 0
var timer : Timer?
var isPause = false
#IBOutlet weak var start: UIButton!
#IBOutlet weak var stop: UIButton!
#IBOutlet weak var pause: UIButton!
#IBAction func start(_ sender: AnyObject) {
timer?.invalidate()
timer = nil
isPause = false
time = 0
lbl.text = "0"
// or call stop(self.stop)
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
}
#IBAction func stop(_ sender: AnyObject) {
timer?.invalidate()
timer = nil
isPause = false
time = 0
lbl.text = "0"
}
#IBAction func pause(_ sender: AnyObject) {
timer.invalidate()
isPause = !isPause // second click to resum...
}
override func viewDidLoad() {
super.viewDidLoad()
}
func action() {
if !isPause {
time += 1
lbl.text = String(time)
}
}

Swift iOS- How to hide label then make it appear after a certain time period [duplicate]

This question already has answers here:
NSTimer - how to delay in Swift
(4 answers)
Closed 5 years ago.
I have a label that gets hidden when a button is pressed. After a certain time period like 60 secs I want the label to reappear. I'd assume I do that in viewDidAppear, How would i do that?
#IBOutlet weak var myLabel: UILabel!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//after 60 secs myLabel should reappear
//self.myLabel.isHidden = false
}
#IBAction func buttonTapped(_ sender: UIButton){
self.myLabel.isHidden = true
}
#IBAction func buttonTapped(_ sender: UIButton){
self.myLabel.isHidden = true
DispatchQueue.main.asyncAfter(deadline: .now() + 60) {
self.myLabel.isHidden = false
}
}
You can do this by scheduling a timer:
class ViewController: UIViewController {
#IBOutlet weak var myLabel: UILabel!
#IBAction func buttonTapped(sender: UIButton) {
if !myLabel.isHidden {
myLabel.isHidden = true
Timer.scheduledTimer(timeInterval: 15.0, target: self, selector: #selector(showLabel), userInfo: nil, repeats: false)
}
}
func showLabel() {
myLabel.isHidden = false
}
}

Resources