2015-09-28 232 views
0

创建导航面板我做这个教程:斯威夫特

http://www.raywenderlich.com/78568/create-slide-out-navigation-panel-swift

我想实现这个对于有滑出式菜单更换中心视图控制器:

http://www.raywenderlich.com/forums/viewtopic.php?f=20&t=19064&start=40#p85001

在这里我修改的文件的代码,我已经采取了最后的项目,以确保:

CenterViewCont辊:

@objc 
protocol CenterViewControllerDelegate { 
    optional func toggleLeftPanel() 
    optional func toggleRightPanel() 
    optional func collapseSidePanels() 
} 

class CenterViewController: UIViewController { 
    @IBOutlet weak private var imageView: UIImageView! 
    @IBOutlet weak private var titleLabel: UILabel! 
    @IBOutlet weak private var creatorLabel: UILabel! 

    var delegate: CenterViewControllerDelegate? 

    // MARK: Button actions 

    @IBAction func kittiesTapped(sender: AnyObject) { 
     delegate?.toggleLeftPanel?() 
    } 

    @IBAction func puppiesTapped(sender: AnyObject) { 
     delegate?.toggleRightPanel?() 
    } 
} 

ContainerViewController:

import UIKit 
import QuartzCore 

enum SlideOutState { 
    case BothCollapsed 
    case LeftPanelExpanded 
    case RightPanelExpanded 
} 

    class ContainerViewController: UIViewController, CenterViewControllerDelegate, SidePanelViewControllerDelegate, UIGestureRecognizerDelegate { 


    var centerNavigationController: UINavigationController! 
    var centerViewController: CenterViewController! 

    var currentState: SlideOutState = .BothCollapsed { 
    didSet { 
     let shouldShowShadow = currentState != .BothCollapsed 
     showShadowForCenterViewController(shouldShowShadow) 
    } 
    } 

    var leftViewController: SidePanelViewController? 
    var rightViewController: SidePanelViewController? 

    let centerPanelExpandedOffset: CGFloat = 60 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    centerViewController = UIStoryboard.centerViewController() 
    centerViewController.delegate = self 

    // wrap the centerViewController in a navigation controller, so we can push views to it 
    // and display bar button items in the navigation bar 
    centerNavigationController = UINavigationController(rootViewController: centerViewController) 
    view.addSubview(centerNavigationController.view) 
    addChildViewController(centerNavigationController) 

    centerNavigationController.didMoveToParentViewController(self) 

    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGesture:") 
    centerNavigationController.view.addGestureRecognizer(panGestureRecognizer) 
    } 

} 

// MARK: CenterViewController delegate 




extension ContainerViewController: SidePanelViewControllerDelegate { 
    func itemSelected(item: MenuItem) { 
     let vc = item.viewController() 
     vc.navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Menu", style: .Plain, target: self, action: "toggleLeftPanel") 
     self.centerNavigationController.viewControllers = [vc] 
     self.collapseSidePanels() 
    } 
} 

extension ContainerViewController: CenterViewControllerDelegate { 

    func toggleLeftPanel() { 
    let notAlreadyExpanded = (currentState != .LeftPanelExpanded) 

    if notAlreadyExpanded { 
     addLeftPanelViewController() 
    } 

    animateLeftPanel(shouldExpand: notAlreadyExpanded) 
    } 

    func toggleRightPanel() { 
    let notAlreadyExpanded = (currentState != .RightPanelExpanded) 

    if notAlreadyExpanded { 
     addRightPanelViewController() 
    } 

    animateRightPanel(shouldExpand: notAlreadyExpanded) 
    } 

    func collapseSidePanels() { 
    switch (currentState) { 
    case .RightPanelExpanded: 
     toggleRightPanel() 
    case .LeftPanelExpanded: 
     toggleLeftPanel() 
    default: 
     break 
    } 
    } 

    func addLeftPanelViewController() { 
    if (leftViewController == nil) { 
     leftViewController = UIStoryboard.leftViewController() 
     leftViewController!.animals = Animal.allCats() 

     addChildSidePanelController(leftViewController!) 
    } 
    } 



    func addChildSidePanelController(sidePanelController: SidePanelViewController) { 
     sidePanelController.delegate = self 
    } 

    func addRightPanelViewController() { 
    if (rightViewController == nil) { 
     rightViewController = UIStoryboard.rightViewController() 
     rightViewController!.animals = Animal.allDogs() 

     addChildSidePanelController(rightViewController!) 
    } 
    } 

    func animateLeftPanel(#shouldExpand: Bool) { 
    if (shouldExpand) { 
     currentState = .LeftPanelExpanded 

     animateCenterPanelXPosition(targetPosition: CGRectGetWidth(centerNavigationController.view.frame) - centerPanelExpandedOffset) 
    } else { 
     animateCenterPanelXPosition(targetPosition: 0) { finished in 
     self.currentState = .BothCollapsed 

     self.leftViewController!.view.removeFromSuperview() 
     self.leftViewController = nil; 
     } 
    } 
    } 

    func animateCenterPanelXPosition(#targetPosition: CGFloat, completion: ((Bool) -> Void)! = nil) { 
    UIView.animateWithDuration(0.5, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0, options: .CurveEaseInOut, animations: { 
     self.centerNavigationController.view.frame.origin.x = targetPosition 
     }, completion: completion) 
    } 

    func animateRightPanel(#shouldExpand: Bool) { 
    if (shouldExpand) { 
     currentState = .RightPanelExpanded 

     animateCenterPanelXPosition(targetPosition: -CGRectGetWidth(centerNavigationController.view.frame) + centerPanelExpandedOffset) 
    } else { 
     animateCenterPanelXPosition(targetPosition: 0) { _ in 
     self.currentState = .BothCollapsed 

     self.rightViewController!.view.removeFromSuperview() 
     self.rightViewController = nil; 
     } 
    } 
    } 

    func showShadowForCenterViewController(shouldShowShadow: Bool) { 
    if (shouldShowShadow) { 
     centerNavigationController.view.layer.shadowOpacity = 0.8 
    } else { 
     centerNavigationController.view.layer.shadowOpacity = 0.0 
    } 
    } 

} 

extension ContainerViewController: UIGestureRecognizerDelegate { 
    // MARK: Gesture recognizer 

    func handlePanGesture(recognizer: UIPanGestureRecognizer) { 
    let gestureIsDraggingFromLeftToRight = (recognizer.velocityInView(view).x > 0) 

    switch(recognizer.state) { 
    case .Began: 
     if (currentState == .BothCollapsed) { 
     if (gestureIsDraggingFromLeftToRight) { 
      addLeftPanelViewController() 
     } else { 
      addRightPanelViewController() 
     } 

     showShadowForCenterViewController(true) 
     } 
    case .Changed: 
     recognizer.view!.center.x = recognizer.view!.center.x + recognizer.translationInView(view).x 
     recognizer.setTranslation(CGPointZero, inView: view) 
    case .Ended: 
     if (leftViewController != nil) { 
     // animate the side panel open or closed based on whether the view has moved more or less than halfway 
     let hasMovedGreaterThanHalfway = recognizer.view!.center.x > view.bounds.size.width 
     animateLeftPanel(shouldExpand: hasMovedGreaterThanHalfway) 
     } else if (rightViewController != nil) { 
     let hasMovedGreaterThanHalfway = recognizer.view!.center.x < 0 
     animateRightPanel(shouldExpand: hasMovedGreaterThanHalfway) 
     } 
    default: 
     break 
    } 
    } 
} 

private extension UIStoryboard { 
    class func mainStoryboard() -> UIStoryboard { return UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) } 

    class func leftViewController() -> SidePanelViewController? { 
    return mainStoryboard().instantiateViewControllerWithIdentifier("LeftViewController") as? SidePanelViewController 
    } 

    class func rightViewController() -> SidePanelViewController? { 
    return mainStoryboard().instantiateViewControllerWithIdentifier("RightViewController") as? SidePanelViewController 
    } 

    class func centerViewController() -> CenterViewController? { 
    return mainStoryboard().instantiateViewControllerWithIdentifier("CenterViewController") as? CenterViewController 
    } 

} 

SidePanelViewController:

import UIKit 

protocol SidePanelViewControllerDelegate { 
    func itemSelected(item: MenuItem) 
} 

class SidePanelViewController: UIViewController { 

    @IBOutlet weak var tableView: UITableView! 
    var delegate: SidePanelViewControllerDelegate? 

    var animals: Array<Animal>! 

    struct TableView { 
    struct CellIdentifiers { 
     static let AnimalCell = "AnimalCell" 
    } 
    } 

    override func viewDidLoad() { 
    super.viewDidLoad() 

    tableView.reloadData() 
    } 

} 

// MARK: Table View Data Source 

extension SidePanelViewController: UITableViewDataSource { 

    func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return 1 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 3 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier(TableView.CellIdentifiers.AnimalCell, forIndexPath: indexPath) as! AnimalCell 
    cell.configureForAnimal(animals[indexPath.row]) 
    return cell 
    } 

} 

// Mark: Table View Delegate 

extension SidePanelViewController: UITableViewDelegate { 
    func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) { 
     let selectedAnimal = animals[indexPath.row] 
     delegate?.itemSelected(MenuItem(rawValue: indexPath.row)!) 
    } 
} 

enum MenuItem: Int { 
    case Home 
    case Animals 
    case Settings 

    func viewController() -> UIViewController { 
     switch (self) { 
     case Home: return { 
      let vc = UIViewController(); 
      vc.view.backgroundColor = UIColor.greenColor(); 
      return vc 
      }() 
     case Animals: return UIStoryboard.centerViewController()! 
     case Settings: return { 
      let vc = UIViewController(); 
      vc.view.backgroundColor = UIColor.orangeColor(); 
      return vc 
      }() 
     } 
    } 
} 

class AnimalCell: UITableViewCell { 

    @IBOutlet weak var animalImageView: UIImageView! 
    @IBOutlet weak var imageNameLabel: UILabel! 
    @IBOutlet weak var imageCreatorLabel: UILabel! 

    func configureForAnimal(animal: Animal) { 
    animalImageView.image = animal.image 
    imageNameLabel.text = animal.title 
    imageCreatorLabel.text = animal.creator 
    } 

} 


private extension UIStoryboard { 
    class func mainStoryboard() -> UIStoryboard { return UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()) } 

    class func leftViewController() -> SidePanelViewController? { 
     return mainStoryboard().instantiateViewControllerWithIdentifier("LeftViewController") as? SidePanelViewController 
    } 

    class func rightViewController() -> SidePanelViewController? { 
     return mainStoryboard().instantiateViewControllerWithIdentifier("RightViewController") as? SidePanelViewController 
    } 

    class func centerViewController() -> CenterViewController? { 
     return mainStoryboard().instantiateViewControllerWithIdentifier("CenterViewController") as? CenterViewController 
    } 

} 

当我跑我的左边或右边的菜单滑动,它slinding一个黑色的窗口,而不是菜单。

+0

尝试哪里这个问题,你可以分享你的项目发生 – Qbyte

+0

使用最少的代码量? –

回答

0

你错过了几行字在你ContainerViewController.swiftaddChildSidePanelController功能

func addChildSidePanelController(sidePanelController: SidePanelViewController) { 
    sidePanelController.delegate = self 

    /*** Missing Lines Start ***/ 
    view.insertSubview(sidePanelController.view, atIndex: 0) 

    addChildViewController(sidePanelController) 
    sidePanelController.didMoveToParentViewController(self) 
    /*** Missing Lines End ***/ 
} 
+0

这看起来不错,我会做不同的故事板,并把他们的链接(因为现在我只是做一个背景颜色),我会回来给你,如果我得到一个错误:) –

+0

对不起,做你知道我为什么失去我的代表? http://stackoverflow.com/questions/33524590/delegate-is-nil-cant-open-my-slide-out-menu –