Подтвердить что ты не робот

SetRegion: MKMapView не реагирует

У меня есть MKMapView с двумя кнопками на нем: увеличение и уменьшение.

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

У меня есть кнопки, привязанные к setRegion на меньшем или большем расстоянии, чем сейчас.

Я попробовал добавить UIPinchGestureRecognizer к моей карте, чтобы остановить анимацию и позволить щепотку работать. Вот как я это сделал:

Я добавил переменную Bool, которая удерживает ли карта в настоящее время анимация нажатием на кнопки.

func pinchRecognized() {
    if animating {
        var region = self.region
        region.span.latitudeDelta += 0.001
        setRegion(region, animated: false)
        animating = false
    }
}

Я переопределяю setRegion следующим образом:

override func setRegion(_ region: MKCoordinateRegion, animated: Bool) {
    if (animated)
    {
        animating = true
        super.setRegion(region, animated: animated)

        perform(#selector(noLongerAnimating), with: nil, afterDelay: 1)
    }
    else
    {
        super.setRegion(region, animated: animated)
    }
}

func noLongerAnimating() {
    animating = false
}

Они работают с остановкой анимации, но сам пинч не распознается самой картой для увеличения, даже если я это делаю:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
    return true
}

Я думаю, что setRegion в pinchRecognized разбивает его, но я не знаю, как еще остановить анимацию.

В соответствии с запросом, код кнопки, обе кнопки используют этот метод, увеличение использует 0,5, уменьшение - 2:

func zoomTo(delta: Double, animated: Bool) {
    var region = self.region
    var span = region.span

    span.latitudeDelta *= delta
    span.longitudeDelta *= delta
    if (span.latitudeDelta < 180 && span.longitudeDelta < 180)
    {
        region.span = span
        setRegion(region, animated: animated)
    }
}

Изменить: я попытался установить setRegion (тот, который останавливает анимацию) в gestureRecognizer:shouldRecognizeSimultaneouslyWith:, но там он не вызывается во время анимации карты.

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

4b9b3361

Ответ 1

Признаки распознавания жестов не срабатывают при анимации. Удерживайте представления в переменной/массиве в ViewController. Используйте код в этом сообщении для выполнения анимаций: fooobar.com/questions/314510/...

Вот тестовый проект: https://github.com/DuncanMC/iOS-CAAnimation-group-demo

Ответ 2

Анимация MapView isUserInteractionEnabled к false при запуске. Однако, если вы хотите, чтобы это было возможно, вы можете подклассифицировать MKMapView и переопределить метод UIView touchhesBegan, чтобы реагировать на взаимодействие пользователей. Там вы можете сначала вызвать setCenter/setRegion (либо начальные, либо целевые значения) без анимации, чтобы прервать/закрыть анимацию и установить isUserInteractionEnabled в true.

MKMapView использует CATiledLayer и, к сожалению, нет простого способа получить регион и/или центр карты в момент прерывания. С другой стороны, я заметил, что продолжительность анимации является постоянной, хотя и частной, поэтому вы можете использовать Таймер, чтобы лучше угадать область карты, когда touchBegun называется

private var isAnimating: Bool = false

override func setRegion(_ region: MKCoordinateRegion, animated: Bool) {
   isAnimating = animated
   ...
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if isAnimating {
       isAnimating = false
       let region = // Destination region or the approximate region where the animation reached at this moment (although this is a nightmare todo)
       setRegion(region: region, animated: false) // or use setCenter
       isUserInteractionEnabled = true 
    }
}