有没有办法实现IOS斯威夫特滑动工具栏菜单(像Facebook的应用程序),没有任何第三方库的方法吗? 我期待已久的解决方案,但我只成立于Objective-C中实现此功能。
Answer 1:
我相信,你就可以开始表格UISplitViewController这是大大的iOS8上更新。 观看会话视图控制器在进步iOS8上和建设适应企业应用套件的UIKit了解详情。 它们提供的代码示例从第二会话 (但不形成第一个:/)。 在这一点上自然的感觉对我来说,做出这种UI的基础上在iOS8上的分屏视图控制器。
更新:它看起来像他们讲的都是没有着落不是所有的API。 在视频condensesBarsOnSwipe提到当前BETA4不存在,例如。
Answer 2:
更新 :请考虑使用我的更新答案,而不是这一个。 有很多的边缘情况与滚动型/容器视图的方法,可以通过使用自定义视图控制器过渡,而不是避免。
我到处寻找,并不需要一个库中的快捷菜单的解决方案的地方。 结束了创建我自己的,这是相当类似Fengson的方法的教程:
下面是一些要点:
- 创建一个
scrollview
,它将处理菜单滑动,泛手势沿 - 将两个
container
的观点并排,里面scrollview
。 容器允许你嵌入顶级控制器。 - 在
scrollview
,设置paging enabled
,但禁用bounces
。 这将迫使滑出式成打开或闭合状态 -
embed
一个UITableViewController
在左容器 -
embed
一个UITabBarController
在右侧容器 - 在右边的
container
中,添加一个运行时属性layer.shadowOpacity
0.8。 这使您无需任何代码免费影子分离。 - 添加菜单按钮。 您可以使用
NSNotificationCenter
与沟通scrollview
- 对于秘方:用
scrollView.setContentOffset.x
采取菜单的实际开启和关闭的护理
下面是用左滑出式菜单,包括截图和说明标签栏应用程序的工作示例项目。
https://github.com/ThornTechPublic/LeftSlideoutMenu
随着它是如何工作的一个比较通用的解释:
http://www.thorntech.com/2015/06/want-to-implement-a-slideout-menu-in-your-swift-app-heres-how/
Answer 3:
为iOS7和iOS8上滑动侧栏菜单,斯威夫特编码。
如果你想让它在NavigationController水平 (这意味着,它后面人查看控制器):
https://github.com/evnaz/ENSwiftSideMenu
如果你想它只是在一个视图控制器 :
视频: https://www.youtube.com/watch?v=qaLiZgUK2T0
源代码: http://goo.gl/ULWxJh
在这种情况下,iOS7的兼容性,只需添加这个“如果”条件,其中的“添加模糊看法”的评论被放置,这样的:
if (NSClassFromString("UIVisualEffectView") != nil) {
// Add blur view
let blurView:UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
blurView.frame = sideBarContainerView.bounds
sideBarContainerView.addSubview(blurView)
}
Answer 4:
我认为使用自定义视图控制器过渡是使滑出式菜单坚实的方法:
- 您可以自定义动画。
- 过渡是互动的,所以你可以拖动进步前进和后退。 过渡总是能完成或回滚,而永远不会被卡在中间的状态。
- 您可以使用全景手势和屏幕边缘平移手势驱动的交互。 这意味着你可以把它们从战略上尽量减少与水平比划内容冲突。
- 你不必诉诸集装箱意见。 这意味着您的应用程序体系结构是扁平化,您可以使用协议委托代替NSNotifications的。
- 这里只有一次一个视图控制器活跃。 快照是用来给有在屏幕上的第二个VC的错觉。
自定义视图控制器过渡难以在第一学(他们对我来说,至少)。 我写了一篇博客文章就如何创造一个互动的滑出式菜单,并尽我所能,使之容易理解越好。
您也可以直接跳到了GitHub上的代码 。
在一个非常高的水平,这是它如何工作的:
- 您打开滑出式菜单的模式。
- 创建本自定义动画和使用罢免过渡
UIViewControllerAnimatedTransitioning
协议。 您可以使用快照动画时表示主视图控制器。 - 创建潘姿势识别呈现/交互驳回模式。
- 连线泛手势事件的
UIPercentDrivenInteractiveTransition
对象保持同步的过渡与用户的运动。 - 所述呈现控制器采用
UIViewControllerTransitioningDelegate
协议和电线了所有的自定义动画和交互转换。
其实,我在此线程使用滚动型/容器视图前面的回答。 这种方法对于OK的原型,但跑入了大量的边缘情况,使您的应用程序投入生产时的错误。 每周花费回应博客评论和固定边缘情况是什么促使我写关于这个问题的第二博客文章。
Answer 5:
这里的另一个SideMenu库我做出加进来: https://github.com/jonkykong/SideMenu 。
简单的侧面菜单控制被Facebook启发斯威夫特的iOS。 左右两侧。 无需编码。
- 它可以在情节串连图板来实现,而不的一行代码。
- (如果你想获得怪异甚至视差)四个标准的动画风格可供选择。
- 高度可定制而无需编写吨的自定义代码。
- 支持在boths侧面在单一手势侧菜单之间连续滑动。
- 全局菜单配置。 建立一劳永逸的屏幕来完成。
- 菜单可以提出,并驳回了与任何其他视图控制器,因为这种控制使用自定义转换。
Answer 6:
下面是我如何做一个小例子,这个抽屉控件有左,中,右uiviewcontrollers。 这一个工程像松弛的iPad应用程序,其中一侧或另一种是开放的。
/*
To use simply instantiate SlidingDrawerController as your root view in your AppDelegate, or in the
StoryBoard.
Once SlidingDrawerController is instantiated, set the drawerSize of the SlidingDrawerController,
and its leftViewControllerIdentifier, centerViewControllerIdentifier, and
rightViewControllerIdentifier to the Storyboard Identifier of the UIViewController
you want in the different locations.
*/
class SlidingDrawerController: UIViewController {
var drawerSize:CGFloat = 4.0
var leftViewControllerIdentifier:String = "leftViewController"
var centerViewControllerIdentifier:String = "centerViewController"
var rightViewControllerIdentifier:String = "rightViewController"
enum Drawers {
case left
case right
}
private var _leftViewController:UIViewController?
var leftViewController:UIViewController {
get{
if let vc = _leftViewController {
return vc;
}
return UIViewController();
}
}
private var _centerViewController:UIViewController?
var centerViewController:UIViewController {
get{
if let vc = _centerViewController {
return vc;
}
return UIViewController();
}
}
private var _rightViewController:UIViewController?
var rightViewController:UIViewController {
get{
if let vc = _rightViewController {
return vc;
}
return UIViewController();
}
}
static let SlidingDrawerOpenLeft = 1
static let SlidingDrawerOpenRight = 2
var openSide:SlidingDrawerController.Drawers {
get{
return _openSide;
}
}
private var _openSide = SlidingDrawerController.Drawers.left
override func viewDidLoad() {
super.viewDidLoad()
// Instantiate VC's with storyboard ID's
self._leftViewController = self.instantiateViewControllers(storyboardID: self.leftViewControllerIdentifier)
self._centerViewController = self.instantiateViewControllers(storyboardID: self.centerViewControllerIdentifier)
self._rightViewController = self.instantiateViewControllers(storyboardID: self.rightViewControllerIdentifier)
self.drawDrawers(size: UIScreen.main.bounds.size)
self.view.addSubview(self.leftViewController.view)
self.view.addSubview(self.centerViewController.view)
self.view.addSubview(self.rightViewController.view)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition(in: self.view, animation: { (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for beginning of transition
self.drawDrawers(size: size)
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for after transition has completed.
})
}
// MARK: - Drawing View
func drawDrawers(size:CGSize) {
// Calculate Center View's Size
let centerWidth = (size.width/drawerSize) * (drawerSize - 1)
// Left Drawer
self.leftViewController.view.frame = CGRect(x: 0.0, y: 0.0, width: size.width/self.drawerSize, height: size.height)
// Center Drawer
self.centerViewController.view.frame = CGRect(x: self.leftViewController.view.frame.width, y: 0.0, width: centerWidth, height: size.height)
// Right Drawer
self.rightViewController.view.frame = CGRect(x: self.centerViewController.view.frame.origin.x + self.centerViewController.view.frame.size.width, y: 0.0, width: size.width/self.drawerSize, height: size.height)
// Capture the Swipes
let swipeRight = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeRightAction(rec:)))
swipeRight.direction = .right
centerViewController.view.addGestureRecognizer(swipeRight)
let swipeLeft = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeLeftAction(rec:)))
swipeLeft.direction = .left
centerViewController.view.addGestureRecognizer(swipeLeft)
openDrawer(openSide)
}
// MARK: - Open Drawers
func openDrawer(_ side:Drawers) {
self._openSide = side
var rect:CGRect
switch side{
case .left:
rect = CGRect(
x: 0.0,
y: 0.0,
width: self.view.bounds.width,
height: self.view.bounds.height
)
case .right:
rect = CGRect(
x: self.view.bounds.origin.x - self.leftViewController.view.bounds.size.width,
y: 0.0,
width: self.view.bounds.width,
height: self.view.bounds.height
)
}
UIView.animate(withDuration: 0.1, delay: 0, options: UIViewAnimationOptions.curveEaseIn, animations:
{ () -> Void in
// move views here
self.view.frame = rect
}, completion:
{ finished in
})
}
// MARK: - Swipe Handling
@objc func swipeRightAction(rec: UISwipeGestureRecognizer){
self.openDrawer(.left)
}
@objc func swipeLeftAction(rec:UISwipeGestureRecognizer){
self.openDrawer(.right)
}
// MARK: - Helpers
func instantiateViewControllers(storyboardID: String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "\(storyboardID)")
}
}
来源这里 。
图片在这里 。
视频在这里 。
Answer 7:
我在2种方式来实现它。
首先采用Scroll View
和第二使用Container Views
。
你可以有TableViewController
充当一个容器中的菜单和TabBarController
在第二个容器中隐藏标签。 按一个Cell
在一个表视图移到您在标签栏第n个选项卡。
所有你需要做的是动画顶部容器上右键单击按钮或手势。 然后,它可能是这样的:
什么是整齐的是,你可以很容易添加很酷的效果,如采用弹簧通过使用内置的方法来给它充气逼真效果阻尼动画的UIView。 您还可以添加阴影您的主视图(图中未添加),以使它看起来像上面的菜单页面。