Swift 메뉴 화면 제작
아래 영상 처럼 제스쳐 및 버튼을 이용해서 메뉴 화면을 열고 닫는 방법에 대한 소개로,
UIViewController에 종속된 UIView 기반의 메뉴 화면 입니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
프로젝트 생성
메뉴화면을 구성할 프로젝트를 생성합니다.
(여기서는 SwiftMenuView라는 이름으로 생성 하였습니다.)
MenuView 생성
메뉴 화면으로 쓰일 UIView(MenuView.swift)를 생성합니다.

//
// MenuView.swift
// SwiftMenuView
//
// Created by magicmon on 2020/03/10.
// Copyright © 2020 magicmon. All rights reserved.
//
import UIKit
class MenuView: UIView {
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
private func commonInit() {
setupForNibName()
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
메인화면에 연결
MenuView.xib를 메인화면(ViewController.storyboard)에 연결 합니다.
메뉴 View를 메인화면 사이즈에 맞게 AutoLayout을 잡아준 뒤,

MenuView의 크기를 화면과 동일하도록 AutoLayout을 잡아줍니다.

동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
menuView및 menuViewLeading에 대한 Outlet을 설정합니다.
단, menuViewLeading은 위에서 AutoLayout설정한 Width에 연결하도록 합니다.
class ViewController: UIViewController {
@IBOutlet private weak var menuView: MenuView!
@IBOutlet private weak var menuViewLeading: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
}
}


UIPangestureRecognizer 등록
버튼 또는 제스쳐를 이용하여 메뉴 Show/Hide를 시도할 것이기 때문에, 제스쳐를 등록하도록 하겠습니다.
(여기서는 Storyboard를 통해서 등록하는 과정입니다.)
먼저 MainViewController.swif에서 제스쳐 이벤트 처리를 위한 IBOutlet을 등록합니다.
extension ViewController {
@IBAction func panPerformed(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began,. changed:
break
case .ended:
break
default:
break
}
}
}
Storyboard를 통해 UIPanGesture를 등록합니다.
동영상 서비스가 종료되어 해당 콘텐츠를 재생할 수 없습니다.
제스쳐 동작 정의
제스쳐 등록 후 동작에 따른 메뉴 이동을 위한 코드를 작성합니다.
extension ViewController {
@IBAction func panPerformed(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began,. changed:
let translation = sender.translation(in: self.view).x
let panOffset = self.view.frame.size.width * 0.1
if translation > 0 { // swipe right
if self.menuViewLeading.constant < -panOffset {
self.menuViewLeading.constant = -(self.menuView.frame.size.width - translation)
self.view.layoutIfNeeded()
} else {
self.toggleMenu(true)
}
} else { // swipe left
if menuViewLeading.constant > -self.view.frame.size.width + panOffset {
self.menuViewLeading.constant = translation
self.view.layoutIfNeeded()
} else {
self.toggleMenu(false)
}
}
case .ended:
if menuViewLeading.constant < -(self.view.frame.size.width / 2) {
UIView.animate(withDuration: 0.2) { [weak self] in
self?.toggleMenu(false)
}
} else {
UIView.animate(withDuration: 0.2) { [weak self] in
self?.toggleMenu(true)
}
}
default:
break
}
}
}
메뉴 Show/Hide
실제 메뉴의 열고 닫힘에 대한 코드입니다.
버튼 등이나 이벤트를 통해서 메뉴 처리하고 할 때 아래 코드를 이용해서 작업하면 됩니다.
extension ViewController {
func showMenu(duration: TimeInterval = 0.35, completion: ((Bool) -> Void)? = nil ) {
UIView.animate(withDuration: duration, animations: { [weak self] in
self?.toggleMenu(true)
}, completion: completion)
}
func hideMenu(duration: TimeInterval = 0.35, completion: ((Bool) -> Void)? = nil ) {
UIView.animate(withDuration: duration, animations: { [weak self] in
self?.toggleMenu(false)
}, completion: completion)
}
private func toggleMenu(_ isOn: Bool) {
menuViewLeading.constant = isOn ? 0 : -view.frame.size.width
view.layoutIfNeeded()
}
}
UIView를 통해 만들어진 메뉴화면을 ViewController와 연결하는 작업을 간략하게 소개 했습니다.
UIView를 통해 메뉴를 만들었을 때 이점은, 특정 UIViewController에 종속되기 때문에 글로벌한 메뉴가 아닌 어떤 한 화면안에 속해 있는 메뉴를 구성하고자 할 때 유용하게 쓰일 수 있을 것입니다.
위 설명에 대한 소스는 다음을 참고하면 됩니다.