Navigation Bar and Side Menu with Storyboard Practice

Panther·2021년 4월 14일
0
post-custom-banner

이 글은 Side Menu가 기존 화면을 밀어내는 방법은 아닙니다. 만약 기존 화면을 밀어내는 것을 원하신다면 아래 참고영상 링크를 통해 영상을 봐주시기 바랍니다.

참고영상
https://www.youtube.com/watch?v=Hl_Re_KLhcY

아래처럼 스토리보드에 두 개의 TableView는 무시하시기 바랍니다. 먼저 첫 번째 목적은 Navigation Bar를 스토리보드에서 추가하는 것입니다.

화면 상단에 Editor를 선택하면 아래에 Embed In이 있고 하위에 Navigation Controller가 있습니다. 이를 클릭하면 Navigation Bar Controller가 생성될 것입니다.

아래 화면처럼 Navigation Bar Contorller가 생성되었습니다.

추가 후 Navigation Controller가 Is Initial View Controller인지 아닌지 확인해야 합니다. 만약 아니라면 Simulator에서 검정색 화면만 나타날 것입니다.

버튼을 추가해야 합니다. Bar로 검색하면 아래 이미지처럼 Bar Button Item이 있습니다.

드래그 앤 드랍으로 원하는 위치에 추가합니다. 저는 오른쪽에서 Side Menu가 보이도록 하기 위해 오른쪽에 버튼을 추가했습니다.

사용자가 버튼은 누르면 어떤 화면을 보여줄지 결정해야 합니다. 저는 버튼 터치 시 오른쪽에서 Table View가 보이도록 할 것입니다. 그렇게 하기 위해 Table View Controller를 담을 수 있는 Container View Controller를 알맞은 위치에 추가합니다.

오른쪽에 새로운 View Controller가 추가됩니다. 원하는 View Controller는 Table View이므로 삭제한 후 Table View Controller를 추가합니다. 그리고 이전에 추가한 Container View Controller를 키보드 컨트롤 키를 누른 상태로 드래그해서 Table View에 드랍합니다. 선택할 수 있는 항목이 아래 이미지처럼 나오는데, Embed를 선택합니다.

저는 Table View Controller 객체 파일을 별도로 만들어 Class를 지정해줬습니다. 동시에 임의의 label을 추가했습니다.

Reuse Identifier 설정도 잊지 않고 해야 합니다.

만들었던 Table View controller 객체 파일에 다음 코드를 작성합니다. textLabel.text에 입력되는 것은 제가 임으로 배열에 넣어둔 이모티콘입니다.

class SideMenuTableViewController: UITableViewController {

    private let logData = LogData()

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return logData.logData.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "SideMenuCell", for: indexPath)
        cell.textLabel?.text = logData.logData[indexPath.row].emoji
        return cell
    }

}

배열에 3개의 이모티콘이 들어있었기 때문에 다음과 같은 결과가 나옵니다. 왼쪽의 두 테이블은 무시하고 오른쪽 테이블만 생각하겠습니다.

우선 현재 Container View의 Width를 고정 크기로 설정합니다. 그리고 Safe Area를 기준으로 Top, Bottom에 Layout을 설정하고, Trailing(왼쪽에서 나오는 경우 Container View Controller를 스토리보드 가장 왼쪽에 위치시키고 Leading)을 Width의 마이너스 값, 즉 저의 경우 -402 만큼 설정합니다.

그러면 아래 이미지처럼 Container View Controller가 숨겨집니다.

이제 ViewController에 아래처럼 NSLayoutConstraint를 추가합니다.

    @IBOutlet weak var sideMenuTrailingLayout: NSLayoutConstraint!

그러면 IBOutlet 왼쪽에 비어있는 원이 생깁니다. 이것을 이전에 스토리보드에서 작업한 Trailing Constraint와 연결할 것입니다. 아래 이미지에서 가장 아래에서 세 번째에 위치한 'Side Menu Trailing L...'을 보면 연결된 것을 확인할 수 있습니다. 아래 이미지는 연결이 된 상태이므로 연결이 되지 않았다면 다른 이름일 것입니다. 즉 연결 전에는 아래 이미지와 다르게 보입니다.

ViewController를 수정하기 전에 Container View Controller 객체를 하나 생성하고 아래처럼 작성합니다.

class ContainerViewController: UIViewController {
    
    var sideMenuOpen = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
}

ViewController에서 아래처럼 Navigation Bar에 있는 버튼을 연결하고, @IBAction, containerViewController, configureContainer 메소드를 작성합니다.

class ViewController: UIViewController {

    @IBOutlet weak var sideMenuTrailingLayout: NSLayoutConstraint!
    
    @IBOutlet weak var sideMenuButton: UIBarButtonItem!
    
    @IBAction func sideMenuToggled(_ sender: Any) {
        if containerViewController.sideMenuOpen == false {
            containerViewController.sideMenuOpen = true
            sideMenuTrailingLayout.constant = 0
        } else {
            containerViewController.sideMenuOpen = false
            sideMenuTrailingLayout.constant = -402
        }
        UIView.animate(withDuration: 0.3) {
            self.view.layoutIfNeeded()
        }
    }
    
    var containerViewController: ContainerViewController!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableViewDelegate()
        configureContainer()
    }

    private func configureContainer() {
        containerViewController = ContainerViewController()
    }

}

의미를 해석하면 사용자가 버튼을 누르기 전 ContainerViewController는 sideMenuOpen이 false이면서 동시에 숨겨져 있고, 버튼을 누르면 sideMenuOpen이 true로 바뀌는 동시에 sideMenuTrailingLayout.constant를 0으로 되면서 화면에 보이도록 하는 것입니다.

post-custom-banner

0개의 댓글