如何使用 swift 在应用程序中调用一次计时器?
How to call timer one time in application using swift?
大家好我正在开发一个应用程序使用 swift 2 在我的应用程序中每 x 分钟更新一次当前位置所以我使用 NSTimer 能够更新位置并且一切正常 fine.In 我的应用程序(首先视图控制器)当用户成功登录并移动到第二个视图控制器时(第二个视图控制器)我编写了使用 NSTimer 更新位置的函数它工作正常但是当用户移动到第三个视图控制器并且 return 到第二个查看控制器它再次开始更新位置所以我无法停止计时器两次它使计时器无效一次只有另一个即使在用户登录后继续更新位置out.so请有人帮我解决这个问题。
我的第二个视图控制器:
class secondviewcontroller:UIViewController{
查看加载方法:
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(timeToMoveOn), userInfo: nil, repeats: true)
//i declared var timer:nstimer! in appdelegate.swift and i performed some function using nstimer
我的第三个视图控制器:
我为注销代码创建了一个按钮操作是:
var appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as?
AppDelegate)!
appDelegate.timer.invalidate()
提前致谢
大家好谢谢你们的支持我找到了问题的答案
我只是根据我的项目以两种不同的方法保存 timer.invalidate()
而不是从第三个视图控制器推送到第二个视图控制器。您可以弹出到第二个视图控制器。那么你的viewDidLoad就不会调用了。
我看到你的代码,请在你的 AppDelegate Class 中添加一个标志或 Bool 变量。现在,当您从第一个屏幕进入第二个屏幕时,该标志将被启用,当您想要导航到第三个屏幕时,将 false 设置为标志,并通过检查标志是否为真,您的计时器将 运行 按 true 条件。现在,当您再次从第三屏进入第二屏时,如果再次出现计时器情况,请参考此 link:
NSTimer Not Stopping When Invalidated
希望对您有所帮助
我建议这样做:
此单例包装位置。
抱歉,对于 swift3,它看起来像这样:
class LM: NSObject, CLLocationManagerDelegate {
//MARK: Public Variable
var lat = 0.0
var lon = 0.0
var CAST = "location_cast"
public static let i : LM = {
let instance = LM()
return instance
}()
//MARK: Local Variable
fileprivate var locationManager: CLLocationManager?
//MARK: Init
public override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
}
internal func start() {
locationManager?.startUpdatingLocation()
}
internal func stop() {
locationManager?.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
//code
print("\(error)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//code
// print("\(locations)")
if let loc = locations.last {
//simple store to retrieve it later
lat = loc.coordinate.latitude
lon = loc.coordinate.longitude
//cast here notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CAST), object: ["lat": lat, "lon": lon])
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestAlwaysAuthorization()
break
case .authorizedWhenInUse:
manager.startUpdatingLocation()
break
case .authorizedAlways:
manager.startUpdatingLocation()
break
case .restricted:
// restricted by e.g. parental controls. User can't enable Location Services
break
case .denied:
// user denied your app access to Location Services, but can grant access from Settings.app
break
}
}
}
要启动和停止此位置管理器,请使用:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
//...
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
_ = LM.i
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
LM.i.stop()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
LM.i.start()
}
}
您可以在 AppDelegate
您的自定义计时器中添加每 1 秒一次的转换变量
let CASTTOVIEWCONTROLLER = "CASTTOVIEWCONTROLLER"
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CASTTOVIEWCONTROLLER), object: ["lat": LM.i.lat, "lon": LM.i.lon])
甚至简单
let CASTTOVIEWCONTROLLER_PING = "CASTTOVIEWCONTROLLER_PING"
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CASTTOVIEWCONTROLLER), object: nil)
要从转换值中捕获新数据,请使用如下方法:
如果你不会管理 .start()
和 .stop()
iOS 将在几分钟后启动你的后台计时器应用程序,如果你按下 'home' 按钮。
timer的目标是秒viewController,秒viewController拥有这个对象,AppDelegate只引用这个对象,AppDelegate不能释放这个对象,只有secondViewController可以。除非secondViewController被破坏
所以:
var timer:NSTimer//global variable
在 secondViewController 的 viewDidLoad 方法中:
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(timeToMoveOn), userInfo: nil, repeats: true)
在第三个视图控制器中:
let timer = (secondViewControllers object)'s timer
timer.invalidate()
大家好我正在开发一个应用程序使用 swift 2 在我的应用程序中每 x 分钟更新一次当前位置所以我使用 NSTimer 能够更新位置并且一切正常 fine.In 我的应用程序(首先视图控制器)当用户成功登录并移动到第二个视图控制器时(第二个视图控制器)我编写了使用 NSTimer 更新位置的函数它工作正常但是当用户移动到第三个视图控制器并且 return 到第二个查看控制器它再次开始更新位置所以我无法停止计时器两次它使计时器无效一次只有另一个即使在用户登录后继续更新位置out.so请有人帮我解决这个问题。
我的第二个视图控制器:
class secondviewcontroller:UIViewController{
查看加载方法:
var appDelegate:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(timeToMoveOn), userInfo: nil, repeats: true)
//i declared var timer:nstimer! in appdelegate.swift and i performed some function using nstimer
我的第三个视图控制器:
我为注销代码创建了一个按钮操作是:
var appDelegate:AppDelegate = (UIApplication.sharedApplication().delegate as?
AppDelegate)!
appDelegate.timer.invalidate()
提前致谢
大家好谢谢你们的支持我找到了问题的答案
我只是根据我的项目以两种不同的方法保存 timer.invalidate()
而不是从第三个视图控制器推送到第二个视图控制器。您可以弹出到第二个视图控制器。那么你的viewDidLoad就不会调用了。
我看到你的代码,请在你的 AppDelegate Class 中添加一个标志或 Bool 变量。现在,当您从第一个屏幕进入第二个屏幕时,该标志将被启用,当您想要导航到第三个屏幕时,将 false 设置为标志,并通过检查标志是否为真,您的计时器将 运行 按 true 条件。现在,当您再次从第三屏进入第二屏时,如果再次出现计时器情况,请参考此 link: NSTimer Not Stopping When Invalidated
希望对您有所帮助
我建议这样做:
此单例包装位置。
抱歉,对于 swift3,它看起来像这样:
class LM: NSObject, CLLocationManagerDelegate {
//MARK: Public Variable
var lat = 0.0
var lon = 0.0
var CAST = "location_cast"
public static let i : LM = {
let instance = LM()
return instance
}()
//MARK: Local Variable
fileprivate var locationManager: CLLocationManager?
//MARK: Init
public override init() {
super.init()
locationManager = CLLocationManager()
locationManager?.delegate = self
}
internal func start() {
locationManager?.startUpdatingLocation()
}
internal func stop() {
locationManager?.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
//code
print("\(error)")
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//code
// print("\(locations)")
if let loc = locations.last {
//simple store to retrieve it later
lat = loc.coordinate.latitude
lon = loc.coordinate.longitude
//cast here notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CAST), object: ["lat": lat, "lon": lon])
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestAlwaysAuthorization()
break
case .authorizedWhenInUse:
manager.startUpdatingLocation()
break
case .authorizedAlways:
manager.startUpdatingLocation()
break
case .restricted:
// restricted by e.g. parental controls. User can't enable Location Services
break
case .denied:
// user denied your app access to Location Services, but can grant access from Settings.app
break
}
}
}
要启动和停止此位置管理器,请使用:
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
//...
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
// Override point for customization after application launch.
_ = LM.i
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
LM.i.stop()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
LM.i.start()
}
}
您可以在 AppDelegate
您的自定义计时器中添加每 1 秒一次的转换变量
let CASTTOVIEWCONTROLLER = "CASTTOVIEWCONTROLLER"
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CASTTOVIEWCONTROLLER), object: ["lat": LM.i.lat, "lon": LM.i.lon])
甚至简单
let CASTTOVIEWCONTROLLER_PING = "CASTTOVIEWCONTROLLER_PING"
NotificationCenter.default.post(name: NSNotification.Name(rawValue: CASTTOVIEWCONTROLLER), object: nil)
要从转换值中捕获新数据,请使用如下方法:
如果你不会管理 .start()
和 .stop()
iOS 将在几分钟后启动你的后台计时器应用程序,如果你按下 'home' 按钮。
timer的目标是秒viewController,秒viewController拥有这个对象,AppDelegate只引用这个对象,AppDelegate不能释放这个对象,只有secondViewController可以。除非secondViewController被破坏
所以:
var timer:NSTimer//global variable
在 secondViewController 的 viewDidLoad 方法中:
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: #selector(timeToMoveOn), userInfo: nil, repeats: true)
在第三个视图控制器中:
let timer = (secondViewControllers object)'s timer
timer.invalidate()