функция touchesBegan никогда не вводится

Я пытаюсь открыть всплывающее окно для своего приложения. До сих пор всплывающее окно всплывает с фиксированной координатой, я пытаюсь заставить его всплывать в точке, где пользователь нажал. Вот что у меня есть:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    print("touchesbegan")
    for touch in touches{
        //Handle touch
        let location = touch.locationInView(self.view)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        let vc = storyboard.instantiateViewControllerWithIdentifier("ColonyPopoverController") as! ColonyPopoverController
        vc.modalPresentationStyle = .Popover
        vc.preferredContentSize = CGSizeMake(200, 150)

        if let popoverController = vc.popoverPresentationController {
            popoverController.delegate = self
            popoverController.sourceRect = CGRectMake(location.x, location.y, 20, 10)
            popoverController.sourceView = self.view
            self.presentViewController(vc, animated: true, completion: nil)
        }
    }
}

Я заметил, что оператор печати никогда не печатается, когда я нажимаю на симулятор.

В моем представлении включены interaction и multi-touch. Я знаю, что это работает нормально, потому что я также интегрировал его с Google Maps, поэтому, когда я нажимаю, появляется булавка Google:

func mapView(mapView: GMSMapView!, didTapAtCoordinate coordinate: CLLocationCoordinate2D) {
    print("You tapped at \(coordinate.latitude), \(coordinate.longitude)")
    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude)
    marker.title = "Sydney"
    marker.snippet = "Australia"
    marker.map = mapView

}

и я также вижу печать операторов печати. Не уверен, что мне здесь не хватает.

Взаимодействие с пользователем включено как для суперпредставления, так и для представления:

введите здесь описание изображения

введите здесь описание изображения


person Siddhartha    schedule 30.12.2015    source источник


Ответы (3)


Есть три основные причины, по которым представление не получает касаний, когда вы ожидаете:

  • Для userInteractionEnabled установлено значение false. Судя по всему, вы уже убедились, что это не так.

  • Какой-то другой вид находится «поверх» интересующего вида и получает касания. Обратите внимание, что дочернее представление находится поверх своего родителя (в области, охватываемой дочерним элементом), а представление, расположенное ниже в структуре документа раскадровки, находится поверх всех братьев и сестер, которые находятся выше в структуре. (На вашем снимке экрана KittyMapper® находится поверх карты, в любой области, где они перекрываются.) Вам нужно установить userInteractionEnabled в false, если вы не хотите, чтобы вид сверху получал касания.

  • Представление интереса находится за пределами своего родителя.

    Тестирование попадания работает рекурсивно: окно вызывает hitTest(_:withEvent:) для каждого из своих дочерних элементов (в порядке сверху вниз), пока одно из них не вернет значение, отличное от нуля; hitTest(_:withEvent:) немедленно возвращает nil, если pointInside(_:withEvent:) возвращает false; в противном случае hitTest(_:withEvent:) вызывает hitTest(_:withEvent:) для дочернего элемента (в порядке сверху вниз), пока он не вернет ненулевое значение, и возвращает self, если ни один из дочерних элементов не сообщает о попадании.

    Таким образом, если дочерний элемент находится за пределами границ своего родителя, он может быть видимым (если для всех предков clipsToBounds установлено значение false), но никогда не будет получать касания, потому что его родитель pointInside(_:withEvent:) будет отклонять касания, которые кажутся дочерними.

Вы можете диагностировать два последних случая, проверив иерархию представлений с помощью Функция Xcode «Иерархия представлений отладки».

person rob mayoff    schedule 30.12.2015
comment
Спасибо за Ваш ответ. Вместо этого я использовал жестRecognizer и заметил такое же поведение. Я считаю, что моя карта переопределяет распознаватели касания с помощью метода didTapAtCoordinate. Интересно, нельзя ли использовать эти 2 вместе. Попробую функцию Debug View Hierarchy, спасибо. - person Siddhartha; 30.12.2015
comment
Я нашел причину. Googlemaps GMSView использует другие жесты в поле зрения, и его необходимо запретить: mapView.settings.consumesGesturesInView = false;. - person Siddhartha; 31.12.2015

Оказывается, GMSView Googlemaps использует другие жесты в поле зрения, и это должно быть явно запрещено:

mapView.settings.consumesGesturesInView = false;
person Siddhartha    schedule 31.12.2015

Если userInteractionEnabled истинно, тогда должен быть вызван touchesBegan, и ваш код будет работать, и всплывающее окно появится там, где пользователь нажимает.

Если ваше представление является подпредставлением, убедитесь, что userInteractionEnabled имеет значение true для любых суперпредставлений. Взгляните на этот ответ для получения дополнительной информации о touchesBegan not звонят.

person Peter Todd    schedule 30.12.2015
comment
Спасибо за Ваш ответ. Взаимодействие с пользователем включено как для суперпредставления, так и для представления, прикрепленных снимков экрана и обновленного вопроса. - person Siddhartha; 30.12.2015
comment
Я нашел причину. Googlemaps GMSView использует другие жесты в поле зрения, и его необходимо запретить: mapView.settings.consumesGesturesInView = false;. - person Siddhartha; 31.12.2015