在视图控制器之间平移(而不是滑动)
Pan (not swipe) between view controllers
我正在创建一个用户界面类似于 Tinder 的应用程序。
我的意思是,可以在三个主视图控制器之间 "panned"。用户只需拖动即可移动到三个视图控制器中的任何一个。
我在我的应用程序中实现了类似的功能,但有一个重要警告:它使用 swipe 手势识别器,而不是 pan 手势识别器。
最终结果看起来和感觉起来都非常不自然。
这就是我希望我的用户界面的行为方式(忽略 Gecko):
这是它当前与滑动手势识别器的行为方式:
注意如何使用 Tinder,您可以平移到新的视图控制器而无需完全提交 segue。而且,如果平移没有将当前视图控制器移动到超过最小阈值,它会简单地弹回原位。这就是我要寻找的行为。
这是我目前用来模仿滑动手势识别器的一些代码:
//The following logic is applied in a similar way to view controllers 1 and 3 as well.
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
addSwipeGestureRecognizers()
}
func addSwipeGestureRecognizers() {
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeLeft))
swipeLeft.direction = UISwipeGestureRecognizer.Direction.left
self.view.addGestureRecognizer(swipeLeft)
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeRight))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
self.view.addGestureRecognizer(swipeRight)
}
@objc func handleSwipeLeft() {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let viewController1 = storyboard.instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
let transition:CATransition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromLeft
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
navigationController!.pushViewController(viewController1, animated: false)
}
@objc func handleSwipeRight() {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let viewController3 = storyboard.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
let transition:CATransition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
navigationController!.pushViewController(viewController3, animated: false)
}
}
我还利用自定义 UIViewControllerAnimatedTransitioning
使推送视图控制器从左侧或右侧推出呈现视图控制器。这样做与呈现视图控制器顶部的默认堆叠相反。我还隐藏了 UINavigationController
的导航栏。
我不确定 UINavigationController 是否是提供您所需内容的正确容器控制器。您可能会发现 UIPageViewController 是一个更好的选择,我认为它会提供您正在寻找的开箱即用的自然滑动手势,尽管它是一个相当不透明 class 并且有其自身的一些怪癖。
要走自定义路线(使用 UINavigationController 或更多 flexible/customisable UIViewController 自定义演示),您使用 UIViewControllerAnimatedTransitioning 和其他(许多)相关协议走在正确的轨道上。如果您赶时间,那条路线将花费您相当长的时间来实现,因此目前可能需要一个简单的 UIPageViewController 实现。
github 上的这个项目可能会帮助您实现您的要求 -
Here
我正在创建一个用户界面类似于 Tinder 的应用程序。
我的意思是,可以在三个主视图控制器之间 "panned"。用户只需拖动即可移动到三个视图控制器中的任何一个。
我在我的应用程序中实现了类似的功能,但有一个重要警告:它使用 swipe 手势识别器,而不是 pan 手势识别器。
最终结果看起来和感觉起来都非常不自然。
这就是我希望我的用户界面的行为方式(忽略 Gecko):
这是它当前与滑动手势识别器的行为方式:
注意如何使用 Tinder,您可以平移到新的视图控制器而无需完全提交 segue。而且,如果平移没有将当前视图控制器移动到超过最小阈值,它会简单地弹回原位。这就是我要寻找的行为。
这是我目前用来模仿滑动手势识别器的一些代码:
//The following logic is applied in a similar way to view controllers 1 and 3 as well.
class ViewController2: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
addSwipeGestureRecognizers()
}
func addSwipeGestureRecognizers() {
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeLeft))
swipeLeft.direction = UISwipeGestureRecognizer.Direction.left
self.view.addGestureRecognizer(swipeLeft)
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipeRight))
swipeRight.direction = UISwipeGestureRecognizer.Direction.right
self.view.addGestureRecognizer(swipeRight)
}
@objc func handleSwipeLeft() {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let viewController1 = storyboard.instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
let transition:CATransition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromLeft
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
navigationController!.pushViewController(viewController1, animated: false)
}
@objc func handleSwipeRight() {
let storyboard = UIStoryboard(name: "Main", bundle: .main)
let viewController3 = storyboard.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
let transition:CATransition = CATransition()
transition.duration = 0.25
transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
transition.type = CATransitionType.push
transition.subtype = CATransitionSubtype.fromRight
self.navigationController!.view.layer.add(transition, forKey: kCATransition)
navigationController!.pushViewController(viewController3, animated: false)
}
}
我还利用自定义 UIViewControllerAnimatedTransitioning
使推送视图控制器从左侧或右侧推出呈现视图控制器。这样做与呈现视图控制器顶部的默认堆叠相反。我还隐藏了 UINavigationController
的导航栏。
我不确定 UINavigationController 是否是提供您所需内容的正确容器控制器。您可能会发现 UIPageViewController 是一个更好的选择,我认为它会提供您正在寻找的开箱即用的自然滑动手势,尽管它是一个相当不透明 class 并且有其自身的一些怪癖。
要走自定义路线(使用 UINavigationController 或更多 flexible/customisable UIViewController 自定义演示),您使用 UIViewControllerAnimatedTransitioning 和其他(许多)相关协议走在正确的轨道上。如果您赶时间,那条路线将花费您相当长的时间来实现,因此目前可能需要一个简单的 UIPageViewController 实现。
github 上的这个项目可能会帮助您实现您的要求 - Here