본문 바로가기

iOS

[iOS] SideBar

오늘은 iOS에서도 많이 사용하는 SideBar를 만들어보겠습니다!

해당 그림과 같은 모습입니다. Hamburger Button이라고 하는 버튼을 누르면 화면이 슬라이딩되며 나타납니다.

 

 

 

만드는 방법은 https://lidium.tistory.com/15에서 포스팅한 방법과 비슷하게 하려고 합니다.

저번에 만들었던, ActionSheet와 같은 느낌으로 만들 예정이에요. ActionSheet는 밑에서 위로 나왔다면,

SideBar는 버튼을 토글하면 사이드바 뷰가 왼쪽에서 오른쪽으로 슬라이딩되게 만들 것입니다.

 

구조는 크게 세가지인데,

  1. SideBar의 Model

  2. SideBar의 구현부인 SideBarLauncher,

  3. Launcher 안에 TableViewCell 혹은 CollectionViewCell입니다.

 

1. SideBar Model > SideBarComponents.swift

enum SidebarComponents: String {
    
    case name = "asdasd"
    case age = "123123"
    case help = "help"
    case cancel = "cancel"
    
}

열거체와 구조체로 구성해 보았습니다.

 

2. SideBarLauncher.swift

 SideBar의 구현부입니다. 길지만, 생각해보면 어렵지 않습니다.

class SideBar: NSObject {
    let name: SidebarComponents
    
    init(name: SidebarComponents) {
        self.name = name
    }
}

SideBar Class를 선언합니다. name을 가지고 있는 한 줄짜리 CollectionViewCell이 될 것입니다.

NSObject를 채택하여 CollectionViewCell 안에서 활용할 수 있도록 했습니다.

 

  let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        
        cv.backgroundColor = UIColor.white
        return cv
    }()

collectionView를 선언해줍니다. frame이 .zero로 선언을 해 두고, 

SideBar를 함수를 addSubView() 할 때 Size를 다시 부여할 것입니다.

 

또한, 코드로 선언한 레이아웃은 다음과 같이

  override init() {
        super.init()
        
        collectionView.delegate = self
        collectionView.dataSource = self
        
        collectionView.register(SideBarCell.self, forCellWithReuseIdentifier: cellId)
    }

override init()에 delegate를 비롯하여 register까지 해 주어야 합니다.

 

다음은, 버튼을 눌렀을 때 SideBar가 나오게 하겠습니다.

    func setupNavBarButtons() {
        let moreButton = UIBarButtonItem(image: UIImage(named: "hamburgurButton")?.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(handleMore))
        
        navigationItem.leftBarButtonItem = moreButton
    }

NavigationBar에 LeftButton을 세팅해줍니다. 

 

다음은, action에 해당하는 함수입니다. showSideBars()가 실행이 된다면 사이드 바를 슬라이딩 해주게 됩니다.

    func showSideBars() {
        
        if let window = UIApplication.shared.windows.first(where: { $0.isKeyWindow }) {
            blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
            blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
            
            window.addSubview(blackView)
            window.addSubview(collectionView)
            
            let height = window.frame.height
            let width = CGFloat(300)
            
            collectionView.frame = CGRect (x: 0, y: 0, width: self.collectionView.frame.width, height: height)
            blackView.frame = window.frame
            blackView.alpha = 0
            
            UIView.animate(withDuration: 0.7,
                           delay: 0,
                           usingSpringWithDamping: 1,
                           initialSpringVelocity: 1,
                           options: .curveEaseIn,
                           animations: {
                            
                            self.blackView.alpha = 0.5
                            self.collectionView.frame = CGRect(x: 0, y: 0, width: width, height: height)
                            
            }, completion: nil)
            
        }
    }

1. KeyWindow - 가장 맨 위 화면에 삽입될 뷰는 두개입니다. BlackView()collectionView()

collectionView는 아까 선언했던 빈 컬렉션 뷰입니다. 이 해당 구현부에서 실제 CollectionView의 Size를 부여할 것입니다.

BlackViewcollectionView의 뒤 배경을 검정색으로 만들어줄 친구입니다.

 

2. frame의 변화 - frame은 .zero의 CollectionView에서 width와 height를 가지는 CollectionView로 Animate되며 변화할 것입니다.

 

3. CollectionViewCell

override init(frame: CGRect) {
        super.init(frame: frame)
        
        setUpViews()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        
    }
        
    // MARK: - Appearence
    
    let nameLabel: UILabel = {
        let label = UILabel()
        label.text = "Settings"
        label.font = UIFont.systemFont(ofSize: 13)
        
        return label
    }()
    
    func setUpViews() {
        
        addSubview(nameLabel)
        nameLabel.translatesAutoresizingMaskIntoConstraints = false
        
        let constraints = [
            nameLabel.centerXAnchor.constraint(equalTo: contentView.centerXAnchor),
            nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
        ]
        
        NSLayoutConstraint.activate(constraints)
    }
    
    var sideBar: SideBar? {
        didSet {
            nameLabel.text = sideBar?.name.rawValue
        }
    }

CollectionView의 Cell은 Text를 세팅해주고, AutoLayout을 세팅해주어야 합니다. 다음과 같이 세팅을 해 보았습니다.

 

제가 버튼을 44x44짜리를 구하지 못해서 저렇게 되었는데,,요,,,, 저거 네비에 왼쪽 버튼이 맞습니다....

 

 

 

 

다음과 같이 원하는 형태의 SideBar를 만들 수 있습니다. 

혹시 질문이 있으시면 댓글 달아주시고 틀린점 지적은 감사하게 받겠습니다!

 

감사합니다!