【问题标题】:Animate the resizing of full screen UIView to show another UIView at bottom of screen动画调整全屏 UIView 的大小以在屏幕底部显示另一个 UIView
【发布时间】:2019-06-21 14:54:36
【问题描述】:

我正在更新一个 iOS Swift 应用程序(由其他人创建),它包含一个最初填满整个屏幕的视图(“视图 A”)。对于它的价值,这个视图是一张地图。当用户点击地图上的兴趣点时,地图视图(“视图 A”)的高度会缩小到屏幕高度的 75%,而另一个视图(“视图 B”)显示在底部 25屏幕的百分比。这是该场景的视觉描述。

目前,这是这样完成的:

// 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 秒)似乎仍然会导致地图视图立即改变它的高度。我猜这可能是因为没有用于动画的自动布局约束?

【问题讨论】:

    标签: ios swift uiview uiviewanimation


    【解决方案1】:

    在您的情况下使用自动布局会更好,因为寻呼机 pageViewController.view.isHidden = true/false 会立即隐藏/显示,并且不会与地图的折叠同步,因此请设置类似的约束

    Mapview:顶部、前导、尾随和乘数高度

    pager : top to map ,leading , trailing 和 bottom to view

    然后为地图高度乘数的变化设置动画

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

    【讨论】:

      【解决方案2】:

      您也可以使用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()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-14
        • 1970-01-01
        • 1970-01-01
        • 2022-06-26
        相关资源
        最近更新 更多