Floating Button

이세진·2022년 6월 24일
0

iOS

목록 보기
10/46

생성일: 2021년 10월 10일 오후 9:32

화면 구성 상황

왼쪽 뷰컨의 버튼을 클릭하면 오른쪽 뷰컨처럼 작은 버튼 3개가 생기게 만드는 것이 목표이다.

버튼을 눌렀을때 우측의 VC로 이동하도록 Segue를 설정한다.

이동한 VC의 배경사진을 투명하게 만들기 위해 상위 View의 배경색을 Default로 바꾼다.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "showPopup"{
            let floatingVC = segue.destination as! FloatingButtonListViewController
            
            //배경을 투명하게 하기
            floatingVC.modalPresentationStyle = .overCurrentContext
        }
    }
}

prepare를 이용하여 Segue를 할 때 배경을 투명하게 만들어서 기존의 배경사진이 그대로 보이게 한다.

Visual Effect View with Blur를 넣어서 전체적으로 흐리게 만들 수 있다. (버튼보다 뒤에 위치시켜야 버튼까지 흐려지는 것을 막을 수 있다.)

현재까지 실행 화면

버튼이 올라가는 애니메이션

오브젝트 자체 뿐만 아니라 오브젝트의 Constraints 또한 IBOutlet으로 ViewController와 연결 시킬 수 있다.

@IBOutlet weak var btn1CenterY: NSLayoutConstraint!
@IBOutlet weak var btn2CenterY: NSLayoutConstraint!
@IBOutlet weak var btn3CenterY: NSLayoutConstraint!
import UIKit

class FloatingButtonListViewController: UIViewController {

    @IBOutlet weak var btn1CenterY: NSLayoutConstraint!
    @IBOutlet weak var btn2CenterY: NSLayoutConstraint!
    @IBOutlet weak var btn3CenterY: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        btn1CenterY.constant = 0
        btn2CenterY.constant = 0
        btn3CenterY.constant = 0
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        UIView.animate(withDuration: 0.5) {
            
            self.btn1CenterY.constant = 80
            self.btn2CenterY.constant = 160
            self.btn3CenterY.constant = 240
            
            self.view.layoutIfNeeded()  //이걸 꼭 써줘야 갱신이 됨.
        }
    }
    
}

처음 constraint의 constant 값을 전부 0으로 주고 viewDidAppear에서 constant값을 늘려서 애니메이션 효과를 주도록 했다.

UIView.animate를 이용하여 0.5초 동안 움직일 코드를 작성했다.

여기서 중요한 점은 self.view.layoutIfNeeded()를 해주어야 원하는대로 애니메이션이 작동한다는 점이다.

그냥 UIView.animate가 아닌 damping을 사용하면 흔들리는 애니메이션을 줄 수 있다.

UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0.5, options: .curveEaseOut) {
    
            self.btn1CenterY.constant = 80
            self.btn2CenterY.constant = 160
            self.btn3CenterY.constant = 240
            
            self.view.layoutIfNeeded()  //이걸 꼭 써줘야 갱신이 됨.
        } completion: { completion in
            //애니메이션이 끝나는 시점에서 실행
        }

damping이라고 치면 자동 완성으로 해당 함수를 불러올 수 있다. Damping값을 0에 가깝게 줄수록 바운스 되는 정도가 커진다.

버튼 재클릭 상황 및 되돌아가기

버튼을 다시 클릭할 때에는 펼쳐진 작은 버튼 3개를 다시 자연스럽게 접고 원래의 뷰컨트롤러로 돌아가야한다.

@IBAction func dismissFloating(_ sender: UIButton) {
        
        UIView.animate(withDuration: 0.7, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.5, options: .curveEaseOut) {
    
            self.btn1CenterY.constant = 0
            self.btn2CenterY.constant = 0
            self.btn3CenterY.constant = 0
            
            self.view.layoutIfNeeded()  //이걸 꼭 써줘야 갱신이 됨.
        } completion: { completion in
            //애니메이션이 끝나는 시점에서 실행
            
            self.dismiss(animated: false, completion: nil)
        }
    }

큰 버튼을 IBAction으로 연결하고 또 한번 animate를 이용해 펼쳐진 3개의 버튼을 접는다. 3 버튼의 Constraints constant값을 0으로 바꾸고 해당 애니메이션이 끝나는 시점에서 self.dismiss를 시켜서 원래의 ViewController로 돌아가게 구현했다.

최종 결과

profile
나중은 결코 오지 않는다.

0개의 댓글