Действие UIButton не запускается после изменения макетов ограничений - PullRequest
0 голосов
/ 24 августа 2018

У меня есть UIButton на раскадровке ViewController. Когда я загружаю данные в форму и макет значительно меняется, кнопка не распознает действие касания.

Я выяснил, что когда кнопка видна в окне прокрутки сразу после нее, если она заполнена данными, действие касания работает.

Если данные слишком длинные и кнопка вначале не видна, только когда она прокручивается на дисплей, сенсорное действие не работает.

Я проверял, есть ли что-то над кнопкой, но ничего. Я попытался изменить zPosition кнопки, не решил проблему.

В чем может быть проблема?

Я создал пользовательские классы из UIScrollView и UIButton, чтобы проверить, как срабатывает событие touch. Это показывает то же поведение, что очевидно. Если кнопка видна в самом начале, срабатывает событие touchesBegan UIButton. Если кнопка перемещается вниз и не видна в начале, она никогда не срабатывает, но вместо этого вызывается touchchesBegan вида прокрутки.

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

Существует ли какая-либо функция обновления макета или дисплея, которая должна вызываться для возврата поведения к кнопке?

My storyboard setup:

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

func fillFormWithData() {
    dispDescription.text = jSonData[0]["advdescription"]
    dispLongDescription.text = jSonData[0]["advlongdesc"]
    priceandcurrency.text = jSonData[0]["advprice"]! + " " + jSonData[0]["advpricecur"]!
    validitydate.text = jSonData[0]["advdate"]!
    contentview.layoutIfNeeded()
    let contentRect = CGRect(x: 0, y: 0, width: scrollview.frame.width, height: uzenetbutton.frame.origin.y+uzenetbutton.frame.height+50)

    contentview.frame.size.height = contentRect.size.height
    scrollview.contentSize = contentview.bounds.size
}

After data load contentview+scrollview jumps to the bottom

After scroll the content view is cut to the original screensize

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

Ответы [ 4 ]

0 голосов
/ 02 сентября 2018

См. @Endre Olah,

  1. Чтобы сделать ситуацию более понятной, сделайте еще одну вещь, установите clipToBound свойство contentview в true .
  2. вы заметите, что после загрузки данных ваша кнопка не видна полностью, это означает, что она смещает за пределы своего parentView (ContentView)
  3. И вот почему кнопка не берет ваше прикосновение.Однако, если вы аккуратно дотронетесь до верхней части кнопки, она все равно сделает свое дело.Поскольку верхняя часть все еще находится в границ из ContentView
  4. Решение : После загрузки данных вы должны убедиться, что вы увеличиваете высоту ContentView такой, что кнопка никогда не должна выходить за пределы своего parentView (ContentView) .

НА ПРИМЕРЕ

@IBOutlet var heightConstraintOfContentView : NSLayoutConstraint!

После загрузки данных

let contentRect = CGRect(x: 0, y: 0, width: scrollview.frame.width, height: uzenetbutton.frame.origin.y+uzenetbutton.frame.height+50)
heightConstraintOfContentView.constant = contentRect.size.height
contentView.layoutIfNeeded()
0 голосов
/ 27 августа 2018

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

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

@IBOutlet weak var ContentViewHeight: NSLayoutConstraint!

func fillFormWithData() {
    dispDescription.text = jSonData[0]["advdescription"]
    dispLongDescription.text = jSonData[0]["advlongdesc"]
    priceandcurrency.text = jSonData[0]["advprice"]! + " " + jSonData[0]["advpricecur"]!
    validitydate.text = jSonData[0]["advdate"]!
    contentview.layoutIfNeeded()
    let contentRect = CGRect(x: 0, y: 0, width: scrollview.frame.width, height: uzenetbutton.frame.origin.y+uzenetbutton.frame.height+50)

    contentview.bounds = contentRect
    scrollview.contentSize = contentRect.size

    ----------- This is the key line to the success ----------
    ContentViewHeight.constant = contentRect.size.height
    ----------------------------------------------------------
}

После того, как это добавлено, оно отлично работает.

Contentsize is perfectly as should be

0 голосов
/ 29 августа 2018

Я использую следующие шаги, когда мне нужно использовать scrollview с динамическим контентом:

1) Сначала добавьте scrollView с сверху, снизу, сзади и , ведущими , равными 0 в супер-вид.

Scroll View Constraints

2) Добавить представление к scrollView и представление , тянущийся, ведущий нижний и верхний пробел к scrollView можно установить до 0 (или вы можете дополнительно добавить маржу).

view Constraints

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

4) Наконец, добавьте ограничение равной высоты и ширины к представлению с Безопасной областью :

enter image description here

и изменить приоритет высоты равным view на 250 :

Это должно решить вашу проблему с UIScrollView .

0 голосов
/ 27 августа 2018

Позвольте мне получить это ясно, кнопка добавлена ​​в раскадровку, и это проект спрайтекит ?? Если вы используете zPosition ?? Почему бы вам не подключить UIButton через помощник редактора в качестве IBAction, тогда действие всегда привязано к кнопке.

Вы также можете сделать это по-другому

Создайте SKLabelNode и поместите его на экран, где вы хотите иметь кнопку, а затем установите для него имя как myButton

override func touchesBegan(_ touches: Set<UITouch>, with event:
UIEvent?) {
 if let touch = touches.first {
    let location = touch.location(in: self)
    let tappedNodes = nodes(at: location)
      for node in tappedNodes {
        if node.name == "myButton" {
           // call your action here
        }
    }
  }
}

РЕДАКТИРОВАТЬ 1: Вы также можете попробовать автоматически изменить размер scrollView.content, это также работает, если вы добавляете какие-либо виды через приложение или программно

    private func resizeScrollView(){
    print("RESIZING THE SCROLLVIEW from \(scrollView.contentSize)")
    for view in scrollView.subviews {
        contentRect = contentRect.union(view.frame)
    }
    scrollView.contentSize = CGSize(width: contentRect.size.width, height: contentRect.size.height + 150)
    print("THE CONTENT SIZE AFTER RESIZING IS: \(scrollView.contentSize)")
}

РЕДАКТИРОВАТЬ 2: Я думаю, что нашел проблему с вашим проектом. Вам нужно переместить MessageButton (UzenetButton) над меткой DispDescription в инспекторе объектов таким образом, чтобы она всегда была выше вашего textView сообщения. В настоящее время UzeneButton находится в самой далекой иерархии вашего представления, поэтому, если текстовое представление изменяется во время редактирования, оно охватывает кнопку, поэтому вы не можете нажать на нее.

...