본문 바로가기

Programming/iOS

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에 종속되기 때문에 글로벌한 메뉴가 아닌 어떤 한 화면안에 속해 있는 메뉴를 구성하고자 할 때 유용하게 쓰일 수 있을 것입니다.

위 설명에 대한 소스는 다음을 참고하면 됩니다.

 

반응형