꾸준히 안타치기
SideBar / 라이브러리 사용X 본문
스토리보드 구조
Resource그룹을 만들고 이미지를 추가한다.
커스텀클래스를 3개 만든다.
RevealViewController.swift / UIView
import UIKit
class RevealViewController : UIViewController {
}
FrontViewController.swift / UIView
import UIKit
class FrontViewcontroller :UIViewController {
}
SideBarViewController.swift / 테이블뷰
class SideBarViewController : UITableViewController {
}
사이드바 컨트롤러에 스토리보드ID "sw_rear" 입력
_프론트 컨트롤러에 스토리보드ID "sw_front" 입력
만들어놓은 클래스를 메인스토리보드 화면과 각각 연결한다.
SideBarViewcontroller / 목록을 표현할 배열 데이터를 정의
import UIKit
class SideBarViewController : UITableViewController {
//메뉴제목 배열
let titles = [
"메뉴01",
"메뉴02",
"메뉴03",
"메뉴04",
"메뉴05"
]
//메뉴아이콘 배열
let icons = [
UIImage(named: "icon01.png"),
UIImage(named: "icon02.png"),
UIImage(named: "icon03.png"),
UIImage(named: "icon04.png"),
UIImage(named: "icon05.png")
]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 테이블의크기 메뉴제목배열에서 가져오기
return self.titles.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// 재사용 큐로부터 테이블 셀을 꺼내온다.
let id = "menucell" // 재사용 큐에 등록할 식별자
// .dequeueReusableCell(withIdentifier: id)는 재사용 큐에 대기하고 있는 셀을 꺼낼때 호출하는메소드
let cell = tableView.dequeueReusableCell(withIdentifier: id) ??
UITableViewCell(style: .default, reuseIdentifier: id)
//제목과 이미지를 대입한다.
cell.textLabel?.text = self.titles[indexPath.row]
cell.imageView?.image = self.icons[indexPath.row]
//폰트설정
cell.textLabel?.font = UIFont.systemFont(ofSize: 14)
return cell
}
}
a ?? b
a가 nil 이면 b를, nil이 아니면 옵셔널을 해제한 a!를 리턴한다.
테이블뷰 상단 사용자 계정 표시영역 만들기
import UIKit
class SideBarViewController : UITableViewController {
//메뉴제목 배열
let titles = [
"메뉴01",
"메뉴02",
"메뉴03",
"메뉴04",
"메뉴05"
]
//메뉴아이콘 배열
let icons = [
UIImage(named: "icon01.png"),
UIImage(named: "icon02.png"),
UIImage(named: "icon03.png"),
UIImage(named: "icon04.png"),
UIImage(named: "icon05.png")
]
override func viewDidLoad() {
super.viewDidLoad()
//계정정보를 표시할 레이블 객체를 정의한다@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
let accountLabel = UILabel()
accountLabel.frame = CGRect(x: 10, y: 30, width: self.view.frame.width,
height: 30)
accountLabel.text = "abc@gmail.com"
accountLabel.textColor = .white
accountLabel.font = UIFont.boldSystemFont(ofSize: 15)
//테이블뷰 상단에 표시될 뷰를 정의한다.
let v = UIView()
v.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 70)
v.backgroundColor = .brown
v.addSubview(accountLabel)
//생성한 뷰 v를 테이블 헤더 뷰 영역에 등록한다.
self.tableView.tableHeaderView = v
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section:
Int) -> Int {
// 테이블의크기 메뉴제목배열에서 가져오기
return self.titles.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let id = "menucell"
let cell = tableView.dequeueReusableCell(withIdentifier: id) ??
UITableViewCell(style: .default, reuseIdentifier: id)
//제목과 이미지를 대입한다.
cell.textLabel?.text = self.titles[indexPath.row]
cell.imageView?.image = self.icons[indexPath.row]
//폰트설정
cell.textLabel?.font = UIFont.systemFont(ofSize: 14)
return cell
}
}
메인컨트롤러 구현하기 (역할 SideBarController에서 뷰를 가져와 열기, FrontController에서 뷰를 가져와 열기, 뷰컨트롤러를 가져오는것이 아니고 뷰컨트롤러의 뷰를 가져오는 것)
RevealViewController클래스로 구현된 메인컨트롤러는 화면에 직접 나타나지는 않지만, 첫화면을 읽어오고 사이드바를 여닫는 등 사이드 바와 관련된 대부분의 기능을 실제로 처리하는 컨트롤러이다. (커스텀 컨테이너 뷰 컨트롤러)
RevealViewController.swift (메인컨트롤러에 연결)
contentVC - 프론트컨트롤러 객체가 저장될 곳 sideVC- 사이드바컨트롤러 객체가 저장될 곳을 정의한다.
isSideBarShowing - 현재 사이드바 상태를 저장하기 위해 정의한 변수이다.
import UIKit
class RevealViewController : UIViewController {
var contentVC: UIViewController? //콘텐츠를 담당할 뷰 컨트롤러 //자식
var sideVC: UIViewController?// 사이바 메뉴를 담당할 뷰 컨트롤러 //자식
var isSideBarShowing = false // 현재 사이드 바가 열려있는지 여부
let SLIDE_TIME = 0.3 //사이드 바가 열리고 닫히는 데 걸리는 시간 //옵션
let SIDEBAR_WIDTH : CGFloat = 260 //사이드바가 열릴 너비 //옵션
//초기화면을 설정한다.
func setupView(){
}
}
//사이드바의 뷰를 읽어온다.
func getSideView(){
}
//콘텐츠 뷰에 그림자 효과를 준다.
func setShadowEffect(shadow: Bool, offset:CGFloat){
}
//사이드바를 연다.
func openSideBar(_ complete: (()->Void)?) {
}
//사이드바를 닫는다.
func closeSideBar(_ complete: (()->Void)?){
}
)
}
}
setupVIew()
초기화면 설정메소드 / "sw_front"식별자 읽어오기 - **네비컨트롤러의 _프론트컨트롤러 읽어오기
- _프론트컨트롤러(부모), 프론트컨트롤러(자식)이다. 부모컨트롤러만 가져오면 자식컨트롤러는 참조관계를 통해 가져올수 있다.
- _프로트컨트롤러를 먼저읽어온 다음에 프론트컨트롤러를 읽어온다음 contentVC 변수에 대입하여 클래스내 어디서든지 참조할수 있도록한다.
- 읽어온_프로트컨트롤러 객체를 메인컨트롤러의 자식컨트롤러로 연결한다.
- _프론트 컨트롤러의 뷰를 메인컨트롤러의 서브뷰로 등록한다.( 뷰컨트롤러와 뷰를 각각 등록해주기 )
- _프론트 컨트롤러(자식)에게 부모뷰 컨트롤러가 바뀌었음을 알려준다.
//초기화면을 설정한다.
func setupView(){
//1. _프론트컨트롤러 객체를 읽어온다.
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "sw_front") as? UINavigationController {
// 2. 읽어온 컨트롤러를 클래스 전체에서 참조할수 있도록, contentVC속성에 저장한다.
self.contentVC = vc
//3. _프론트 컨트롤러를 메인 컨트롤러의 자식 뷰 컨트롤러로 등록
self.addChild(vc)
//_프론트 컨트롤러의 뷰를 메인 컨트롤러의 서브뷰로 등록
self.view.addSubview(vc.view)
//_프론트 컨틀롤러에 부모뷰 컨트롤러가 바뀌었음을 알려줌.
vc.didMove(toParent: self)
}
}
getSideView()
bringSubviewToFront 사이드바의 등록순서에 상관없이 콘텐츠 뷰가 맨앞에 표시될 수 있도록, 지정된뷰를 화면의 가장 앞쪽으로 가져온다.
//사이드바의 뷰를 읽어온다.
func getSideView(){
guard self.sideVC == nil else {
return
}
// 사이드바 컨트롤러 객체를 읽어온다.
guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "sw_rear") else {
return
}
// 다른 메소드에서도 참조할 수 있도록 sideVC속성에 저장한다.
self.sideVC = vc
// 읽어온 사이드바 컨트롤러 객체를 컨테이너 뷰 컨트롤러에 연결한다.
self.addChild(vc)
self.view.addSubview(vc.view)
//_프론트 컨트롤러에 부모 뷰 컨트롤러가 바뀌었음을 알려준다.
vc.didMove(toParent: self)
//_프론트 컨트롤러의 뷰를 제일 위로 올린다.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
self.view.bringSubviewToFront((self.contentVC?.view)!)
}
setShadowEffect()
//콘텐츠 뷰에 그림자 효과를 준다.
func setShadowEffect(shadow: Bool, offset:CGFloat){
if(shadow == true){ //그림자 효과설정
self.contentVC?.view.layer.masksToBounds = false
self.contentVC?.view.layer.cornerRadius = 10
self.contentVC?.view.layer.shadowOpacity = 0.8
self.contentVC?.view.layer.shadowColor = UIColor.black.cgColor
self.contentVC?.view.layer.shadowOffset = CGSize(width: offset, height: offset)
}else{
self.contentVC?.view.layer.cornerRadius = 0.0;
self.contentVC?.view.layer.shadowOffset = CGSize(width: 0, height: 0)
}
}
openSideBar()
//사이드바를 연다.
func openSideBar(_ complete: (()->Void)?) {
// 앞에서 정의했던 메소드들을 실행
self.getSideView()// 사이드바 뷰를 읽어온다.
self.setShadowEffect(shadow: true, offset: -2)// 그림자 효과를 준다.
// 에니메이션 옵션
let options = UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState])
// 애니메이션 실행
UIView.animate(withDuration: TimeInterval(self.SLIDE_TIME),
delay: TimeInterval(0),
options: options,
animations: {self.contentVC?.view.frame =
CGRect(x: self.SIDEBAR_WIDTH, y: 0, width: self.view.frame.width, height: self.view.frame.height)
},
completion: {
if $0 == true { // 첫번째 매개변수값이 true이면 (애니메이션이 정상종료되었다면,
isSideBarShowing의 변수값을 true로 설정하고, 이어서 complete메소드를 호출하라.
self.isSideBarShowing = true //열림상태로 플래그를 변경한다.
complete?()
}
}
)
}
closeSideBar()
- 사이드바를 열때는 사이드 바의 너비만큼 콘텐츠 뷰를 오른쪽으로 옮겨주었다면, 이제는 콘텐츠 뷰를 원래 자리로 되돌려 놓는다.
- getSideView메소드를 통해 생성한 사이드바 뷰는 다시 열리기 전까지는 사용되지 않으므로 메모리 낭비를 막기 위해 제거해주는것이 좋다.removeFromSuperview()를 호출해 뷰컨트롤러 객체로부터 뷰를 제거한다음 sideVC상수자체의 값도 제거한다.
- 닫힘 상태로 플래그를 변경한다.
- 콘텐츠뷰에 설정해 주었던 그림자효과를 제거하고 원래상태로 되돌린다.
- 인자값으로 입력받은 완료함수를 실행한다. 함수가 비어있을경우에는 호출하지 않아야 하므로 옵셔널 체인으로 처리한다.
//사이드바를 닫는다.
func closeSideBar(_ complete: (()->Void)?){
// 에니메이션 옵션을 정의한다.
let options = UIView.AnimationOptions([.curveEaseInOut, . beginFromCurrentState])
// 애니메이션 실행
UIView.animate(withDuration: TimeInterval(self.SLIDE_TIME),
delay: TimeInterval(0),
options: options,
animations: {
// 옆으로 밀려난 콘텐트 뷰의 위치를 제자리로
self.contentVC?.view.frame =
// x값 0으로 변경 ***********************************************************
CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
},
completion: {
if $0 == true {
// 사이드바 뷰를 제거한다.메모리낭비 방지 ************************************
self.sideVC?.view.removeFromSuperview()
self.sideVC = nil
//닫힘 상태로 플래그를 변경한다.
self.isSideBarShowing = false
//그림자 효과를 제거한다.
self.setShadowEffect(shadow: false, offset: 0)
//인자값으로 입력받은 완료함수를 실행한다. 함수가 비어있을경우에는
// 호출하지 않아야 하므로 옵셔널 체인으로 처리한다.
complete?()
}
}
)
}
FrontController 구현하기 / 실질적인 메인화면 (보이는 화면)
프론트 컨트롤러는 사용자의 터치 이벤트를 입력받아 RevealViewController로 전달해주어야한다.이를 위해서 델리게이트 패턴이 필요하다.
플론트 컨트롤러에 델리게이트 변수를 정의한다. 사용자의 액션이 발생했을때 저장된 참조 정보를 이용해 메인컨트롤러를 찾고 내부에 정의된 openSideBar를 호출하게 된다.
FrontViewController
import UIKit
class FrontViewcontroller :UIViewController {
// 사이드 바 오픈 기능을 위임할 델리게이트 (RevealViewController클래스에 openSideBar 메소드가 정의되어있음)
var delegate: RevealViewController?
사이드바의 오픈기능은 RevealViewController의 openSideBar, closeSideBar에 각각 정의 되어 있음.
사이드바를 열고 닫기위해 델리게이트 메소드 호출구문을 moveSide메소드에 작성한다.
//사용자의 액션에 따라 델리게이트 메소드를 호출한다.
@objc func moveSide(_ sender: Any){
if sender is UIScreenEdgePanGestureRecognizer {
self.delegate?.openSideBar(nil)
}else if sender is UISwipeGestureRecognizer{
self.delegate?.closeSideBar(nil)//사이드 바를 닫는다.
}else if sender is UIBarButtonItem {
if self.delegate?.isSideBarShowing == false { // 닫혀있는 상태이므로 연다.
self.delegate?.openSideBar(nil) //사이드 바를 연다.
}else{
self.delegate?.closeSideBar(nil)//사이드 바를 닫는다.
}
}
}
프론트컨트롤러의 네비게이션바에 사이드바 오픈버튼을 추가하고, moveSide메소드와 연결한다.
왼쪽화면끝에서 오른쪽으로 패닝하는 제스처를 등록한다. 패닝이란 화면의 한쪽끝에서 시작하여 반대편까지 드래그가 이어지는 패턴을 가리키는 용어이다. UISwipeGestureRecognizer 객체 필요
override func viewDidLoad() {
super.viewDidLoad()
//사이드바 오픈용 버튼 정의
let btnSideBar = UIBarButtonItem(image: UIImage(named:"sidemenu.png"), style: UIBarButtonItem.Style.plain, target: self, action: #selector(moveSide))
//버튼을 네비게이션 바의 왼쪽 영역에 추가
self.navigationItem.leftBarButtonItem = btnSideBar
//화면 끝에서 다른 쪽으로 패닝하는 제스처를 정의
let dragLeft = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(moveSide))
dragLeft.edges = UIRectEdge.left
self.view.addGestureRecognizer(dragLeft)
//화면을 스와이프하는 제스처를 정의(사이드 메뉴 닫기용)
let dragRight = UISwipeGestureRecognizer(target: self, action: #selector(moveSide))
dragRight.direction = .left //방향은 왼쪽
self.view.addGestureRecognizer(dragRight)// 뷰에 제스처 객체를 등록
}
RevealViewController에 프론트 컨트롤러의 델리게이트 변수에 참조 정보를 넣어준다.
func setupView(){
//1. _프론트컨트롤러 객체를 읽어온다.
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "sw_front") as?
UINavigationController {
// 2. 읽어온 컨트롤러를 클래스 전체에서 참조할수 있도록, contentVC속성에 저장한다.
self.contentVC = vc
//3. _프론트 컨트롤러를 메인 컨트롤러의 자식 뷰 컨트롤러로 등록
self.addChild(vc)
//_프론트 컨트롤러의 뷰를 메인 컨트롤러의 서브뷰로 등록
self.view.addSubview(vc.view)
//_프론트 컨틀롤러에 부모뷰 컨트롤러가 바뀌었음을 알려줌.
vc.didMove(toParent: self)
// 프론트 컨트롤러의 델리게이트 변수에 참조 정보를 넣어준다.
let frontVC = vc.viewControllers[0] as? FrontViewcontroller
frontVC?.delegate = self
}
}
전체코드
ReavealViewController.swift
import UIKit
class RevealViewController : UIViewController {
var contentVC: UIViewController? //콘텐츠를 담당할 뷰 컨트롤러 //자식
var sideVC: UIViewController?// 사이바 메뉴를 담당할 뷰 컨트롤러 //자식
var isSideBarShowing = false // 현재 사이드 바가 열려있는지 여부
let SLIDE_TIME = 0.3 //사이드 바가 열리고 닫히는 데 걸리는 시간
let SIDEBAR_WIDTH : CGFloat = 260 //사이드바가 열릴 너비
override func viewDidLoad() {
super.viewDidLoad()
self.setupView()// 메인컨트롤러가 로드될때 setupView 메소드가 호출되도록한다.
}
//초기화면을 설정한다.
func setupView(){
//1. _프론트컨트롤러 객체를 읽어온다.
if let vc = self.storyboard?.instantiateViewController(withIdentifier: "sw_front") as?
UINavigationController {
// 2. 읽어온 컨트롤러를 클래스 전체에서 참조할수 있도록, contentVC속성에 저장한다.
self.contentVC = vc
//3. _프론트 컨트롤러를 메인 컨트롤러의 자식 뷰 컨트롤러로 등록
self.addChild(vc)
//_프론트 컨트롤러의 뷰를 메인 컨트롤러의 서브뷰로 등록
self.view.addSubview(vc.view)
//_프론트 컨틀롤러에 부모뷰 컨트롤러가 바뀌었음을 알려줌.
vc.didMove(toParent: self)
// 프론트 컨트롤러의 델리게이트 변수에 참조 정보를 넣어준다.
let frontVC = vc.viewControllers[0] as? FrontViewcontroller
frontVC?.delegate = self
}
}
//사이드바의 뷰를 읽어온다.
func getSideView(){
guard self.sideVC == nil else {
return
}
// 사이드바 컨트롤러 객체를 읽어온다.
guard let vc = self.storyboard?.instantiateViewController(withIdentifier: "sw_rear")
else {
return
}
// 다른 메소드에서도 참조할 수 있도록 sideVC속성에 저장한다.
self.sideVC = vc
// 읽어온 사이드바 컨트롤러 객체를 컨테이너 뷰 컨트롤러에 연결한다.
self.addChild(vc)
self.view.addSubview(vc.view)
//_프론트 컨트롤러에 부모 뷰 컨트롤러가 바뀌었음을 알려준다.
vc.didMove(toParent: self)
//_프론트 컨트롤러의 뷰를 제일 위로 올린다.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
self.view.bringSubviewToFront((self.contentVC?.view)!)
}
//콘텐츠 뷰에 그림자 효과를 준다.
func setShadowEffect(shadow: Bool, offset:CGFloat){
if(shadow == true){ //그림자 효과설정
self.contentVC?.view.layer.masksToBounds = false
self.contentVC?.view.layer.cornerRadius = 10
self.contentVC?.view.layer.shadowOpacity = 0.8
self.contentVC?.view.layer.shadowColor = UIColor.black.cgColor
self.contentVC?.view.layer.shadowOffset = CGSize(width: offset, height: offset)
}else{
self.contentVC?.view.layer.cornerRadius = 0.0;
self.contentVC?.view.layer.shadowOffset = CGSize(width: 0, height: 0)
}
}
//사이드바를 연다.
func openSideBar(_ complete: (()->Void)?) {
// 앞에서 정의했던 메소드들을 실행
self.getSideView()// 사이드바 뷰를 읽어온다.
self.setShadowEffect(shadow: true, offset: -2)// 그림자 효과를 준다.
// 에니메이션 옵션
let options = UIView.AnimationOptions([.curveEaseInOut, .beginFromCurrentState])
// 애니메이션 실행
UIView.animate(withDuration: TimeInterval(self.SLIDE_TIME),
delay: TimeInterval(0),
options: options,
animations: {self.contentVC?.view.frame =
CGRect(x: self.SIDEBAR_WIDTH, y: 0, width: self.view.frame.width, height: self.view.frame.height)
},
completion: {
if $0 == true {
self.isSideBarShowing = true //열림상태로 플래그를 변경한다.
complete?()
}
}
)
}
//사이드바를 닫는다.
func closeSideBar(_ complete: (()->Void)?){
// 에니메이션 옵션을 정의한다.
let options = UIView.AnimationOptions([.curveEaseInOut, . beginFromCurrentState])
// 애니메이션 실행
UIView.animate(withDuration: TimeInterval(self.SLIDE_TIME),
delay: TimeInterval(0),
options: options,
animations: {
// 옆으로 밀려난 콘텐트 뷰의 위치를 제자리로
self.contentVC?.view.frame =
CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
},
completion: {
if $0 == true {
// 사이드바 뷰를 제거한다.메모리낭비 방지
self.sideVC?.view.removeFromSuperview()
self.sideVC = nil
//닫힘 상태로 플래그를 변경한다.
self.isSideBarShowing = false
//그림자 효과를 제거한다.
self.setShadowEffect(shadow: false, offset: 0)
//인자값으로 입력받은 완료함수를 실행한다. 함수가 비어있을경우에는 호출하지 않아야 하므로 옵셔널 체인으로 처리한다.
complete?()
}
}
)
}
}
SideBarViewController.swift
import UIKit
class SideBarViewController : UITableViewController {
//메뉴제목 배열
let titles = [
"메뉴01",
"메뉴02",
"메뉴03",
"메뉴04",
"메뉴05"
]
//메뉴아이콘 배열
let icons = [
UIImage(named: "icon01.png"),
UIImage(named: "icon02.png"),
UIImage(named: "icon03.png"),
UIImage(named: "icon04.png"),
UIImage(named: "icon05.png")
]
override func viewDidLoad() {
super.viewDidLoad()
//계정정보를 표시할 레이블 객체를 정의한다@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
let accountLabel = UILabel()
accountLabel.frame = CGRect(x: 10, y: 30, width: self.view.frame.width, height: 30)
accountLabel.text = "abc@gmail.com"
accountLabel.textColor = .white
accountLabel.font = UIFont.boldSystemFont(ofSize: 15)
//테이블뷰 상단에 표시될 뷰를 정의한다.
let v = UIView()
v.frame = CGRect(x: 0, y: 0, width: self.view.frame.width, height: 70)
v.backgroundColor = .brown
v.addSubview(accountLabel)
//생성한 뷰 v를 테이블 헤더 뷰 영역에 등록한다.
self.tableView.tableHeaderView = v
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// 테이블의크기 메뉴제목배열에서 가져오기
return self.titles.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let id = "menucell"
let cell = tableView.dequeueReusableCell(withIdentifier: id) ?? UITableViewCell(style: .default, reuseIdentifier: id)
//제목과 이미지를 대입한다.
cell.textLabel?.text = self.titles[indexPath.row]
cell.imageView?.image = self.icons[indexPath.row]
//폰트설정
cell.textLabel?.font = UIFont.systemFont(ofSize: 14)
return cell
}
}
FrontViewController.swift
import UIKit
class FrontViewcontroller :UIViewController {
// 사이드 바 오픈 기능을 위임할 델리게이트 (RevealViewController클래스에 openSideBar 메소드가 정의되어있음)
var delegate: RevealViewController?
override func viewDidLoad() {
super.viewDidLoad()
//사이드바 오픈용 버튼 정의
let btnSideBar = UIBarButtonItem(image: UIImage(named:"sidemenu.png"), style: UIBarButtonItem.Style.plain, target: self, action: #selector(moveSide))
//버튼을 네비게이션 바의 왼쪽 영역에 추가
self.navigationItem.leftBarButtonItem = btnSideBar
//화면 끝에서 다른 쪽으로 패닝하는 제스처를 정의
let dragLeft = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(moveSide))
dragLeft.edges = UIRectEdge.left
self.view.addGestureRecognizer(dragLeft)
//화면을 스와이프하는 제스처를 정의(사이드 메뉴 닫기용)
let dragRight = UISwipeGestureRecognizer(target: self, action: #selector(moveSide))
dragRight.direction = .left //방향은 왼쪽
self.view.addGestureRecognizer(dragRight)// 뷰에 제스처 객체를 등록
}
//사용자의 액션에 따라 델리게이트 메소드를 호출한다.
@objc func moveSide(_ sender: Any){
if sender is UIScreenEdgePanGestureRecognizer {
self.delegate?.openSideBar(nil)
}else if sender is UISwipeGestureRecognizer{
self.delegate?.closeSideBar(nil)//사이드 바를 닫는다.
}else if sender is UIBarButtonItem {
if self.delegate?.isSideBarShowing == false { // 닫혀있는 상태이므로 연다.
self.delegate?.openSideBar(nil) //사이드 바를 연다.
}else{
self.delegate?.closeSideBar(nil)//사이드 바를 닫는다.
}
}
}
}
'iOS > 기본편 | 실전편 -꼼꼼한재은씨' 카테고리의 다른 글
SideBar / 계정관리 눌러 -> 새창 프로필화면으로 전환 (0) | 2022.02.17 |
---|---|
SideBar / 새글작성 눌러 -> 프론트뷰로 화면전환 (0) | 2022.02.16 |
② Picker View - customPlist / 커스텀 (0) | 2022.02.12 |
① Picker View - userDefault (0) | 2022.02.11 |
UserDefaults (0) | 2022.02.10 |