Заполнение UITableView тайм-аутом - PullRequest
0 голосов
/ 30 мая 2018

Я создаю приложение chatbot, которое имитирует статус реального набора текста пользователем, поэтому после каждого сообщения должна быть задержка в 1 секунду (например), прежде чем приложение отправит второе сообщение.

Моя логика сообщений

    let size = dictionary[key]!.count;
    let pointer = random(lower: 0, upper: UInt32(size) - 1);
    let part = dictionary[key]![pointer];

    for row in part {
        if let message = row as? Message {
            self.sendMessage(message: message);
            print("MESSAGE TRIGGERED");
            usleep(1 * 1000 * 1000)
        }

        if let question = row as? Question {

        }
    }

здесь я беру случайный массив сообщений (фактически строк), и в цикле просто добавляю их в мою таблицу, как эта проблема

func sendMessage(message: Message) {
    self.tableView.beginUpdates();

    let indexPath = IndexPath.init(row: self.log.count, section: 0);
    self.log.insert(
        message,
        at: self.log.count
    );
    self.tableView.insertRows(at: [indexPath], with: UITableViewRowAnimation.fade);
    self.tableView.endUpdates()
    self.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
}

в том, что если есть10 строк в массиве сообщений, я вижу 10 «MESSAGE TRIGGERED» журналов в консоли, 1 новая строка, каждую секунду, как я планировал, но в таблице я не вижу строк в течение 10 секунд, а затемони все только появляются сразу.Почему?

Ответы [ 3 ]

0 голосов
/ 30 мая 2018

замените этот код на:

let size = dictionary[key]!.count;
let pointer = random(lower: 0, upper: UInt32(size) - 1);
let part = dictionary[key]![pointer];

for row in part {
    if let message = row as? Message {
        self.sendMessage(message: message);
        print("MESSAGE TRIGGERED");
        usleep(1 * 1000 * 1000)
    }

    if let question = row as? Question {

    }
}

этот код:

let size = dictionary[key]!.count;
let pointer = random(lower: 0, upper: UInt32(size) - 1);
let part = dictionary[key]![pointer];
var timer = Timer!
for row in part {
    if let message = row as? Message {
        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(runTimedCode), userInfo: nil, repeats: true)
    }

    if let question = row as? Question {

    }
}
timer.invalidate()

и добавьте эту функцию:

  @objc func runTimedCode() {
      self.sendMessage(message: message);
        print("MESSAGE TRIGGERED");
  }
0 голосов
/ 30 мая 2018

Не спите основной поток.

Вместо этого вы устанавливаете вызов функции через секунду после.

Вы должны создать таймер внутри каждой ячейки, тогда у каждой ячейки есть отдельные таймеры.

class MyCustomCell: UITableViewCell {
@IBOutlet weak private var myLabel: UILabel!

private var timer: Timer?
private var timeCounter: Double = 0

var expiryTimeInterval: TimeInterval? {
    didSet {
        startTimer()
    }
}

private func startTimer() {
    if let interval = expiryTimeInterval {
        timeCounter = interval // should be 1 for 1 second.
        if #available(iOS 10.0, *) {
            timer = Timer(timeInterval: 1.0,
                          repeats: true,
                          block: { [weak self] _ in
                            guard let strongSelf = self else {
                                return
                            }
                            strongSelf.onComplete()
            })
        } else {
            timer = Timer(timeInterval: 1.0,
                          target: self,
                          selector: #selector(onComplete),
                          userInfo: nil,
                          repeats: true)
        }
    }
}

@objc func onComplete() {
    guard timeCounter >= 0 else {
        timer?.invalidate()
        timer = nil
        return
    }
    myLabel.text = String(format: "%d", timeCounter)
    timeCounter -= 1
}
}

И вы можете использовать вот так;

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell =  tableView.dequeueReusableCell(withIdentifier: "cell") as! MyCustomCell

    cell.expiryTimeInterval = 10

    return cell
}
0 голосов
/ 30 мая 2018

Ваша проблема в том, что вы работаете в главном потоке и никогда не предоставляете системе возможность обновить таблицу.Вы нарушили правило: никогда не вызывайте sleep в главном потоке .

. Это можно исправить несколькими способами:

1) Запустите цикл в фоновом потоке,и вернитесь в основной поток для вызова self.sendMessage и print.

let size = dictionary[key]!.count;
let pointer = random(lower: 0, upper: UInt32(size) - 1);
let part = dictionary[key]![pointer];

DispatchQueue.global().async {
    for row in part {
        if let message = row as? Message {
            DispatchQueue.main.async {
                self.sendMessage(message: message);
                print("MESSAGE TRIGGERED");
            }
            usleep(1 * 1000 * 1000)
        }

        if let question = row as? Question {

        }
    }
}

2) Используйте повторяющийся таймер с интервалом 1 секунды и добавляйте один элемент к вашей таблице каждый раз, когда таймерпожары.

let size = dictionary[key]!.count;
let pointer = random(lower: 0, upper: UInt32(size) - 1);
let part = dictionary[key]![pointer];

var idx = 0
Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in

    if idx >= part.count {
        timer.invalidate()
    } else {
        let row = part[idx]
        if let message = row as? Message {
            self.sendMessage(message: message);
            print("MESSAGE TRIGGERED");
        }

        if let question = row as? Question {

        }
    }
    idx += 1
}

3) Задержка добавления каждой таблицы все большей задержкой:

let size = dictionary[key]!.count;
let pointer = random(lower: 0, upper: UInt32(size) - 1);
let part = dictionary[key]![pointer];

var delay = 0.0
for row in part {
    if let message = row as? Message {
        DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
            self.sendMessage(message: message);
            print("MESSAGE TRIGGERED");
        }
        delay += 1.0
    }

    if let question = row as? Question {

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...