【问题标题】:How to display current time zones in a UITableView Cell如何在 UITableView 单元格中显示当前时区
【发布时间】:2020-08-19 21:24:06
【问题描述】:

我正在尝试创建一个时区应用程序,该应用程序将显示当前时间,每秒钟计数一次,我能够在标签上显示秒数,但所有行显示相同的时间。我尝试将带有当前时间的时区附加到一个数组中,但我想不出一种方法来每秒更新一次数组以显示当前时间。

正如您在图片中看到的,我需要相应地更新 seconds、minutes 和 hours。

这是我目前得到的。

谢谢

import UIKit



class TimeZoneViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{

    var timer: Timer?
    

    @IBOutlet weak var timeZoneTableView: UITableView!

    var zoneNameArray: [String] = ["Alpha Zone","Bravo Zone"]
    // var offSetArray:[Int] = [1,2,3,4,5,6,7,8,9,10]
    var timeArray:[String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        timeZoneTableView.delegate = self
        timeZoneTableView.dataSource = self
        // SupportedLocation.rowHeight = 69
        
    }
    
    
    override func viewWillAppear(_ animated: Bool) {
        createTimer()
        // createTimerTest()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return zoneNameArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = timeZoneTableView.dequeueReusableCell(withIdentifier: "TimeZoneSegue",for: indexPath) as? TimeZoneTableViewCell  {
            //timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
            
            print(timeArray.count)
            cell.timeZoneNameLbl.text = zoneNameArray[indexPath.row]
            //updateTimer()
            return cell
        }
        
        
        return UITableViewCell()
    }
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 125
    }
    
    
    
    
    
    
    @objc func updateTimer() {
        // 1
        guard let visibleRowsIndexPaths = timeZoneTableView.indexPathsForVisibleRows else {
            return
        }
        
        for indexPath in visibleRowsIndexPaths {
            // 2
            if let cell = timeZoneTableView.cellForRow(at: indexPath) as? TimeZoneTableViewCell {
                
                
                // cell.updateTime()
                //                // Time
                //                //Local Time
                let dateDate = Date()
                let formatter = DateFormatter()
                //
                formatter.dateFormat = "HH:mm:ss"
                
                let timeResults = formatter.string(from: dateDate)
                //  print("\(timeResults)")
                
                //Zulu Time
                
                let UTCDate = Date()
                let formatterUTC = DateFormatter()
                
                
                for offset in zoneNameArray{
                    
                    switch offset {
                    case "Alpha Zone":
                        // print("Alpha")
                        
                        formatterUTC.timeZone = TimeZone(abbreviation: "UTC+0")!
                        formatterUTC.locale = Locale(identifier: "en_US_POSIX")
                        formatterUTC.dateFormat = "HH:mm:ss"
                        
                        
                        
                        let defaultTimeZoneStr = formatterUTC.string(from: UTCDate)
                        // cell.zoneTimeLbl.text = defaultTimeZoneStr
                        timeArray.append(defaultTimeZoneStr)
                        
                    case "Bravo Zone":
                        print("Bravo")
                        
                        formatterUTC.timeZone = TimeZone(abbreviation: "UTC+2")!
                        formatterUTC.locale = Locale(identifier: "en_US_POSIX")
                        formatterUTC.dateFormat = "HH:mm:ss"
                        
                        
                        
                        let defaultTimeZoneStrBravo = formatterUTC.string(from: UTCDate)
                        // print("\(")l
                        
                        // cell.zoneTimeLbl.text = defaultTimeZoneStrBravo
                        timeArray.append(defaultTimeZoneStrBravo) // defaultTimeZoneStrBravo
                    default:
                        break
                    }
                    cell.zoneTimeLbl.text = timeArray[indexPath.row]
                    
                }
                
                
                
                
                
            }
            
        }
        
    }
    
    
    
    
    func createTimer() {
        // 1
        if timer == nil {
            // 2
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                         target: self,
                                         selector: #selector(updateTimer),
                                         userInfo: nil,
                                         repeats: true)
        }
        
    }
}

【问题讨论】:

  • 将计时器添加到 UILabel 本身
  • 我没有工作,我可以使用该问题的答案来更新标签,但它只显示一个时区。如何将其应用于我所有时区所在的 TimeArray ? @LeoDabus
  • 您可能使用的是同一个标签实例
  • @Roger ,我想我发现了这个错误。请检查我的答案。

标签: swift xcode uitableview timer


【解决方案1】:

我想我发现了这个错误。在updateTimer() 函数中,您确实计算了最新时间并将它们附加到timeArray,但是您使用cell.zoneTimeLbl.text = timeArray[indexPath.row] 填充单元格,这意味着您始终使用第一批计算时间,而最新时间保持不变。

要修复它,您应该清除timeArray 之前 for offset in zoneNameArray。

更新:这是修改后的代码sn-p。

import UIKit


fileprivate let currentZoneName = "Current"
fileprivate let alphaZoneName = "Alpha Zone"
fileprivate let bravoZoneName = "Bravo Zone"

class TimeZoneViewController: UIViewController,UITableViewDelegate,UITableViewDataSource{

    var timer: Timer?
    
    @IBOutlet weak var timeZoneTableView: UITableView!

    var zoneNameArray: [String] = [currentZoneName, alphaZoneName, bravoZoneName]
    
    var zoneDict = [
        currentZoneName: TimeZone.current,
        alphaZoneName: TimeZone(abbreviation: "UTC+0")!,
        bravoZoneName: TimeZone(abbreviation: "UTC+2")!
    ]
    
    // var offSetArray:[Int] = [1,2,3,4,5,6,7,8,9,10]
    var timeArray:[String] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        timeZoneTableView.delegate = self
        timeZoneTableView.dataSource = self
        // SupportedLocation.rowHeight = 69
    }
    
    override func viewWillAppear(_ animated: Bool) {
        createTimer()
        // createTimerTest()
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return zoneNameArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = timeZoneTableView.dequeueReusableCell(withIdentifier: "TimeZoneSegue",for: indexPath) as? TimeZoneTableViewCell  {
            //timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
            
            print(timeArray.count)
            cell.timeZoneNameLbl.text = zoneNameArray[indexPath.row]
            //updateTimer()
            return cell
        }
        
        
        return UITableViewCell()
    }
    
    func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        // timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector:#selector(self.tick) , userInfo: nil, repeats: true)
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 125
    }
    
    @objc func updateTimer() {
        // 1
        guard let visibleRowsIndexPaths = timeZoneTableView.indexPathsForVisibleRows else {
            return
        }
        
        // cell.updateTime()
        //                // Time
        //                //Local Time
        let dateDate = Date()
        let formatter = DateFormatter()
        //
        formatter.dateFormat = "HH:mm:ss"
        
        let timeResults = formatter.string(from: dateDate)
        //  print("\(timeResults)")
        
        //Zulu Time
        
        let UTCDate = Date()
        let formatterUTC = DateFormatter()
        
        // remove all elements in timeArray, they are useless
        timeArray.removeAll()
        
        for offset in zoneNameArray{
            switch offset {
            case currentZoneName:
                formatterUTC.timeZone = zoneDict[currentZoneName]!
                formatterUTC.locale = Locale(identifier: "en_US_POSIX")
                formatterUTC.dateFormat = "HH:MM:ss"
                
                let defaultTimeZoneStr = formatterUTC.string(from: UTCDate)
                // cell.zoneTimeLbl.text = defaultTimeZoneStr
                timeArray.append(defaultTimeZoneStr)
            case alphaZoneName:
                // print("Alpha")
                
                formatterUTC.timeZone = zoneDict[alphaZoneName]!
                formatterUTC.locale = Locale(identifier: "en_US_POSIX")
                formatterUTC.dateFormat = "HH:mm:ss"
                
                let defaultTimeZoneStr = formatterUTC.string(from: UTCDate)
                // cell.zoneTimeLbl.text = defaultTimeZoneStr
                timeArray.append(defaultTimeZoneStr)
                
            case bravoZoneName:
                print("Bravo")
                
                formatterUTC.timeZone = zoneDict[bravoZoneName]!
                formatterUTC.locale = Locale(identifier: "en_US_POSIX")
                formatterUTC.dateFormat = "HH:mm:ss"
                
                let defaultTimeZoneStrBravo = formatterUTC.string(from: UTCDate)
                // print("\(")l
                
                // cell.zoneTimeLbl.text = defaultTimeZoneStrBravo
                timeArray.append(defaultTimeZoneStrBravo) // defaultTimeZoneStrBravo
            default:
                break
            }
        }
        
        for indexPath in visibleRowsIndexPaths {
            // 2
            if let cell = timeZoneTableView.cellForRow(at: indexPath) as? TimeZoneTableViewCell {
                cell.zoneTimeLbl.text = timeArray[indexPath.row]
            }
        }
    }
    
    func createTimer() {
        // 1
        if timer == nil {
            // 2
            timer = Timer.scheduledTimer(timeInterval: 1.0,
                                         target: self,
                                         selector: #selector(updateTimer),
                                         userInfo: nil,
                                         repeats: true)
        }
    }
}

其他提示:

  • 您不应将for offset in zoneNameArray 放在for indexPath in visibleRowsIndexPaths 中。而是将for offset in zoneNameArray 放在 for indexPath in visibleRowsIndexPaths。

  • 通过共享实例来避免频繁创建实例(例如,将它们作为属性)。

【讨论】:

  • 感谢您的回复。我尝试通过 timeArray.removeAll() 清除 timeArray,但应用程序因数组越界而崩溃。我能够让 tableView 填充正确的时区,我只需要表格视图中的秒、分钟和小时来实时更新。就像 iPhone 上的时钟 App。
  • 其实我跑的很顺畅。
  • 你能把你的代码贴出来和我的比较一下吗?谢谢
  • @Roger 更新为TimeZoneViewController。我主要更改了updateTimer() func,并将当前时区添加为第一行。单元格上的所有时间标签都正确更新。
  • @Roger 不客气。我很高兴它有帮助。编码愉快!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多