如何显示UITableViewController作为另一个ViewController前面的向上滑动手势?

问题描述:

我试图让这样的工作。这是优步应用程序。用户可以在背景视图前轻扫另一个视图。如何显示UITableViewController作为另一个ViewController前面的向上滑动手势?

enter image description here

背景的看法是相当简单的,它已经做了。将在顶部滑动的视图将是一个UITableView。我希望用户能够在应用程序启动时首先看到一个小顶部,然后稍微滑动一下,它应该在中间停下来,然后在完全滑动之后应该一直到顶部,取代背景视图。

我看过的框架是适用于iOS的可拉式视图。但它太老了,并没有得到任何好的动画。我也看过SWRevealViewController,但我无法弄清楚如何从下面向上滑动。

我也试过使用一个按钮,所以当用户点击它时,表格视图控制器以模态方式出现,覆盖垂直,但这不是我想要的。它需要识别一个手势。

任何帮助,非常感谢。谢谢。

编辑:我打算不接受我的答案,并保持它打开,如果任何人在未来有更好的方式来实现它。即使我的答案有效,它也可以改进。此外,它并不像Uber应用程序中发生的那样泛滥,这是我的原始问题。

您可以在自定义滚动视图中嵌入该表格视图,该视图只在触摸该表格视图部分(覆盖hittest)时处理触摸,然后将其拖动(禁用tableview滚动),直到上部部分,然后禁用滚动视图和启用的tableview滚动再次

或者,你可以添加滑动手势到你的tableview,并改变它的沿框架和禁用刷卡时,它与那些达到顶峰

实验,最终你会达到你想要

效果

正如Tj3n指出的,你可以使用UISwipeGesture显示UITableView。因此,使用约束(而不是框架)继承人如何能够做到这一点:

转到您的故事板内您想要显示UITableViewUIViewController。拖放UITableView并向UITableView添加前导,尾随和高度。现在在UIViewControllerUITableView之间添加一个垂直约束,以便UITableView出现在以下UIViewController(使用此垂直值玩耍,直到您可以显示UITableView的顶部以满足您的需要)。为垂直间距约束和高度约束创建出口(以防需要设置可在运行时计算出的特定高度)。在向上扫掠只是兴致勃勃地设置垂直约束等于高度有点像的负值:

topSpaceToViewControllerConstraint.constant = -mainTableViewHeightConstraint.constant 

UIView.animate(withDuration: 0.3) { 

    view.layoutIfNeeded() 
}; 

或者

如果你希望能够带给UITableView了视在平底锅上的金额(即。e取决于用户在屏幕上移动了多少或者速度有多快),您应该改用UIPanGestureRecognizer,并尝试为UITableView设置帧而不是autoLayout(因为我不是很喜欢重复调用view.layoutIfNeeded的粉丝。这是一个昂贵的操作,将不胜感激,如果有人会确认或纠正这一点)。

func handlePan(sender: UIPanGestureRecognizer) { 

     if sender.state == .Changed { 
       //update y origin value here based on the pan amount 
     } 
    } 

或者使用的UITableViewController

否则要执行什么,也可以使用UITableViewController,如果你希望,但它涉及到很多伪造和努力通过创建一个自定义UINavigationControllerDelegate主要是创建一个自定义动画将使用UIPercentDrivenInteractiveTransition根据摇摄量使用UIPanGestureRecognizer拉动新的UITableViewController。否则,您可以简单地添加一个UISwipeGestureRecognizer来呈现UITableViewController,但您仍然必须再次创建一个自定义动画来“伪装”您想要的效果。

+0

谢谢,我会试试这个报告。 – Munib

感谢Rikh和Tj3n给我提示。我设法做了一些非常基本的事情,它没有Uber这样好的动画,但它完成了工作。

使用以下代码,您可以轻扫任何UIViewController。我在我的图像上使用了UIPanGestureRecognizer,它始终保持在拖动视图的顶部。基本上,您使用该图像并识别它被拖动的位置,并根据用户的输入设置视图的框架。

首先转到故事板并添加将被拖动的UIViewController的标识符。

enter image description here

然后在MainViewController,使用下面的代码:

class MainViewController: UIViewController { 

// This image will be dragged up or down. 
@IBOutlet var imageView: UIImageView! 

// Gesture recognizer, will be added to image below. 
var swipedOnImage = UIPanGestureRecognizer() 

// This is the view controller that will be dragged with the image. In my case it's a UITableViewController. 
var vc = UIViewController() 

override func viewDidLoad() { 
    super.viewDidLoad() 

    // I'm using a storyboard. 
    let sb = UIStoryboard(name: "Main", bundle: nil) 

    // I have identified the view inside my storyboard. 
    vc = sb.instantiateViewController(withIdentifier: "TableVC") 

    // These values can be played around with, depending on how much you want the view to show up when it starts. 
    vc.view.frame = CGRect(x: 0, y: self.view.frame.height, width: self.view.frame.width, height: -300) 


    self.addChildViewController(vc) 
    self.view.addSubview(vc.view) 
    vc.didMove(toParentViewController: self) 

    swipedOnImage = UIPanGestureRecognizer(target: self, action: #selector(self.swipedOnViewAction)) 
    imageView.addGestureRecognizer(swipedOnImage) 

    imageView.isUserInteractionEnabled = true 

} 

// This function handles resizing of the tableview. 
func swipedOnViewAction() { 

    let yLocationTouched = swipedOnImage.location(in: self.view).y 

    imageView.frame.origin.y = yLocationTouched 

    // These values can be played around with if required. 
    vc.view.frame = CGRect(x: 0, y: yLocationTouched, width: UIScreen.main.bounds.width, height: (UIScreen.main.bounds.height) - (yLocationTouched)) 
    vc.view.frame.origin.y = yLocationTouched + 50 

} 

最终产品

enter image description here

现在,这可能是我的答案可能不是最这是一种有效的方式,但我是iOS新手,所以这是目前我能想到的最好的方法。

+0

什么是swipedDiscoveries? – Edu

+0

@Edu对不起,它应该swipedOnImage UIPanGestureRecognizer,我在我的项目中显示发现,并忘记更改名称。谢谢 – Munib

+0

这会解释很多,谢谢! – Edu