Bottom Sheet์œผ๋กœ ๋ชจ๋‹ฌ๋ทฐ ๊ตฌํ˜„ํ•˜๊ธฐ(Github - Swipeable View ์‘์šฉ)

2021. 8. 23. 22:42ใ†iOS/View

์ฝ”๋”์Šคํ•˜์ด ๋ฉ˜ํ† ๋ง์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋˜ Bottom Sheet ๊ตฌํ˜„์„ ๊ธฐ๋ก์œผ๋กœ ๋‚จ๊ฒจ๋‘ก๋‹ˆ๋‹ค.

 

์ด๊ฑธ ์ •ํ™•ํžˆ Bottom Sheet์ด๋ผ๊ณ  ๋ถ€๋ฅด๋Š”์ง€, ๋ชจ๋‹ฌ์ด๋ผ๊ณ  ๋ถˆ๋Ÿฌ์•ผํ• ์ง€ ์กฐ๊ธˆ ์• ๋งคํ•œ ๋ถ€๋ถ„์ด ์žˆ์ง€๋งŒ,

์ด ํฌ์ŠคํŠธ์—์„œ ๊ถ๊ทน์ ์œผ๋กœ ๋ณด์—ฌ๋“œ๋ฆฌ๋ ค๊ณ  ํ•˜๋Š”๊ฑด ์ด๋Ÿฐ ๋ถ€๋ถ„์ž…๋‹ˆ๋‹ค.

 

๊ธฐ์กด ๋ทฐ์— ์žˆ๋Š” ๋ฒ„ํŠผ์ด๋‚˜ ์ด๋ฏธ์ง€๊ฐ€ ํ•˜๋‹จ์˜ ๋ทฐ์™€ ํ•จ๊ป˜ ์›€์ง์ž„

 

 

์šฐ์„  ์ œ๊ฐ€ ์ฐธ๊ณ ํ•œ ํ”„๋กœ์ ํŠธ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

https://github.com/LucaIaco/SwipeableView

 

GitHub - LucaIaco/SwipeableView: A simple and easy to use view component for iOS written in Swift which allows to be expanded an

A simple and easy to use view component for iOS written in Swift which allows to be expanded and collapsed with user gestures relying on autolayouts, and supports interpolation of items which can b...

github.com

 

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋ฅผ Stack Overflow์—์„œ ๋ฐœ๊ฒฌํ•˜๊ณ  ์ง์ ‘ ๋‹ค์šด๋ฐ›์•„์„œ ์‹คํ–‰์‹œ์ผœ๋ณด๊ณ  ์ฝ”๋“œ๋ฅผ ์ด๋ž˜์ €๋ž˜ ๋‘˜๋Ÿฌ๋ณด๋‹ˆ,

๊ถ๊ทน์ ์œผ๋กœ '์ƒˆ๋กœ์šด ํ”„๋กœํ† ์ฝœ'์„ ๋งŒ๋“ค์–ด ๋‘์…จ๋”๋ผ๊ณ ์š”.

 

ํ”„๋กœํ† ์ฝœ SwipeableView์™€ SwipeableItem

 

ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ ํŒŒ์ผ์„ ๋ฐ›์•„์˜ค์…”์„œ ๋ฐ”๋กœ ํ•ด์„ํ•˜๋ฉด์„œ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋Šฅ๋ ฅ์ด ๋˜์‹ ๋‹ค๋ฉด ๊ทธ๋ ‡๊ฒŒ ํ•˜์‹œ๋ฉด ๋˜๊ฒ ์ง€๋งŒ...

์กฐ๊ธˆ ์–ด๋ ค์šฐ์‹œ๋‹ค๋ฉด ์ฒจ๋ถ€ํ•œ ๋งํฌ์˜ ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์šด ๋ฐ›์œผ์‹œ๊ณ 

์ง์ ‘ ์ฝ”๋“œ์— ๋ธŒ๋ ˆ์ดํฌ ํฌ์ธํŠธ๋ฅผ ๊ฑธ์–ด๋ณด๋ฉด์„œ ์‹œ๋ฎฌ๋ ˆ์ดํ„ฐ๋กœ ์ด๋ž˜์ €๋ž˜ ๋งŒ์ ธ๋ณด๊ณ 

์–ด๋–ค ์ƒํ™ฉ์— ์–ด๋–ค ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์ด ์–ด๋–ป๊ฒŒ ์ž‘๋™ํ•˜๋Š”์ง€ ์ง์ ‘ ๋ˆˆ์œผ๋กœ ํ™•์ธํ•˜์‹œ๋Š”๊ฒŒ

ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ์ฐพ์•„์™€ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. 

 

๊ทธ๋Ÿผ ์ด์ œ ์ง์ ‘ ๊ตฌํ˜„ํ•œ ๊ณผ์ •๊ณผ ์ฝ”๋“œ๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜ ์ œ๊ฐ€ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ์€, 'map picker'๋ผ๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ์•„๋ž˜์—์„œ ๋ชจ๋‹ฌ์ด ์˜ฌ๋ผ์˜ค๊ณ 

๊ทธ ๋ชจ๋‹ฌ์„ ์œ„ ์•„๋ž˜๋กœ ํฌ๊ธฐ๋ฅผ ๋Š˜๋ฆฌ๊ฑฐ๋‚˜ ์ค„์ผ ์ˆ˜ ์žˆ๊ณ ,

๊ทธ ๋ชจ๋‹ฌ์ด ์›€์ง์ผ๋•Œ 'map picker'๋ฒ„ํŠผ ๋˜ํ•œ ๊ฐ„๊ฒฉ์— ๋งž๊ฒŒ ์›€์ง์—ฌ์ฃผ๋Š”๊ฒ๋‹ˆ๋‹ค.

 

0. ํ•ด๋‹น ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์—์„œ ํ”„๋กœ์ ํŠธ ๋‹ค์šด ๋ฐ›์€ ๋’ค

๋‘ ๊ฐœ์˜ ํ”„๋กœํ† ์ฝœ์„ ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ ํŒŒ์ผ์— ํฌํ•จํ•˜๊ธฐ 

 

ํŒŒ์ผ์„ ๋„ฃ์–ด์ค€ ๋’ค์— ํ”„๋กœํ† ์ฝœ์„ ๋ถˆ๋Ÿฌ์™€์ค๋‹ˆ๋‹ค.

 

class ViewController: UIViewController, SwipeableViewProtocol {
    func swipeableViewDidExpand(swipeableView: SwipeableView, previousState: Bool) {
        print(2)
    }
    
    func swipeableViewDidCollapse(swipeableView: SwipeableView, previousState: Bool) {
       print(3)
    }
    
    func swipeableViewDidPan(swipeableView: SwipeableView, percentage: CGFloat) {
        print(1)
    }

 

ํ•จ์ˆ˜ ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด expand ํ–ˆ์„๋•Œ, collapseํ–ˆ์„๋•Œ, pan ๋˜์—ˆ์„๋•Œ ๋ถˆ๋Ÿฌ์ง€๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

ํ•ด๋‹น ํ”„๋กœ์ ํŠธ๋ฅผ ์ œ์ž‘ํ•˜์‹  ๋ถ„์€ ํ•ด๋‹น ํ•จ์ˆ˜๋“ค์ด ๋ถˆ๋Ÿฌ์งˆ๋•Œ๋งˆ๋‹ค ์ƒํ˜ธ์ž‘์šฉ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์œผ์…จ๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ ์ €๋Š” ๋”ฑํžˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ฒจ์ค„ ํ•„์š”๋„ ์—†๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์—†์–ด์„œ ๋‹จ์ˆœ print๋ฌธ์œผ๋กœ ๋Œ€์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.

 

 

 

1. Swipe View๋ผ๋Š” ๋ทฐ๋ฅผ ๋ทฐ ์•ˆ์— ๋„ฃ๊ธฐ & constraint ์ •์˜ํ•˜๊ธฐ

 

 

์ € Swipe View์— ๋ชจ๋‹ฌ ๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ• ๊ฑด๋ฐ์š”,

์ € ๋ทฐ๊ฐ€ ์›€์ง์—ฌ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— constraint๊ฐ€ ์ž์œ ์ž์žฌ๋กœ ๋ฐ”๋€Œ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

 

Flex Layout์ด๋ผ๋Š” constraint

 

์—ฌ๊ธฐ์„œ ์ œ๊ฐ€ ์ฒจ๋ถ€ํ•œ ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์—์„œ ์ง์ ‘ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์šด ๋ฐ›๊ณ  ๋งŒ์ ธ๋ณด์‹  ๋ถ„๋“ค์€ ๋ˆˆ์น˜์ฑ˜๊ฒ ์ง€๋งŒ,

ํŠน์ดํ•˜๊ฒŒ๋„ ์ € 'Swipe View'์˜ ์œ„ constraint(Flex Layout)๋ฅผ var๋กœ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

(์ €๋Š” ์ฐธ๊ณ ํ•œ ํ”„๋กœ์ ํŠธ์™€ ๋‹ค๋ฅด๊ฒŒ 'map picker'๋ผ๋Š” ๋ฒ„ํŠผ์„ ๊ธฐ์ค€์œผ๋กœ ์‚ผ์•˜์Šต๋‹ˆ๋‹ค.)

 

 

 

2. Swipe View ์ฝ”๋“œ ์งœ๊ธฐ

 

2-1. ์ฒ˜์Œ ์ƒํƒœ

 

์ €ํฌ๋Š” ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ธฐ ์ „์—๋Š” Swipe View๊ฐ€ ๋ณด์ด์ง€ ์•Š๋Š” ์ƒํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

๊ทธ๊ฑธ ๊ณ ๋ คํ•ด์„œ ViewDidLoad์—์„œ๋Š” ๋ณด์ด์ง€ ์•Š๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

 

 @IBOutlet weak var swipeView: SwipeableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        self.swipeView.isHidden = true
        self.swipeView.isUserInteractionEnabled = false
        self.swipeView.delegate = self
    }

์‹คํ–‰ํ•ด๋ณด๋ฉด ๊ทธ๋ƒฅ ํ‰๋ฒ”ํ•œ ํŒŒ๋ž€์ƒ‰ ๋ทฐ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๋‹น์—ฐํ•ฉ๋‹ˆ๋‹ค! Hidden์„ true๋กœ ์„ค์ •ํ•ด๋‘์—ˆ์œผ๋‹ˆ๊นŒ์š”.

 

 

2-2. ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ(๋ชจ๋‹ฌ๋ทฐ ์„ค์ •)

 

๊ทธ๋Ÿผ ์ด์ œ ๋งŒ์•ฝ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ์„ค์ •ํ•  ๊ฒƒ๋“ค์„ ํ•จ์ˆ˜๋กœ ๋”ฐ๋กœ ๋งŒ๋“ค์–ด ์ค๋‹ˆ๋‹ค.

 

func childViewSettings() {
        self.swipeView.isHidden = false
        self.swipeView.isUserInteractionEnabled = true
        self.swipeView.flexibleLayout = .init(with: self.flexLayout, end: 40.0)
        
        //indicator ์—ฌ๋ถ€
        self.swipeView.isSwipeIndicatorVisible = false
        //๋‘ฅ๊ทผ ๋ชจ์„œ๋ฆฌ ์—ฌ๋ถ€
        self.swipeView.hasRoundedCorners = true
        
        //์ž‘์„๋•Œ๋‚˜ ํด๋•Œ๋‚˜ ๋‘˜ ๋‹ค child View์™€ interaction ๊ฐ€๋Šฅ
        self.swipeView.childViewInteractionOnExpandedOnly = false
    }

 

์—ฌ๊ธฐ์„œ flexibleLayout์ด๋ผ๋Š” ๊ฒŒ ๋ณด์ด์ฃ ?

์ด๊ฑด QuickHelp๋“ฑ์œผ๋กœ ํ™•์ธํ•ด๋ณด๋ฉด Declared In 'SwipeableView.swift'๋ผ๋Š” ์„ค๋ช…์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ฆ‰, ํ”„๋กœ์ ํŠธ ์ž‘์„ฑ์ž ๋ถ„์ด ๋งŒ๋“ค์–ด ๋‘” ํ”„๋กœํ† ์ฝœ์— ํฌํ•จ๋„๋‹ˆ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.

 

 

์ž‘๋™ ๋ฐฉ์‹์„ ๋ณด์•„ํ•˜๋‹ˆ .init(with: (constraint ๋„ฃ์–ด์ฃผ๊ธฐ), end: (์ˆซ์ž))๋„ค์š”.

์ € ์ˆซ์ž๋Š” ์ง์ ‘!! ํ…Œ์ŠคํŠธ ํ•ด๋ณด๋ฉด ๊ธˆ๋ฐฉ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”, constraint ์ ์šฉ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.

 

์ €๋Š” 40์œผ๋กœ ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.(์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณด๊ณ  ๊ฐ€์žฅ ์ ํ•ฉํ•˜๋‹ค๊ณ  ์ƒ๊ฐ๋œ๋Š” ์ˆซ์ž๋ฅผ ๋„ฃ์–ด์ฃผ์„ธ์š”)

constraint๋Š” ์•„๊นŒ ์ €ํฌ๊ฐ€ ์•ž์„œ ๋งŒ๋“ค์–ด์ค€ flexLayout์ด๊ฒ ์ฃ ?

 

 

3. ๋ฒ„ํŠผ ๋ˆŒ๋ €์„ ๋•Œ SwipeView ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•˜๊ธฐ

 

์ด์ œ SwipeView๋ฅผ ๋‚˜ํƒ€๋‚˜๊ฒŒ ํ•˜๊ณ , ํ•ด๋‹น View์•ˆ์— ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€(๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ์€)

๋ทฐ๋ฅผ ์—ฐ๊ฒฐํ•ด์ค„๊ฒ๋‹ˆ๋‹ค.

 

 

์ €๋Š” ์ด๋Ÿฐ์‹์œผ๋กœ ์•„์ฃผ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•ด๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

Storyboard ID๋ฅผ "childVC"๋ผ๊ณ  ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

 

childVC์˜ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ๋Š” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

 

class ChildViewController: UIViewController{

    weak var swipeView:SwipeableView? //์ค‘์š”
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

 

ํ•„์š”ํ•œ ํ…Œ์ด๋ธ”๋ทฐ๋‚˜.. ๋ฒ„ํŠผ์ด ์žˆ์œผ๋ฉด ์ถ”๊ฐ€์ ์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ฃผ๋ฉด ๋˜๊ฒ ์ฃ ?

 

 

๊ทธ๋Ÿผ ์ด์ œ ๋‹ค์‹œ ์›๋ž˜ ๋ทฐ์ปจํŠธ๋กค๋Ÿฌ ์ฝ”๋“œ๋กœ ๋Œ์•„์˜ค๊ฒ ์Šต๋‹ˆ๋‹ค.

map picker๋ผ๋Š” ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ ์‹คํ–‰๋˜๋Š” ํ•จ์ˆ˜์—์„œ childVC๋ฅผ ๋ถˆ๋Ÿฌ์™€์ค„๊ฒ๋‹ˆ๋‹ค.

 

    @IBAction func pickerSelected(_ sender: Any) {
        
        //childViewController์—ฐ๊ฒฐ
        if let childViewController = self.storyboard?.instantiateViewController(withIdentifier:"childVC") as? ChildViewController {
            childViewSettings()
            // alternative way to interact with the swipeable view from within a child view
            childViewController.swipeView = self.swipeView
            // plug the child view into the swipeable view
            self.swipeView.setChildView(childVC: childViewController, parentVC: self)
            
        }
        
    }

 

์ง์ ‘ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๋‹ˆ if๋ฌธ์„ ๊ฑธ์–ด์ฃผ์ง€ ์•Š์œผ๋ฉด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋”๋ผ๊ณ ์š”.

๊ทธ๋ž˜์„œ if๋ฌธ์„ ๊ฑธ๊ณ  childViewController์— ์šฐ๋ฆฌ๊ฐ€ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ "childVC"๋ฅผ ์ €์žฅํ•ด์ค๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  childViewSettings()ํ•จ์ˆ˜(๋ฐ”๋กœ ์œ„์—์„œ ๋งŒ๋“ค์–ด์ค€ ํ•จ์ˆ˜)๋ฅผ ๋ถˆ๋Ÿฌ์™€์ฃผ๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ ๋‘ ์ค„์€ ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์„ ๋งŒ๋“œ์‹  ๋ถ„์˜ ํŠœํ† ๋ฆฌ์–ผ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ”์Šต๋‹ˆ๋‹ค.

(์• ์ดˆ์— ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜๋“ค์ด ์•„๋‹˜! ๊ฐ•์กฐ)

 

 

 

4. map picker ๋ฒ„ํŠผ๋„ ํ•จ๊ป˜ ์›€์ง์ด๊ฒŒ ํ•˜๊ธฐ

 

์œ„ 3๋ฒˆ๊นŒ์ง€ ํ•˜๊ณ  ์‹คํ–‰์„ ํ•ด ๋ณด๋ฉด ์ด์ œ ๋ชจ๋‹ฌ์ด ์ž˜ ์ƒ๊ธธ ๊ฒƒ์ด๊ณ , ์›€์ง์ž„์—๋„ ๋ฌธ์ œ๊ฐ€ ์—†๊ฒ ์ง€๋งŒ

๋ฒ„ํŠผ์ด ํ•จ๊ป˜ ์›€์ง์ด์ง€ ์•Š๋Š”๋‹ค๋Š”๊ฑธ ๋ฐœ๊ฒฌํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค.

๊ทธ๋ž˜์„œ SwipeableItem ํ”„๋กœํ† ์ฝœ์„ ์ด์šฉํ•ด์ค„๊ฒ๋‹ˆ๋‹ค.

 

@IBOutlet weak var pickerFlexLayout: NSLayoutConstraint!
    
@IBOutlet weak var picker: UIButton!

override func viewDidLoad() {
        super.viewDidLoad()
       .
       .
       .
        
        //addAnimateableItem์— layout์„ ๋„ฃ๊ณ  end ๊ฐ’์„ ์กฐ์ •ํ•˜๋ฉด์„œ ์›€์ง์ด๋Š”๊ฑฐ ํ™•์ธ
        self.swipeView.addAnimatableItem(SwipeableItemLayout(with: pickerFlexLayout, end: 100.0))
    }

 

 

์œ„์—์„œ ํ•œ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ constraint๋ฅผ ์ •์˜ํ•ด์ฃผ๊ณ 

ํ”„๋กœํ† ์ฝœ์—์„œ ํ•˜๋ผ๋Š”๋Œ€๋กœ ํ•ด์ฃผ๋ฉด ๋ชจ๋‘ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

๊ธฐ์กด ๋ทฐ์— ์žˆ๋Š” ๋ฒ„ํŠผ์ด๋‚˜ ์ด๋ฏธ์ง€๊ฐ€ ํ•˜๋‹จ์˜ ๋ทฐ์™€ ํ•จ๊ป˜ ์›€์ง์ž„

์ด๋ ‡๊ฒŒ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋ฒ„ํŠผ์ด ํ•จ๊ป˜ ์›€์ง์ด๋Š” ๋ชจ๋‹ฌ๋ทฐ bottom sheet๊ฐ€ ์™„์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!!

์•ž์„œ ๋ง์”€๋“œ๋ ธ์ง€๋งŒ ์ง์ ‘!! ํ•ด๋‹น ๋ ˆํŒŒ์ง€ํ† ๋ฆฌ์—์„œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹ค์šด๋ฐ›์•„ ํ…Œ์ŠคํŠธ ํ•ด๋ณด๊ณ 

์ œ ๋ธ”๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด์„œ ๊ตฌํ˜„ํ•˜์‹œ๋Š” ๊ฑธ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

 

 

(+)

cocoapod์œผ๋กœ ์„ค์น˜ํ•˜๋Š” ๋‹จ์ˆœํ•œ Bottom Sheet๋„ ๊ตฌํ˜„ํ•ด๋ณด์•˜๋Š”๋ฐ,

์˜คํžˆ๋ ค ํ”„๋กœํ† ์ฝœ์„ ์ด์šฉํ•œ ๋ณต์žกํ•œ ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•˜๊ธฐ ์‰ฝ๊ณ  ์ €์—๊ฒ ์ž˜ ๋งž์•˜๋˜ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.