DirTy™의 하루일과/DirTy™의 가당찮은iOS

[IOS] 간단한 SlideView 구현하기.

DirTy™ 2016. 4. 8. 17:25

오픈소스만 찾아봐도 정말 잘 구현되어 있는 SlideView가 많다.

그래도 간단하게 라도 한번 만들어 보도록 하자. 스위프트 공부하려고 만들어 봤다. ㅎㅎ

결과물은 아래 동영상



일단 구현해보자.

스토리보드는 아래와 같이 구현하였다.

Main View : 메인뷰

Easy View : Container View로 왼쪽 오른쪽으로 이동 할 뷰

Show/Hide 버튼 : Slide Show, Hide

Mode 버튼 : 동영상을 보면 알겠지만 Mode는 2개다. 슬라이드뷰만 이동. 메인뷰 슬라이드뷰 같이 이동.

view effect UISwitch : view animation effect를 준다. uiview animation에 기본으로 있는 damping 을 이용했다.





스토리보드에서 컨테이너뷰는 일단 안보이게 x좌표를 -값을 주어 왼쪽으로 밀어놓았다.

Slide될 핑크색 뷰를 메인뷰에서 안보이게 왼쪽으로 밀어놓고

버튼 클릭시 Slide될 뷰의 NSLayoutConstaint 의 constant값을 더하거나 빼는것 만으로 동작한다.


아래는 구현한 소스코드이다. 주석이 달려있으니 이해하기는 어렵지 않을것이다.


import Foundation

import UIKit


class EasySlideViewController: UIViewController, UIGestureRecognizerDelegate {

    

    // uianimation duration

    let duration = 0.5

    // slide show/hide status

    var showhideState: Bool = false

    // slide leading default value

    var slideLeadingValue: CGFloat = 0

    // showhideButton position: true:left false:right -> default is false(right)

    var showhideButtonPosition: Bool = false


    // autolayout leading state for programmitically

    @IBOutlet weak var leadingState: NSLayoutConstraint!

    // showhide button leading state for programmitically

    @IBOutlet weak var showhideButtonState: NSLayoutConstraint!

    // mode button leading state for programmitically

    @IBOutlet weak var modeButtonState: NSLayoutConstraint!

    // onoff switch leading state for programmitically

    @IBOutlet weak var onoffState: NSLayoutConstraint!

    

    // container view(menu)

    @IBOutlet weak var EasyView: UIView!

    // slide main view

    @IBOutlet weak var mainView: UIView!

    // show/hide button

    @IBOutlet weak var ShowHideButton: UIButton!

    // mode change button

    @IBOutlet weak var ModeButton: UIButton!

    // view animation effect on/off switch

    @IBOutlet weak var onoffSwitch: UISwitch!

    

    override func viewDidAppear(animated: Bool) {

        super.viewDidAppear(animated)

        

        self.setLeadingStateConstantValue()

    }

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        let tapGetsture = UITapGestureRecognizer(target: self, action: #selector(EasySlideViewController.tapHideview(_:)))

        tapGetsture.delegate = self

        self.mainView.userInteractionEnabled = true

        self.mainView.addGestureRecognizer(tapGetsture)

        

        // 화면 위의 버튼 기타 포지션 설정.

        guard self.showhideButtonPosition else {

            self.initPosition()

            return

        }


    }

    

    func tapHideview(gesture: UITapGestureRecognizer) {

        if self.showhideState {

            // hiding slide view

            if onoffSwitch.on {

                self.hideViewEffect()

            } else {

                self.hideView()

            }

            self.showhideState = !self.showhideState

        }

    }

    

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

    }

    

    // show/hide button action

    @IBAction func ActionShowHide(sender: AnyObject) {

        if self.showhideState {

            // hiding slide view

            if onoffSwitch.on {

                self.hideViewEffect()

            } else {

                self.hideView()

            }

        } else {

            // showing slide view

            if onoffSwitch.on {

                self.showViewEffect()

            } else {

                self.showView()

            }

        }

        

        self.showhideState = !self.showhideState

    }

    

    override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {

        self.setLeadingStateConstantValue()

    }

    

    func setLeadingStateConstantValue() {

        // 오토레이아웃으로 변경된 EasyView width값으로 slideWidth값을 설정.

        self.slideLeadingValue = self.EasyView.frame.width

        // default slide leading value 화면에서 안보이게 - 값으로 설정.

        self.leadingState.constant = -slideLeadingValue

    }

    

    @IBAction func ActionMode(sender: AnyObject) {

        self.showhideButtonPosition = !self.showhideButtonPosition

        self.initPosition()

    }


    func initPosition() {

        // main view position init

        if self.showhideState {

            var viewRect: CGRect?

            viewRect = self.mainView!.frame

            viewRect?.origin.x = 0

            self.mainView.frame = viewRect!

            self.mainView.layoutIfNeeded()

            

            self.leadingState.constant -= self.slideLeadingValue

            self.showhideState = !self.showhideState

            self.view.layoutIfNeeded()

        }

        

        // button positon init

        self.showhideButtonState.constant = (self.view.frame.width - self.showhideButtonState.constant) - self.ShowHideButton.frame.size.width

        self.modeButtonState.constant = (self.view.frame.width - self.modeButtonState.constant) - self.ModeButton.frame.size.width

        self.onoffState.constant = (self.view.frame.width - self.onoffState.constant) - self.onoffSwitch.frame.size.width

    }

    

    func showView() {

        UIView.animateWithDuration(duration, animations: {

            self.leadingState.constant += self.slideLeadingValue

            self.view.layoutIfNeeded()

            

            if self.showhideButtonPosition {

                var fMainRect:CGRect = self.mainView.frame

                fMainRect.origin.x += self.slideLeadingValue

                self.mainView.frame = fMainRect

                self.mainView.layoutIfNeeded()

            }

        })

    }

    

    func hideView() {

        UIView.animateWithDuration(duration, animations: {

            if self.showhideButtonPosition {

                var fMainRect:CGRect = self.mainView.frame

                fMainRect.origin.x -= self.slideLeadingValue

                self.mainView.frame = fMainRect

                self.mainView.layoutIfNeeded()

            }

            

            self.leadingState.constant -= self.slideLeadingValue

            self.view.layoutIfNeeded()

        })

    }

    

    func showViewEffect() {

        UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0.1, options: [], animations: {

            self.leadingState.constant += self.slideLeadingValue

            self.view.layoutIfNeeded()

            

            if self.showhideButtonPosition {

                var fMainRect:CGRect = self.mainView.frame

                fMainRect.origin.x += self.slideLeadingValue

                self.mainView.frame = fMainRect

                self.mainView.layoutIfNeeded()

            }

            

            }, completion: { finished in

                print("show complete!!!")

        })

    }

    

    func hideViewEffect() {

        UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.1, initialSpringVelocity: 0.1, options: [], animations: {

            if self.showhideButtonPosition {

                var fMainRect:CGRect = self.mainView.frame

                fMainRect.origin.x -= self.slideLeadingValue

                self.mainView.frame = fMainRect

                self.mainView.layoutIfNeeded()

            }

            

            self.leadingState.constant -= self.slideLeadingValue

            self.view.layoutIfNeeded()

            

            }, completion: { finished in

                print("hide complete!!!")

        })

    }

    

}