Анимация высоты UIScrollView на основе его содержимого

#ios #swift #uiscrollview #uistackview

Вопрос:

Мое положение:

У меня есть горизонтальное представление прокрутки, содержащее представление стека. Внутри этого стека есть несколько представлений, которые можно развернуть/свернуть.

Когда я хочу развернуть одно из этих представлений, я сначала показываю некоторые подвиды в представлении. После этого мне нужно изменить высоту прокрутки на основе новой высоты этого представления.

Но это не работает…

Я пробую этот код:

         UIView.animate(withDuration: 0.3) { [self] in
            // Toggle hight of all subViews
            stackView.arrangedSubviews.forEach { itemView in
                guard let itemView = itemView as? MyView else { return }
                itemView.toggleView()
            }
            
            // Now update the hight of the StackView
            // But here the hight is always from the previous toggle
            let height = self.stackView.arrangedSubviews.map {$0.frame.size.height}.max() ?? 0.0
            print(height)

            heightConstraint.constant = height
        }
 

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

У кого-нибудь есть идеи, как это решить?

Комментарии:

1. Можете ли вы добавить немного графики или демо-версии?

Ответ №1:

Проблема в том, что, что бы вы здесь ни делали:

 itemView.toggleView()
 

возможно, вы что-то сделали, чтобы изменить высоту обзора, но затем вы сразу же звоните:

 let height = self.stackView.arrangedSubviews.map {$0.frame.size.height}.max() ?? 0.0
 

прежде чем UIKit обновит рамки.

Таким образом, вы можете либо отслеживать свое собственное свойство высоты, либо…

получите высоту рамки после обновления, например, с помощью:

     DispatchQueue.main.async {
        let height = self.stackView.arrangedSubviews.map {$0.frame.size.height}.max() ?? 0.0
        print("h", height)
        self.scrollHeightConstraint.constant = height
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }