all
I am a new developer on IOS. nowdays I study Swift by books.
there are some trouble. I use swift3 but the book consists of swift2.
so I don't know what is wrong code.
could you help me?
thanks you for reading and helping me.
this is datacode.
import UIKit
class ViewController: UIViewController {
let timeSelector: Selector = #selector(ViewController.updateTime)
let interval = 1.0
var count = 0
#IBOutlet weak var IbICurrentTime: UILabel!
#IBOutlet weak var IbIPickTime: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: timeSelector)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func changeDatePicker(_ sender: UIDatePicker) {
let datePickerView = sender
let formatter = DateFormatter()
formatter.dateFormat = "YYYY-MM-dd HH:mm:ss EEE"
IbIPickTime.text = "선택시간: " + formatter.string(from: datePickerView.date)
}
func updateTime() {
IbICurrentTime.text = String(count)
count = count+1
}
}
there are problem
Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: timeSelector)
}
i don't know what i have to input at "block"?
"Block" is the Objective-C term of Swift's closure. The "Blocks" variant works like this:
Timer.scheduledTimer(timeInterval: interval, repeats: true, block: { timer in
self.IbICurrentTime.text = String(self.count)
self.count += 1
})
You don't need to define a separate updateTime() function with the block syntax.
In Swift the above can be written more naturally as
Timer.scheduledTimer(timeInterval: interval, repeats: true) { _ in
self.IbICurrentTime.text = String(self.count)
self.count += 1
}
If you want to use selectors, use scheduledTimer(timeInterval:target:selector:userInfo:repeats:) instead:
Timer.scheduledTimer(timeInterval: interval,
target: self,
selector: #selector(updateTime),
userInfo: nil,
repeats: true)
Related
I figured out how to display the live current time in "hh:mm:ss" (code below). I want the label to display the time left until a specific target time, like a countdown. I want it to count down until e.g. 3pm each day and then start over. I know I need to subtract my target time from the current time but I don't know how to do that.
(I am new to programming)
class ViewController: UIViewController {
#IBOutlet weak var Label: UILabel!
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
getCurrentTime()
}
private func getCurrentTime() {
timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector:#selector(self.currentTime) , userInfo: nil, repeats: true)
}
#objc func currentTime() {
let formatter = DateFormatter()
formatter.dateFormat = "hh:mm:ss"
Label.text = formatter.string(from: Date())
}
}
Use timeIntervalSince to find TimeInterval between two dates. Like below
let secondsBetween: TimeInterval = targetDate.timeIntervalSince(currentDate)
self.counter = Int(secondsBetween)
func timerAction() {
counter -= 1
label.text = timeString(time: TimeInterval(counter))
}
I'm trying to get output like so:
1 (then a one second delay)
Hello
2 (then a one second delay)
Hello
3 (then a one second delay)
Hello
But instead I get
1
2
3 (then a one second delay)
Hello
Hello
Hello
Here's my for loop invoking the NSTimer
var timer = NSTimer()
for i in 1...3 {
print("\(i)");
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(MainVPScreenViewController.printTest), userInfo: nil, repeats: false)
}
And here's the selector method:
func printTest() {
print("Hello")
}
Thanks in advance for any help you can provide
Try this solution without NSTimer:
var i = 1
func printHello() {
print(i)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
print("Hello")
i +=1
if i <= 3 {
printHello()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
printHello()
}
I need 2 NSTimers to do this, this is my approach
class ViewController: UIViewController {
var i = 1
override func viewDidLoad() {
super.viewDidLoad()
beginPrinting()
}
func beginPrinting() {
var timer2 = NSTimer()
if(i <= 100)
{
timer2 = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.printWithDelay), userInfo: nil, repeats: false)
}
}
func printWithDelay()
{
var timer = NSTimer()
print("\(i)");
i += 1
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.printTest), userInfo: nil, repeats: false)
}
func printTest() {
print("Hello")
beginPrinting()
}
}
Hope this helps you
Use timer with repeat to true. So in your view controller would be like this
var timer = NSTimer()
var counter = 0
var max = 10
let delay = 1 // in second
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self,
selector: #selector(self.printTest), userInfo: nil, repeats: true)
}
func printTest() {
counter += 1
print(counter)
print(hello)
if counter == maxNumber {
timer.invalidate()
}
}
This does it with repeat false, and is set up to be in a playground:
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
#objc class Foo: NSObject {
static var timer = NSTimer()
var i:Int
override init() {
Foo.timer = NSTimer()
i = 1
}
func schedule() {
print("\n\(i)");
i += 1
Foo.timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: #selector(printTest),
userInfo: nil,
repeats: false)
}
#objc func printTest() {
print("Hello")
if i < 5 {
schedule()
}
}
}
let bar = Foo()
bar.schedule()
I have a widget with data. When I launch today extension my widget data is updating and showing in real time. But when I scroll the notification center and return to my widget, it doesn't update. I tried several different methods but they didn't help me. I wrote below the last method which I tried.
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateLabels", userInfo: nil, repeats: true)
}
func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
// Perform any setup necessary in order to update the view.
// If an error is encountered, use NCUpdateResult.Failed
// If there's no update required, use NCUpdateResult.NoData
// If there's an update, use NCUpdateResult.NewData
completionHandler(.NewData)
}
func updateLabels() {
runtimeLabel.text = returnTime() + " " + returnDay()
}
func returnTimeInterval() -> NSTimeInterval {
let uptime = NSProcessInfo().systemUptime
return uptime
}
func returnTime() -> String {
dateFormatter.unitsStyle = .Short
dateFormatter.allowedUnits = [.Day, .Hour, .Minute, .Second]
dateFormatter.zeroFormattingBehavior = .Pad
let time = dateFormatter.stringFromTimeInterval(returnTimeInterval())!
return time
}
func returnDay() -> String {
dateFormatter.unitsStyle = .Short
dateFormatter.allowedUnits = [.Year, .Month, .Day]
dateFormatter.zeroFormattingBehavior = .Pad
let date = NSDate(timeInterval: -returnTimeInterval(), sinceDate: NSDate())
let formatter = NSDateFormatter()
formatter.locale = NSLocale.currentLocale()
formatter.dateStyle = .MediumStyle
let megaDate = formatter.stringFromDate(date)
return megaDate
}
I tried the same and it worked with the code below:
#IBOutlet weak var infoLabel: UILabel!
var timer = NSTimer()
var counter = 0
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateLabel"), userInfo: nil, repeats: true)
}
func updateLabel(){
counter += 1
myLabel.text = "Test \(counter)"
}
Update:
viewWillAppear and viewDidAppear should be called after when the widget is active and viewDidDisappear should be called when scrolling (leaving the widget). As for now the viewDidDisappear is working as expected but not viewWillAppear and viewDidAppear on scrolling.
It´s a known bug that this is not working properly, you can read more information in this post at Apples forum and check the bug status report here.
You should write your update code in widgetPerformUpdateWithCompletionHandler method.
I need launch the timer few times in sequence (one after another). And of course I need update Label with timer results.
For example, I have two periods (50 sec and 10 sec) and I need to make a series of periods: 50-10-50-10-50-10.
How can I do it?
import UIKit
class StartTimerViewController: UIViewController {
let firstPeriodTime = 50
let secondPeriodTime = 10
var currentPeriodTime: Int!
let repetitionTime = 3
var timer: NSTimer!
var timeCount = 0
#IBOutlet weak var timerLabel: UILabel!
// MARK: - IBAction method implementation
#IBAction func start(sender: AnyObject) {
// I know it's wrong... This is my question!!!!!
var i = 1
while i <= repetitionTime {
currentPeriodTime = firstPeriodTime
startTimer()
currentPeriodTime = secondPeriodTime
startTimer()
i = i + 1
}
}
// MARK: - Timer method implementation
func startTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: "updateCounter", userInfo: nil, repeats: true)
print("timer start")
}
func updateCounter() {
if timeCount < currentPeriodTime {
timeCount++
let currentTime = Double(currentPeriodTime - timeCount)
timerLabel.text = timeString(currentTime)
}
else {
timer.invalidate()
timeCount = 0
}
}
func timeString(time:NSTimeInterval) -> String {
let minutes = Int(time) / 60
let seconds = time - Double(minutes) * 60
return String(format:"%02i:%02i",minutes,Int(seconds))
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Please use the code below
#IBOutlet weak var _lblTimer: UILabel!
var timer = NSTimer()
var intValue = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update50:", userInfo: nil, repeats: true)
}
func update50(timer : NSTimer){
intValue += 1
_lblTimer.text = intValue.description
if(intValue == 50){
intValue = 0
timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update10:", userInfo: nil, repeats: true)
}
}
func update10(timer : NSTimer){
intValue += 1
_lblTimer.text = intValue.description
if(intValue == 10){
intValue = 0
timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update50:", userInfo: nil, repeats: true)
}
}
I'm trying to make a laundry timer app in Swift where the washer and drying will have different starting times, counting down to 0.
func updateTime() {
...
var elapsedTime: NSTimeInterval = operationDuration - (currentTime - startTime)
...
}
In the var elapsedTime I have operationDuration (how long the washer or dryer will take) and later on in the #IBAction func for pressing the "washer" button I have
let operationDuration == 1800
However I am getting an error the the updateTime func that
'operationDuration' is not defined.
How can I do this? Thanks in advance.
edit:
Here is my washerButtonPress code:
#IBAction func washerButtonPress(sender: AnyObject) {
// TODO: start 30 minute countdown
if !timer.valid {
var operationDuration = 1800
let aSelector:Selector = "updateTime"
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: aSelector, userInfo: nil, repeats: true)
startTime = NSDate.timeIntervalSinceReferenceDate()
}
And how I'm trying to call it in my func updateTime()
var elapsedTime: NSTimeInterval = washerButtonPress.operationDuration - (currentTime - startTime)
and it returns '(AnyObject) -> ()' does not have a member named 'operationDuration'
I apologize for not knowing much but I'm pretty new to this
If this is merely a constant, you can declare it as a global variable.
let kOperationDuration = 1800
class Washer {
...
#IBAction func washerButtonPress(sender: AnyObject) {
if !timer.valid {
let aSelector:Selector = "updateTime"
timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: aSelector, userInfo: nil, repeats: true)
startTime = NSDate.timeIntervalSinceReferenceDate()
}
}
...
}
Then in the Dryer class you can reference the constant.
class Dryer {
...
func updateTime() {
...
var elapsedTime: NSTimeInterval = kOperationDuration - (currentTime - startTime)
...
}
...
}