Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift Set&;在标签中设置日期和时间的动画_Swift_Date_Timer_Uilabel - Fatal编程技术网

Swift Set&;在标签中设置日期和时间的动画

Swift Set&;在标签中设置日期和时间的动画,swift,date,timer,uilabel,Swift,Date,Timer,Uilabel,我很难完成某件事。我正在使用Firebase作为数据库。当用户创建新的民意测验帖子时,他们还必须设置过期日期。在应用程序本身中,我必须在UILabel中以计时器(或倒计时?)的形式显示过期日期,显示应禁用投票前的剩余时间 以下是我目前掌握的情况: extension Date { func offsetFromNow() -> String { let formatter = DateComponentsFormatter() formatter.allow

我很难完成某件事。我正在使用
Firebase
作为数据库。当用户创建新的民意测验帖子时,他们还必须设置过期日期。在应用程序本身中,我必须在
UILabel
中以计时器(或倒计时?)的形式显示过期日期,显示应禁用投票前的剩余时间

以下是我目前掌握的情况:

extension Date {


func offsetFromNow() -> String {
       let formatter = DateComponentsFormatter()
       formatter.allowedUnits = [.day, .hour, .minute, .second]
       formatter.unitsStyle = .abbreviated
       return formatter.string(from: Date(), to: self)!
   }
}

class PostPollCVCell: UICollectionViewCell {
    var seconds = 60 
    var timer = Timer()
    var isTimerRunning = false
    func updateView() {
        if let expirationTimeInt = post?.pollExpirationTime {
            let expirationDate = Date(timeIntervalSince1970: Double(expirationTimeInt))
            self.pollExpirationDate.text = "poll ends in: " + expirationDate.offsetFromNow()
        }
    }

   func runTimer() {
   timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimer), userInfo: nil, repeats: true)
    }

    @objc func updateTimer() {
        seconds -= 1     //This will decrement(count down)the days, hours, min and seconds.
      // pollExpirationDate.text = Update the label with the total time left
    }
}
上面的代码所做的唯一一件事就是简单地获取日期,并将
pollExpirationDate.text
设置为基本上任何时间。输出格式如下所示:

3小时34分钟5秒

我必须做什么而不知道如何做(需要代码方面的帮助):

  • 我必须确保时间不是负的。现在,它只是显示时间,即使是负数。如果时间为负数,则意味着pollExpirationDate
    UILabel
    应该简单地说投票已经结束,禁用投票选项(即
    UIButton
    )并显示一个包含结果的块(现在,我不希望您这样做,现在还没有设置,我只需要知道我应该在哪里运行这些代码,就这样)

  • 我正在从
    FirebaseDatabase
    下载日期并设置
    UILabel
    ,但我不知道如何创建计时器(或倒计时),该计时器应设置
    pollExpirationDate
    UILabel
    (剩余时间)的动画

  • 当倒计时达到0秒时,应禁用投票(时间已过)


  • 我从来没有这样做过,所以非常感谢您的帮助。

    在类中全局创建两个变量,以检查计时器是否工作或暂停/停止

    fileprivate var timeWorking                     : Bool = false
    var timer                                       : Timer?
    
    然后,创建一个方法,以使每个日期组件与您描述的相同

    func timeLeftExtended(date:Date) -> NSAttributedString {
    
        let cal = Calendar.current
        let now = Date()
        let calendarUnits : NSCalendar.Unit = [.day, .hour, .minute, .second]
        let components = (cal as NSCalendar).components(calendarUnits, from: now, to: date, options: [])
    
        let fullCountDownStr = ""
    
        if(components.day!.description == "0" || components.day!.description == "00") {
    
            // This will display hour, minute, and second
            fullCountDownStr = "\(components.hour!.description)h " + "\(components.minute!.description)m " + "\(components.second!.description)s "
    
        } else if (components.day!.description == "0" || components.day!.description == "00") && (components.hour!.description == "0" || components.hour!.description == "00") {
    
            // This will display minute and second
            fullCountDownStr = "\(components.minute!.description)m " + "\(components.second!.description)s "
    
        } else if (components.day!.description == "0" || components.day!.description == "00") && (components.hour!.description == "0" || components.hour!.description == "00") && (components.minute!.description == "0" || components.minute!.description == "00") {
    
            // This will display second only
            fullCountDownStr = "\(components.second!.description)s "
    
        } else {
    
            // This will display day, hour, minute, second
            fullCountDownStr = "\(components.day!.description)d " + "\(components.hour!.description)h " + "\(components.minute!.description)m " + "\(components.second!.description)s "
    
        }
    
        let mutableStr = NSMutableAttributedString(string: fullCountDownStr, attributes: [.foregroundColor: UIColor.white])
    
        for (index,char) in mutableStr.string.enumerated() {
            if(char == "d" || char == "h" || char == "m" || char == "s") {
                mutableStr.removeAttribute(NSAttributedStringKey.foregroundColor, range: NSMakeRange(index, 1))
                mutableStr.addAttributes([.foregroundColor : UIColor.white], range: NSMakeRange(index, 1))
                mutableStr.addAttributes([.font: UIFont.systemFont(ofSize: 12)], range: NSMakeRange(index, 1))
            }
        }
    
        return mutableStr
    }
    
    这将以
    3d 3h 34min 5s
    格式显示日期

    设置make Timer计数器的动画并调用此方法

    func setupTimer() {
    
        if let expirationTimeInt = post?.pollExpirationTime {
            let expirationDate = Date(timeIntervalSince1970: Double(expirationTimeInt))
    
            if expirationDate == Date() {
                self.pollExpirationDate.text = "expirationDate is Today's date"
            } else if date! > Date() {
                if(!timeWorking) {
                    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.updateCountDown), userInfo: nil, repeats: true)
                    self.timeWorking = true
                }
            } else if date! < Date() {
                 self.pollExpirationDate.text = "expirationDate is gone"
            }
        }
    }
    

    从viewDidLoad调用setup timer方法。这是我的工作代码,我希望这会对您有所帮助。

    很抱歉,响应太晚,这确实有效,但当时间为负时,它会一直显示为负。我们如何解决这一问题?只有一个问题-说天和小时实际上是
    0
    (意味着只剩下几分钟和几秒钟了),我们怎么能隐藏那些零,只显示剩余的时间呢?我的意思是(负时间)只有在应用程序未刷新或在我的情况下,应用程序未重新编译时才会发生。@Dani,对于分钟和秒,您可以从
    TimeleftTextEnded
    方法中设置条件并仅返回所需的日期组件。请查看我的更新代码。非常好。非常感谢!@Dani,很高兴帮助您。
    @objc func updateCountDown() {
        if let expirationTimeInt = post?.pollExpirationTime {
            let expirationDate = Date(timeIntervalSince1970: Double(expirationTimeInt))
    
            self.pollExpirationDate.attributedText = self.timeLeftExtended(date: expirationDate)
        }
    }