Programming/iOS

Swift 메뉴 화면 제작

알레아 2020. 3. 10. 18:25
반응형

아래 영상 처럼 제스쳐 및 버튼을 이용해서 메뉴 화면을 열고 닫는 방법에 대한 소개로,

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

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

 

반응형