Есть ли способ реализовать меню боковой панели слайдов (например, приложение Facebook) в IOS Swift без какой-либо сторонней библиотеки? Я ищу решения, но я только основал эту функцию, реализованную в Objective-C.
Меню боковой панели слайдов IOS 8 Swift
Ответ 1
Я считаю, что вы можете запустить форму UISplitViewController, которая была резко обновлена в iOS8. Наблюдайте за сеансами Просмотр улучшений контроллера в iOS8 и Создание адаптивных приложений с помощью UIKit. Они обеспечивают пример кода со второго сеанса (но не образуют первую:/). На данный момент для меня естественно создать такой пользовательский интерфейс, основанный на контроллере разделенного вида в iOS8.
Обновление: похоже, что не все API, о которых они говорят, все еще приземляются. В текущем бета-версии 4, упомянутой в видеоконденсатах, BarsOnSwipe не представляется, например.
Ответ 2
Обновить. Пожалуйста, используйте мой обновленный ответ, а не этот. Там много крайних случаев с помощью подхода Scrollview/Container View, которого можно избежать, используя вместо этого Custom Transiler Transitions.
Я смотрел повсюду для решения меню Swift, которое не требовало библиотеки. Закончилось создание собственного учебника, которое довольно похоже на подход Fengson:
Вот некоторые из основных моментов:
- Создайте
scrollview
, который будет обрабатывать перемещение меню, а также жест панорамы - Поместите два представления
container
рядом друг с другом, внутриscrollview
. Контейнеры позволяют встроить контроллеры верхнего уровня. - На
scrollview
установитеpaging enabled
, но отключитеbounces
. Это приведет к принудительному выходу в открытое или закрытое состояние. -
embed
aUITableViewController
в левом контейнере -
embed
aUITabBarController
в правом контейнере - Справа
container
добавьте атрибут runtimelayer.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/
Ответ 3
Меню боковой панели слайдов для iOS7 и iOS8, Swift.
Если вы хотите, чтобы он находился на уровне NavigationController (это означает, что для него все остальные контроллеры):
https://github.com/evnaz/ENSwiftSideMenu
Если вы хотите его просто в одном ViewController:
Видео: 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)
}
Ответ 4
Я думаю, что использование Custom View Controller Transitions - прочный подход для создания меню выноса:
- Вы можете настроить анимацию.
- Переход является интерактивным, поэтому вы можете перемещаться вперед и назад. Переход всегда заканчивается или откатывается назад и никогда не застревает между состояниями.
- Для управления взаимодействием используются жесты и жесты экрана. Это означает, что вы можете разместить их стратегически, чтобы минимизировать конфликт с горизонтальным жестовым контентом.
- Вам не нужно прибегать к Container Views. Это означает, что ваша архитектура приложения более плоская, и вы можете использовать протокол-делегат вместо NSNotifications.
- Только один монитор ViewController активен одновременно. Снимки используются, чтобы дать иллюзию, что на экране есть второй VC.
Пользовательский контроллер просмотра Переходы трудно освоить сначала (они были для меня, по крайней мере). Я написал сообщение в блоге о том, как создать интерактивное меню выноса и старался изо всех сил сделать его максимально понятным.
Вы также можете перейти прямо в код на GitHub.
На очень высоком уровне, вот как это работает:
- Вы открываете меню слайдов как модальное.
- Вы создаете пользовательские анимации для настоящих и отклоняете переходы с использованием протокола
UIViewControllerAnimatedTransitioning
. Вы используете моментальный снимок для представления главного контроллера представления во время анимации. - Вы создаете распознаватели жеста, чтобы представить/отклонить модально интерактивно.
- Вы переносите события "Жест" в объект
UIPercentDrivenInteractiveTransition
, чтобы синхронизация осуществлялась с помощью движений пользователя. - Представляющий контроллер использует протокол
UIViewControllerTransitioningDelegate
и подключает все пользовательские анимации и интерактивные переходы.
На самом деле у меня есть предыдущий ответ в этом потоке, который использует Scrollview/Container View. Этот подход подходит для прототипа, но он запускается во множество случаев и ошибок при создании готового приложения. Проводя каждую неделю, отвечая на комментарии в блоге и фиксируя крайние случаи, мотивировал меня написать вторую запись в блоге по этому вопросу.
Ответ 5
Здесь другая библиотека SideMenu, которую я добавил, чтобы добавить в микс: https://github.com/jonkykong/SideMenu.
Простое управление боковым меню для iOS в Swift, вдохновленное Facebook. Правильно и левой стороны. Кодирование не требуется.
- Он может быть реализован в раскадровке без единой строки кода.
- Четыре стандартных стили анимации на выбор (даже параллакс, если вы хотите получить странный).
- Высоко настраиваемый без необходимости писать тонны настраиваемого кода.
- Поддерживает непрерывную прокрутку между боковыми меню с обеих сторон одним жестом.
- Глобальная конфигурация меню. Настройте один раз и сделайте все экраны.
- Меню могут быть представлены и отклонены так же, как и любой другой контроллер просмотра, поскольку этот элемент управления использует настраиваемые переходы.
Ответ 6
Вот небольшой пример того, как я это делаю, этот элемент управления ячеек имеет uiviewcontrollers для левого, центрального и правого. Это работает как приложение Slack IPad, где открыта одна или другая сторона.
/*
To use simply instantiate NVMDrawerController as your root view in your AppDelegate, or in the
StoryBoard.
Once NVMDrawerController is instantiated, set the drawerSize of the NVMDrawerController,
and its leftViewControllerIdentifier, centerViewControllerIdentifier, and
rightViewControllerIdentifier to the Storyboard Identifier of the UIViewController
you want in the different locations.
*/
class NVMDrawerController: UIViewController {
// This is where you set the drawer size (i.e. for 1/3rd use 3.0, for 1/5 use 5.0)
var drawerSize:CGFloat = 4.0
var leftViewControllerIdentifier:String = "LeftController"
var centerViewControllerIdentifier:String = "CenterController"
var rightViewControllerIdentifier:String = "RightController"
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 NVMDrawerOpenLeft = 0
static let NVMDrawerOpenRight = 1
var openSide:Int {
get{
return _openSide;
}
}
private var _openSide:Int = NVMDrawerOpenLeft
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Instantiate VC with storyboard ID's
_leftViewController = instantiateViewControllers(leftViewControllerIdentifier)
_centerViewController = instantiateViewControllers(centerViewControllerIdentifier)
_rightViewController = instantiateViewControllers(rightViewControllerIdentifier)
// Call configDrawers() and pass the drawerSize variable.
drawDrawers(UIScreen.mainScreen().bounds.size)
self.view.addSubview(leftViewController.view)
self.view.addSubview(centerViewController.view)
self.view.addSubview(rightViewController.view)
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for beginning of transition
self.drawDrawers(size)
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
// This is for after transition has completed.
})
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Drawing View
func drawDrawers(size:CGSize) {
// Calculate Center View Size
let centerWidth = (size.width/drawerSize) * (drawerSize - 1)
// Left Drawer
leftViewController.view.frame = CGRect(x: 0.0, y: 0.0, width: size.width/drawerSize, height: size.height)
// Center Drawer
centerViewController.view.frame = CGRect(x: leftViewController.view.frame.width, y: 0.0, width: centerWidth, height: size.height)
// Right Drawer
rightViewController.view.frame = CGRect(x: centerViewController.view.frame.origin.x + centerViewController.view.frame.size.width, y: 0.0, width: size.width/drawerSize, height: size.height)
//rightViewController = rc
// Capture the Swipes
let swipeRight = UISwipeGestureRecognizer(target: self, action: Selector("swipeRightAction:"))
swipeRight.direction = .Right
centerViewController.view.addGestureRecognizer(swipeRight)
let swipeLeft = UISwipeGestureRecognizer(target: self, action: Selector("swipeLeftAction:"))
swipeLeft.direction = .Left
centerViewController.view.addGestureRecognizer(swipeLeft)
if(openSide == NVMDrawerController.NVMDrawerOpenLeft){
openLeftDrawer()
}
else{
openRightDrawer()
}
}
// MARK: - Open Drawers
func openLeftDrawer() {
_openSide = NVMDrawerController.NVMDrawerOpenLeft
UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations:
{ () -> Void in
// move views here
self.view.frame = CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width, height: self.view.bounds.height)
}, completion:
{ finished in
})
}
func openRightDrawer() {
_openSide = NVMDrawerController.NVMDrawerOpenRight
UIView.animateWithDuration(0.1, delay: 0, options: UIViewAnimationOptions.CurveEaseIn, animations:
{ () -> Void in
// move views here
self.view.frame = 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)
}, completion:
{ finished in
})
}
// MARK: - Swipe Handling
func swipeRightAction(rec: UISwipeGestureRecognizer){
self.openLeftDrawer()
}
func swipeLeftAction(rec:UISwipeGestureRecognizer){
self.openRightDrawer()
}
// MARK: - Helpers
func instantiateViewControllers(storyboardID: String) -> UIViewController {
if let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("\(storyboardID)") as? UIViewController{
return viewController;
}
return UIViewController();
}
}
Ответ 7
Я реализовал его двумя способами.
Сначала используйте Scroll View
и второй, используя Container Views
.
Вы можете использовать TableViewController
как меню в одном контейнере и TabBarController
со скрытыми вкладками во втором контейнере. Нажатие a Cell
в представлении таблицы перемещает вас на n-ю вкладку в панели вкладок.
Все, что вам нужно сделать, - это анимировать верхний контейнер прямо при нажатии кнопки или в жесте. Тогда это может выглядеть так:
То, что аккуратно, - это то, что вы можете легко добавить интересные эффекты, такие как анимация UIView с помощью демпфирования spring, используя встроенные методы, чтобы придать ему реалистичный бодрый эффект. Вы также можете добавить тень к своему основному представлению (не добавленному на картинке), чтобы сделать его похожим на страницу над меню.