Установка значения изображения на ноль приводит к исчезновению ImageView при просмотре стека - PullRequest
0 голосов
/ 31 января 2020

Недавно я переместил группу UIImageViews во вложенные стековые представления (горизонтальные и вертикальные). Всякий раз, когда пользователь нажимает кнопку воспроизведения, он оживляет, а затем запускает таймер. Как только таймер достигнет 0, он должен последовательно переворачивать каждую карту и скрывать само изображение. Это работало, пока я не добавил их в представление стека. Я читал, что представления стека глючат, когда дело доходит до такого рода вещей, но любая попытка исправить это до сих пор не сработала. Я нахожусь в тупике, кто-нибудь может указать мне правильное направление?

Проблема возникает здесь, я думаю

//INFO: Disable cards while viewing.
for card in cardsPhone
{
    card.isUserInteractionEnabled = false
    flipCard(sender: card)
}



DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 5) {

    for card in self.cardsPhone
    {
        DispatchQueue.main.async {

            //THIS IS THE ANIMATION CALL THAT MAKES VIEWS DISAPPEAR.
            self.flipCard(sender: card)

        }
        usleep(20000)
    }

    DispatchQueue.main.async{
        //INFO: Enable cards after hidden.
        for card in self.cardsPhone
        {
            card.isUserInteractionEnabled = true
        }

        //INFO: Enable play button after cards are hidden to prevent crashing layout.
        self.playButtonView.isUserInteractionEnabled = true
    }
}

Flip Animation Controller

func flipCard(sender: UIImageView)
{
    playButtonView.isUserInteractionEnabled = false

    //INFO: If there is no UIImage, assign the appropriate image from the array.
    if sender.image == nil
    {
        sender.image = cardsImages[sender.tag]
        UIView.transition(with: sender, duration: 0.3, options: .transitionFlipFromLeft, animations: nil, completion: nil)
    }
    //INFO: If there is an image, remove it and replace with no Image.
    else
    {
        sender.image = nil
        UIView.transition(with: sender, duration: 0.3, options: .transitionFlipFromRight, animations: nil, completion: nil)
    }
}

Обновление

Я обнаружил, что если я заменю изображение в UIImageView, то именно это и приводит к его исчезновению. Таким образом, проблема связана с кодом выше в операторе else, где sender.image = UIImage(). Не имеет значения, заменю ли я другим изображением или нет, в тот момент, когда изображение меняется, оно исчезает.

Ответы [ 2 ]

0 голосов
/ 02 февраля 2020

Я читал, что представления стека глючат, когда дело доходит до такого рода вещей

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

Что такое представление стека? Это конструктор ограничений для автоматического размещения. И это все, что есть. Помещение представлений в представление стека означает «Пожалуйста, настройте эти представления с равным интервалом» (или какими-либо другими настройками для представления стека) «, используя наложенные вами ограничения на автоматическое расположение».

Хорошо, но как работает представление стека? сделай это? Autolayout требует четырех частей информации, положения x и y, ширины и высоты. Представление стека предоставит позицию, но как насчет размера (ширина и высота) его представлений? Ну, один из способов сказать это - дать вашим представлениям внутренние ограничения (если они не конфликтуют с тем, что еще будет делать представление стека). Но в отсутствие этого он должен использовать intrinsi c size своих представлений. И размер встроенного c представления изображения в режиме автоматического размещения - это размер изображения, которое он содержит.

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

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

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

0 голосов
/ 02 февраля 2020

Решение

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

func setColorImage(viewToModify: UIImageView, colorToSet: UIColor)
{
    let rect = CGRect(origin: .zero, size: viewToModify.layer.bounds.size)

    UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
    colorToSet.setFill()
    UIRectFill(rect)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    guard (image?.cgImage) != nil else { return }
    viewToModify.image = image
    viewToModify.backgroundColor = colorToSet
    viewToModify.isUserInteractionEnabled = false
}

По сути, этот код создает новый cgRect, устанавливает цвет, создает новое изображение из этого цвета, а затем применяет его обратно к UIImageView.

...