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, я увидел, что мои аннотации обновляются быстрее, чем сама моя карта, предлагая, чтобы регион был установлен, он просто ждет чего-то, чтобы визуально обновить карту.
Ответы
Ответ 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
}
}