Анимируйте изменение размера полноэкранного UIView, чтобы показать другой UIView внизу экрана. - PullRequest
0 голосов
/ 21 июня 2019

Я обновляю приложение iOS Swift (созданное кем-то другим), которое содержит представление («Представление A»), которое изначально занимает весь экран.Для чего это стоит, этот вид является картой.Когда пользователь нажимает на интересующую точку на карте, высота вида карты («Вид A») уменьшается до 75% от высоты экрана, и другой вид («Вид B») отображается внизу.% экрана.Вот визуальное описание этого сценария.

enter image description here

В настоящее время это выполняется следующим образом:

// this is "View A"
var mapView: MGLMapView!
// this is "View B"
var pageViewController : UIPageViewController!
var pageViewControllerFrame = CGRect()

override func viewDidLoad() {
    super.viewDidLoad()

    // setup map view
    mapView = MGLMapView(frame: view.bounds, styleURL: styleUrl)
    mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    view.addSubview(mapView)

    // setup UIPageViewController
    pageViewControllerFrame = CGRect(x: 0, y: self.view.bounds.height * 0.75, width: mapView.bounds.width, height: self.view.bounds.height / 4)

    pageViewController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
    pageViewController.view.frame = pageViewControllerFrame
    pageViewController.view.autoresizingMask = [.flexibleWidth]
    pageViewController.view.translatesAutoresizingMaskIntoConstraints = true
    view.addSubview(pageViewController.view)
    pageViewController.view.isHidden = true
}

@objc func handleMapTap(sender: UITapGestureRecognizer) {

    if userTappedOnPoi == true {
        self.mapView.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: view.bounds.height * 3/4)
        pageViewController.view.isHidden = false
    } else {
        // user tapped on the map but not on a POI so hide pageViewController and reset map frame to take up the entire screen
        pageViewController.view.isHidden = true
        mapView.frame = view.bounds
    }
}

Как вы можетевидите, на экране карты есть распознаватель жестов касания.Если пользователь нажимает на POI, то рамка вида карты будет отрегулирована таким образом, чтобы высота составляла 75% высоты вида, а затем вид снизу («Вид B») становился видимым.Это работает, но я думаю, что это выглядело бы лучше, если бы оно было анимированным, так как высота вида карты уменьшается, вид внизу скользит вверх по экрану.

Я играл с animate(withDuration:delay:options:animations:completion:) но пока не получилось, чтобы анимация работала правильно.Большинство вещей, которые я пробовал (даже с продолжительностью около 3,0 секунд), по-прежнему приводят к тому, что вид карты немедленно меняет свою высоту.Я предполагаю, что это может быть из-за того, что нет автоматических ограничений макета для анимации?

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Вы также можете использовать UIStackView, чтобы легко получать анимацию, изменив свойство isHidden.

Пример:

import UIKit
import PlaygroundSupport

class VC: UIViewController {

    private let view1 = UIView()
    private let view2 = UIView()

    override func viewDidLoad() {
        super.viewDidLoad()
        view1.backgroundColor = .red
        view2.backgroundColor = .green
        view2.isHidden = true
        let stackView = UIStackView(arrangedSubviews: [view1, view2])
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.axis = .vertical
        view.addSubview(stackView)
        NSLayoutConstraint.activate([
            stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            stackView.topAnchor.constraint(equalTo: view.topAnchor),
            stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            view2.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25)
        ])
        view1.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleMapTap(sender:))))
    }

    @objc func handleMapTap(sender: Any) {
        UIView.animate(withDuration: 0.3) {
            self.view2.isHidden = !self.view2.isHidden
            self.view.layoutIfNeeded()
        }
    }
}

PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = VC()
1 голос
/ 21 июня 2019

Использование автоматического размещения лучше в вашем случае, так как с пейджером pageViewController.view.isHidden = true/false скрыто / отображается мгновенно и без синхронизации с развалом карты, поэтому установите ограничения, например

Просмотр карты:top, ведущая, конечная и множительная высота

пейджер: верхняя часть к карте, ведущая, конечная и нижняя для просмотра

Затем анимируйте изменение множителя высоты карты, например

var heightCon:NSLayoutConstraint!

heightCon.constant = self.view.bounds.height * 0.75
UIView.animate(withDuration: 0.5) {
  self.view.layoutIfNeeded()
}
...