如何使 Asynctask 中的 UIView 无效 (swift, ios)

how to invalidate a UIView in a Asynctask (swift, ios)

我有一个带有背景颜色的 UIView。

@IBOutlet var timelineview: Timelineview!

现在我想用异步任务更改 UIView 的背景颜色,它应该每秒更改 UIView 的背景颜色。

    dispatch_async(dispatch_get_main_queue()) {
        for var i=10;i<100;i++ {
            println(i);
            var iRed:CGFloat=CGFloat(i)/CGFloat(10.0);
            var backgroundColor:UIColor=UIColor(red: iRed, green: iRed, blue: iRed, alpha: 0.5);
            self.timelineview.backgroundColor = backgroundColor;
            sleep(1);
        }
    }

这只是一个示例,用于了解如何从后台任务调用对 GUI 的更改。在 Android 中,这是通过更新 GUI 的处理程序完成的。我不知道 IOS 中的概念。

有什么帮助吗?

除非您覆盖了视图的行为,否则设置 backgroundColor 也会告知视图它需要重新显示。如果您发现它不起作用(它应该),您可以使用

明确告诉视图重新显示
self.timelineview.setNeedsDisplay()

旁注:你应该永远不要在主队列中调用sleep


您似乎希望它每秒不断更新颜色。这个循环不应该存在于主队列上;但是,内容可能存在于其中。相反,请考虑以下内容:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
  for var i=10;i<100;i++ {
    println(i);
    var iRed:CGFloat=CGFloat(i)/CGFloat(10.0);
    var backgroundColor:UIColor=UIColor(red: iRed, green: iRed, blue: iRed, alpha: 0.5);
    dispatch_async(dispatch_get_main_queue())) {
      self.timelineview.backgroundColor = backgroundColor;
    }
    sleep(1);
  }
}

一次对整个块进行排队仍然不是一个好主意(即使您正在排队到后台队列)。您应该使用重复计时器或显示器 link.

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    //Background Thread
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates/Main Queue

    });
});

您实际上要寻找的不是调度队列,而是可以使用 GCD 的 dispatch_source_create 方法创建的计时器,如下所示:

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main-queue());

//start timer
if (timer) {
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, interval * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        // set background color or any other UI code here
    });
    dispatch_resume(timer);
}

interval 是计时器应该触发的时间间隔(以秒为单位)(1.0 适合您) 要停止计时器,请使用:

dispatch_source_cancel(timer);
timer = NULL;

对不起,我是一个普通的老 Objective C 人,对 Swift 不太熟悉。但是你可能会明白这个概念。