Как обновить представление во время выполнения функции? - PullRequest
0 голосов
/ 12 марта 2019

Я строю алгоритм поиска пути A * в swift.
У меня есть этот точечный объект, который представляет каждую точку на сетке

/// Point Object for each node in the grid
class Point {
    var gridCoordinate: [Int]
    var fCost: Double
    var gCost: Double
    var hCost: Double
    var neighbors: [Point] = []
    var parent: Point?
    var isWall: Bool
    var cell: UIView = UIView()


    init(x: Int, y: Int, f: Double, g: Double, h: Double, neighbors: [Point]) {
        self.gridCoordinate = [x, y]
        self.fCost = f
        self.gCost = g
        self.hCost = h
        self.neighbors = neighbors
        self.parent = nil
        self.isWall = false
    }



    /// Shows the Object on the main view
    func showPoint(on view: UIView, withTheColor color: UIColor) {
        let width = view.frame.width / CGFloat(cols)

        // Seting up the UIView
        cell = UIView(frame: CGRect(x: CGFloat(gridCoordinate[0]) * width, y: CGFloat(gridCoordinate[1]) * width, width: width, height: width))

        // Seting up the UIView

        cell.backgroundColor = color
        cell.layer.borderWidth = 0.3
        cell.layer.borderColor = UIColor.black.cgColor
        view.addSubview(cell)

    }


    /// Finds all the neighbors of a givin Point Object
    func findAllNeighbors(grid: [Point]) {

        var results: [[Int]] = []

        let lowerBoundOfXRange = gridCoordinate[0] - 1
        let upperBoundOfXRange = gridCoordinate[0] + 1

        let lowerBoundOfYRange = gridCoordinate[1] - 1
        let upperBoundOfYRange = gridCoordinate[1] + 1


        for xCoordinate in lowerBoundOfXRange...upperBoundOfXRange {
            for yCoordinate in lowerBoundOfYRange...upperBoundOfYRange {
                if xCoordinate < 0 || yCoordinate < 0 || xCoordinate > rows - 1 || yCoordinate > cols - 1 {
                    continue
                } else if xCoordinate == gridCoordinate[0] && yCoordinate == gridCoordinate[1] {
                    continue
                } else {
                    if gridCoordinate[0] - 1 == xCoordinate && gridCoordinate[1] - 1 == yCoordinate {
                        continue
                    } else if gridCoordinate[0] + 1 == xCoordinate && gridCoordinate[1] - 1 == yCoordinate {
                        continue
                    } else if gridCoordinate[0] - 1 == xCoordinate && gridCoordinate[1] + 1 == yCoordinate {
                        continue
                    } else if gridCoordinate[0] + 1 == xCoordinate && gridCoordinate[1] + 1 == yCoordinate {
                        continue
                    } else {
                        results.append([xCoordinate, yCoordinate])
                    }
                }
            }
        }
        for i in results  {
            for item in grid {
                if item.gridCoordinate == i {
                    neighbors.append(item)
                }
            }
        }
    }
}

У меня есть массив с именем grid, который содержит всеобъекты Point.
Есть функция с именем 'main ()', которая запускает алгоритм.

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

while openSet.count > 0 {
    main()
    for item in cloedSet {
        item.showPoint(on: view, withTheColor: .red)
    }
}

openSet - это все узлыкоторые будут оцениваться, и closedSet - это все узлы, которые были оценены.Таким образом, когда больше нет узлов для оценки, тогда либо есть путь, и он покажет его, либо его нет.

Я хотел бы показать процесс оценки каждого узла.Поверните каждую ячейку красным, когда она будет оценена.
Итак, я изменил ее так, чтобы она ждала одну секунду, а затем снова делает это.

while openSet.count > 0 {
    main()
    for item in cloedSet {
        item.showPoint(on: view, withTheColor: .red)
    }
    sleep(1)
}

Но когда я запускаю это, этого не происходит, он ждет, ноне обновляет вид.Он ожидает его завершения, прежде чем показывать обновление представления.

Как мне сделать так, чтобы он отображал процесс при оценке каждого узла.
Спасибо.

1 Ответ

1 голос
/ 12 марта 2019

Как говорит Роберт, никогда не используйте sleep в главном потоке.Он замораживает пользовательский интерфейс вашего приложения.

Вместо этого запустите таймер, который срабатывает один раз в секунду и вызывает ваш код каждый раз, когда он срабатывает (либо селектор, либо более современная версия, которая требует закрытия.)

В коде таймера добавьте новый элемент из вашего набора.Вам понадобится переменная экземпляра, чтобы отслеживать добавленные вами элементы.(Если ваши коллекции openSet и closedSet являются Set объектами, вам может потребоваться сопоставить исходный набор с любым массивом, чтобы вы получали согласованный порядок при их итерации.

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