LoginSignup
53
52

More than 5 years have passed since last update.

[Swift]曇りガラスのかかったサイドバー(blur, Xcode6 beta6)

Last updated at Posted at 2014-08-26

sideMenu.gif

いい感じのBlurEffectがかかっているサイドバーの作り方です。

必要なファイルの作成

以下の2つのファイルを作成します。

SideMenu.swift
import UIKit

@objc protocol SideMenuDelegate {
    func sideMenuDidSelectItemAtIndex(index:Int)
    optional func sideMenuWillOpen()
    optional func sideMenuWillClose()
}

class SideMenu : NSObject, MenuTableViewControllerDelegate {

    let menuWidth : CGFloat = 160.0
    let menuTableViewTopInset : CGFloat = 64.0 // if you use translusent navigation bar
    let sideMenuContainerView =  UIView()
    let sideMenuTableViewController = MenuTableViewController()
    var animator : UIDynamicAnimator!
    let sourceView : UIView!
    var delegate : SideMenuDelegate?
    var isMenuOpen : Bool = false

    init(sourceView: UIView, menuData:Array<String>) {
        super.init()
        self.sourceView = sourceView
        self.sideMenuTableViewController.tableData = menuData

        self.setupMenuView()

        animator = UIDynamicAnimator(referenceView:sourceView)
        // Add show gesture recognizer
        var showGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("handleGesture:"))
        showGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Right
        sourceView.addGestureRecognizer(showGestureRecognizer)

        // Add hide gesture recognizer
        var hideGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("handleGesture:"))
        hideGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Left
        sideMenuContainerView.addGestureRecognizer(hideGestureRecognizer)
    }


    func setupMenuView() {

        // Configure side menu container
        sideMenuContainerView.frame = CGRectMake(-menuWidth-1.0, sourceView.frame.origin.y, menuWidth, sourceView.frame.size.height)
        sideMenuContainerView.backgroundColor = UIColor.clearColor()
        sideMenuContainerView.clipsToBounds = false
        sideMenuContainerView.layer.masksToBounds = false;
        sideMenuContainerView.layer.shadowOffset = CGSizeMake(1.0, 1.0);
        sideMenuContainerView.layer.shadowRadius = 1.0;
        sideMenuContainerView.layer.shadowOpacity = 0.125;
        sideMenuContainerView.layer.shadowPath = UIBezierPath(rect: sideMenuContainerView.bounds).CGPath

        sourceView.addSubview(sideMenuContainerView)

        // Add blur view
        var visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light)) as UIVisualEffectView
        visualEffectView.frame = sideMenuContainerView.bounds
        sideMenuContainerView.addSubview(visualEffectView)

        // Configure side menu table view
        sideMenuTableViewController.delegate = self
        sideMenuTableViewController.tableView.frame = sideMenuContainerView.bounds
        sideMenuTableViewController.tableView.clipsToBounds = false
        sideMenuTableViewController.tableView.separatorStyle = .None
        sideMenuTableViewController.tableView.backgroundColor = UIColor.clearColor()
        sideMenuTableViewController.tableView.scrollsToTop = false
        sideMenuTableViewController.tableView.contentInset = UIEdgeInsetsMake(menuTableViewTopInset, 0, 0, 0)

        sideMenuTableViewController.tableView.reloadData()

        sideMenuContainerView.addSubview(sideMenuTableViewController.tableView)
    }

    func handleGesture(gesture: UISwipeGestureRecognizer) {

        if (gesture.direction == .Left) {
            toggleMenu(false)
             delegate?.sideMenuWillClose?()
        }
        else{
            toggleMenu(true)
             delegate?.sideMenuWillOpen?()
        }
    }

    func toggleMenu (shouldOpen: Bool) {
        animator.removeAllBehaviors()
        isMenuOpen = shouldOpen
        let gravityDirectionX: CGFloat = (shouldOpen) ? 0.5 : -0.5;
        let pushMagnitude: CGFloat = (shouldOpen) ? 20.0 : -20.0;
        let boundaryPointX: CGFloat = (shouldOpen) ? menuWidth : -menuWidth-1.0;

        let gravityBehavior = UIGravityBehavior(items: [sideMenuContainerView])
        gravityBehavior.gravityDirection = CGVectorMake(gravityDirectionX, 0.0)
        animator.addBehavior(gravityBehavior)

        let collisionBehavior = UICollisionBehavior(items: [sideMenuContainerView])
        collisionBehavior.addBoundaryWithIdentifier("menuBoundary", fromPoint: CGPointMake(boundaryPointX, 20.0),
            toPoint: CGPointMake(boundaryPointX, sourceView.frame.size.height))
        animator.addBehavior(collisionBehavior)

        let pushBehavior = UIPushBehavior(items: [sideMenuContainerView], mode: UIPushBehaviorMode.Instantaneous)
        pushBehavior.magnitude = pushMagnitude
        animator.addBehavior(pushBehavior)

        let menuViewBehavior = UIDynamicItemBehavior(items: [sideMenuContainerView])
        menuViewBehavior.elasticity = 0.3
        animator.addBehavior(menuViewBehavior)
    }

    func menuControllerDidSelectRow(indexPath:NSIndexPath) {  
         delegate?.sideMenuDidSelectItemAtIndex(indexPath.row)
    }

    func toggleMenu () {
        if (isMenuOpen) {
            toggleMenu(false)
        }
        else {
            toggleMenu(true)
        }
    }
}
MenuTableViewController.swift
//
//  MenuController.swift
//  SwiftSideMenu
//
//  Created by Evgeny on 23.07.14.
//  Copyright (c) 2014 Evgeny Nazarov. All rights reserved.
//

import UIKit

protocol MenuTableViewControllerDelegate {
    func menuControllerDidSelectRow(indexPath:NSIndexPath)
}

class MenuTableViewController: UITableViewController {

    var delegate : MenuTableViewControllerDelegate?
    var tableData : Array<String> = []

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

    override func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
        return tableData.count
    }

    override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

        var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell

        if (cell == nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "CELL")
            cell!.backgroundColor = UIColor.clearColor()
            cell!.textLabel.textColor = UIColor.darkGrayColor()
            let selectedBackgroundView = UIView(frame: CGRectMake(0, 0, cell!.frame.size.width, cell!.frame.size.height))
            selectedBackgroundView.backgroundColor = UIColor.grayColor().colorWithAlphaComponent(0.2)
            cell!.selectedBackgroundView = selectedBackgroundView
        }

        cell!.textLabel.text = tableData[indexPath.row]

        return cell
    }

    override func tableView(tableView: UITableView!, heightForRowAtIndexPath indexPath: NSIndexPath!) -> CGFloat {
        return 50.0
    }

    override func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
        delegate?.menuControllerDidSelectRow(indexPath)
    }
}

VCにDelegateを設定

VC.swift
class ViewController: UIViewController, SideMenuDelegate {
    .
    .   
    .
    var sideMenu : SideMenu?

    override func viewDidLoad() {
        super.viewDidLoad()

        sideMenu = SideMenu(sourceView: self.view, menuData: ["UIDynamics", "UIGestures", "UIBlurEffect"])
        sideMenu!.delegate = self


    }

    func sideMenuDidSelectItemAtIndex(index: Int) {
        sideMenu?.toggleMenu()
    }

    @IBAction func toggleSideMenu(sender: AnyObject) {
        sideMenu?.toggleMenu()
    }


Navigation Controllerの作成

Navigation Controllerを作成して、Bar button itemを作成します。
作成したBar button Itemと上記の@IBActionを紐付ければ完了です。
スクリーンショット 2014-08-26 13.19.19.png

スクリーンショット 2014-08-26 13.19.43.png    スクリーンショット 2014-08-26 13.20.32.png

参考

下記を参考にして、beta6用に書き換えました。
https://github.com/evnaz/ENSwiftSideMenu

その他の記事


★女性エンジニア向けのイベントやります
9/17(水)開催 - ZIGExN Swift Girls 〜集え☆iPhoneアプリを作りたい女子〜

53
52
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
53
52