오늘은 iOS에서도 많이 사용하는 SideBar를 만들어보겠습니다!
해당 그림과 같은 모습입니다. Hamburger Button이라고 하는 버튼을 누르면 화면이 슬라이딩되며 나타납니다.
만드는 방법은 https://lidium.tistory.com/15에서 포스팅한 방법과 비슷하게 하려고 합니다.
저번에 만들었던, ActionSheet와 같은 느낌으로 만들 예정이에요. ActionSheet는 밑에서 위로 나왔다면,
SideBar는 버튼을 토글하면 사이드바 뷰가 왼쪽에서 오른쪽으로 슬라이딩되게 만들 것입니다.
구조는 크게 세가지인데,
-
SideBar의 Model
-
SideBar의 구현부인 SideBarLauncher,
-
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를 부여할 것입니다.
BlackView는 collectionView의 뒤 배경을 검정색으로 만들어줄 친구입니다.
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를 만들 수 있습니다.
혹시 질문이 있으시면 댓글 달아주시고 틀린점 지적은 감사하게 받겠습니다!
감사합니다!
'iOS' 카테고리의 다른 글
[iOS] 화면전환 애니메이션 커스텀하기 (2) UIViewControllerAnimatedTransitioning, (NavigationController) (0) | 2020.05.23 |
---|---|
[iOS] 화면전환 애니메이션 커스텀하기 - CGAffineTransform, animateTransition [1] (3) | 2020.05.15 |
[iOS] Calendar (2) (0) | 2020.05.02 |
[iOS] Calendar (1) (0) | 2020.04.25 |
[iOS] LinkPresentation (0) | 2020.04.18 |