티스토리 뷰
안녕하세요.
Stack View를 이용해서 Floating Custom Tab Bar를 만드는 방법을 알아보겠습니다.
앞으로 진행될 내용을 따라하시면
위와 같은 tab bar를 만드실 수 있습니다.
Step 1
Single View App을 만들어주세요.
product name은 CustomTabBar로 설정했습니다.
Step 2
이미 생성되어 있는 ViewController의 이름을 TabViewController로 바꿔주세요.
그리고 Storyboard에서 View와 연결되는 Class를 TabViewController로 설정해줍니다.
Step 3
뷰 하단에 UIView를 붙여넣고 constaints를 적용해줍니다.
Step 4
이전 단계에서 생성한 View에 Stack View를 올리고, Stack View에 4개의 Button을 추가한 뒤,
Stack View의 Distribution을 Fill Equally로 설정합니다.
Step 5
버튼 이름을 각각 First, Second, Third, Fourth로 바꾸고, 각 버튼에 대한 태그를 지정해줍니다.
태그는 각 버튼 순서에 맞춰 0, 1, 2, 3으로 설정했습니다.
step 6
Storyboard에 각 버튼과 연결될 4개의 ViewController를 생성합니다.
그리고 해당 ViewController와 연결될 Class이름을 작성합니다.
step 7
Storyboard ID를 Class이름과 동일하게 작성하고,
Storyboard ID 사용에 체크합니다.
그리고 각 View에 UIScrollView를 추가해주세요.
이렇게 하면 Storyboard에서의 작업은 끝입니다.
step 8
각 버튼과 연결되는 4개의 ViewController 파일을 생성합니다.
step 9
ViewController 파일들에 코드를 작성합니다.
편의상 SecondViewController.swift, ThirdViewController.swift, FourthViewController.swift는 생략했습니다.
FirstViewController와 동일하게 작성하시면 됩니다.
- TabViewController.swift
import UIKit
class TabViewController: UIViewController {
var selectedIndex: Int = 0
var previousIndex: Int = 0
var viewControllers = [UIViewController]()
@IBOutlet var buttons:[UIButton]!
@IBOutlet var tabView:UIView!
var footerHeight: CGFloat = 50
static let firstVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FirstViewController")
static let secondVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController")
static let thirdVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ThirdViewController")
static let fourthVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FourthViewController")
override func viewDidLoad() {
super.viewDidLoad()
viewControllers.append(TabViewController.firstVC)
viewControllers.append(TabViewController.secondVC)
viewControllers.append(TabViewController.thirdVC)
viewControllers.append(TabViewController.fourthVC)
buttons[selectedIndex].isSelected = true
tabChanged(sender: buttons[selectedIndex])
}
}
// MARK: - Actions
extension TabViewController {
@IBAction func tabChanged(sender:UIButton) {
previousIndex = selectedIndex
selectedIndex = sender.tag
buttons[previousIndex].isSelected = false
let previousVC = viewControllers[previousIndex]
previousVC.willMove(toParent: nil)
previousVC.view.removeFromSuperview()
previousVC.removeFromParent()
sender.isSelected = true
let vc = viewControllers[selectedIndex]
vc.view.frame = UIApplication.shared.windows[0].frame
vc.didMove(toParent: self)
self.addChild(vc)
self.view.addSubview(vc.view)
self.view.bringSubviewToFront(tabView)
}
func hideHeader() {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {
self.tabView.frame = CGRect(x: self.tabView.frame.origin.x, y: (self.view.frame.height + self.view.safeAreaInsets.bottom + 16), width: self.tabView.frame.width, height: self.footerHeight)
})
}
func showHeader() {
UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {
self.tabView.frame = CGRect(x: self.tabView.frame.origin.x, y: self.view.frame.height - (self.footerHeight + self.view.safeAreaInsets.bottom + 16), width: self.tabView.frame.width, height: self.footerHeight)
})
}
}
- FirstViewController.swift
import UIKit
class FirstViewController: UIViewController, UIScrollViewDelegate {
@IBOutlet var scrollView: UIScrollView!
var headerVisible = true
override func viewDidLoad() {
super.viewDidLoad()
scrollView.contentSize = CGSize(width: self.view.frame.width, height: 2 * self.view.frame.height)
}
}
extension FirstViewController {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
performHeaderCheck(translation: translation)
}
func performHeaderCheck(translation:CGPoint) {
if translation.y == 0 { return }
if translation.y > 0 {
// Scroll Down
if !headerVisible {
showHeader()
}
} else {
// Scroll Up
if headerVisible {
hideHeader()
}
}
}
func hideHeader() {
self.headerVisible = false
UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {
let parent = self.parent as! TabViewController
parent.hideHeader()
})
}
func showHeader() {
self.headerVisible = true
UIView.animate(withDuration: 0.3, delay: 0, options: .curveLinear, animations: {
let parent = self.parent as! TabViewController
parent.showHeader()
})
}
}
step 10
outlet 변수와 action 함수를 컴포넌트에 연결하겠습니다.
TabViewController에서 buttons 변수를 4개의 버튼과 각각 연결해주세요.
그리고, tabView 변수를 Tab View와 연결해주세요.
tabChanged 함수를 4개의 버튼과 연결해주세요.
FirstViewController로 넘어와서
scrollView 변수와 Scroll View를 연결해주세요.
마지막으로, Scroll View의 delegate와 FirstViewController를 연결해주세요.
이렇게 해서 모든 과정이 끝났습니다!
프로그램을 실행시키면 아래와같은 Floating Tab Bar가 완성됩니다.
참고로 저는 Tab Bar의 Background Color를 Light Gray로 변경했습니다.
* 아래 포스팅을 참고했습니다.
https://medium.com/@prabtanimehul.86/custom-floating-tab-bar-ios-swift-4-2-24abc6f29a70
'Dev.iOS > Swift' 카테고리의 다른 글
[iOS Swift] MVC 패턴 (2) | 2019.12.14 |
---|---|
[iOS Swift] CocoaPods 설치 및 사용 방법 (Xcode) (5) | 2019.11.19 |
[Swift] 컬렉션형 - Set(세트) (0) | 2019.10.13 |
[Swift] 컬렉션형 - Dictionary(딕셔너리) (3) | 2019.10.13 |
[Swift] 컬렉션형 - Array(배열) (0) | 2019.10.12 |
- Total
- Today
- Yesterday
- 알고리즘
- Xcode
- isempty
- algorithm
- 구슬탈출
- count
- 백준
- 호제법
- aws
- Programmers
- dp
- 코딩테스트
- BFS
- SummerCoding
- c++
- 프로그래머스
- ios
- 컬렉션
- 자료구조
- dfs
- Collection
- 시뮬레이션
- 서머코딩
- Swift
- 스위프트
- datastructure
- 삼성역량테스트
- 이진트리
- ec2
- 깊이우선탐색
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |