본문 바로가기
iOS/WWDC

[WWDC] SheetPresentationController 만들기

by Odin_1204 2022. 7. 27.
이런 Sheet!! 너무 Sheep잖아~?! 😄

 

 

 

안녕하세요. 오딘(Odin)입니다.

 

 

여러분 혹시 SheetPresentationViewController라고 아시나요??

 

SheetPresentationController는 iOS15.0+ 부터 사용 가능한 ViewController 입니다.

쉽게 설명하자면 Alert의 .sheet 형태의 확장판 이라고 생각하시면 될거 같네요!

 

생각보다 만들기 너무너무 쉽더라구요!! 

그러면 우리 다같이 한번 만들어 볼까요?!?

 

 

 

 


1. SheetViewController 띄우기

 

 

    func showSheetViewController() {
        let vc = SheetViewController() // 전환하고 싶은 화면의 ViewController 이름!
        if let sheet = vc.sheetPresentationController {
            /// 보여지는 sheetView를 중간 or 전체, 아니면 두개 방식 모두 가능하게 할거냐
            sheet.detents = [.medium(), .large()]
        }
        self.present(vc, animated: true)
    }

 

평소에 화면 전환 하는 방식처럼  ViewController 의 인스턴스 변수를 반들고
sheet의 띄우고 싶은 방식을 설정한 뒤 .sheetPrsenetationController 로 띄워주기만 하면 끝!!!! 😃
정말 쉽지 않나요?!?

 

그러면 이번에는 TableView가 포함 되어 있는 화면을 띄워봅시다!

 

 

 

 

 

2. TableView가 포함된 SheetViewController 띄우기

자!! 위와 동일한 방식으로 SheetViewController에 TableView를 넣고 띄워볼게요!!

 

 

⛔️ 앗?!  이게 무슨일이죠?!

Sheet가 medium에 있을 때 Tableview가 scroll이 되지가 않네요...!!

왜 그럴까요?

 

prefersScrollingExpandsWhenScrolledToEdge로 인해 다음과 같은 현상이 발생합니다.


★ prefersScrollingExpandsWhenScrolledToEdge 란?

- "sheet" present시 사용 가능한 Scroll을  "SheetViewController" 내부 Scroll 멈춤쇠 역할을 할 수 있는 용도로 확장할 것이냐?!? 

그러나 해당 변수의 Defualt 값이 "True" 이므로
Scroll이 확장 되어 SheetViewController 내부의 Scroll이 안먹히게 되는 것입니다!

 

그러면 이제 해결해 볼까요??

 

 

 

 

prefersScrollingExpandsWhenScrolledToEdge 의 값을 false 로 변경해주면~!

 

sheet.prefersScrollingExpandsWhenScrolledToEdge = false // Default: True

 

 

 

 

짜잔 ~!! 🎉


SheetViewController의 내부 Scroll이 가능해졌어요~!!

이번에는 조금 더 다양한 기능을 추가해볼게요~!

 

 

 

 

 

3. Dimmed 화면 제거

sheetViewController를 띄우게 되면 HomeViewController 화면이 Dimmed 처리가 되어있는데 

/// "sheetViewController" 밑 화면이 흐리게 띄우지 않고 싶을 때
sheet.largestUndimmedDetentIdentifier = .medium  // Defualt: nill

 

해당 코드를 사용해서 제거 해볼까요??

 

 

다음 화면처럼 Dimmed가 제거 되면 빨간 네모 박스 안에 있는 화면을 눌러도 sheet가 사라지지 않지만
"HomeViewController"의 Tap 기능이 적용 가능해집니다.

그렇다면 다양한 Custom이 가능해지겠죠?!?ㅎㅎ

 

 이번에는 간단한 Custom을 한번 해볼까요??

 

 

 

 

 

4. delegate를 통한 전 화면에 Data 전달

SheetViewController내부의 Cell 에 해당 Data를 HomeViewController에 전달해봅시다.

 

HomeViewController

// Data 전달을 위한 프로토콜 생성
protocol SendDataDelegate {
    func reciveData(response: Int) -> Void
}

// HomeViewController
class HomeViewController: UIViewController {
...	
    func reciveData(response: Int) {
        mainLabel.text = "Cell\(response) 눌림"
    }
...
}

-> 화면 전환시 vc.delegate = self 는 당연히 해줘야 되는거 알고 계시죠??ㅎㅎ

 

SheetViewController

class SheetViewController: UIViewController, ... {

    var delegate: SendDataDelegate?
...
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        delegate?.reciveData(response: indexPath.row)
    }
...
}

 

 

SheetViewController에서 변경된 사항들이 HomeViewController에서 바로바로 볼 수 있으니

이제 다양한 커스텀도 가능하겠죠~?!ㅎㅎ

 

 

 

 

 

5. 그 외 다양한 Method 

"Navigation 화면" - "Grabber 생성" - "가로 화면시 sheet 방식"

 

다양한 기능을 밑 "전체코드"에 정리해두었으니 보시고 적용하시면 된답니다~

 

 

 

 


 

 

 

 

 

오늘은 SheetViewController에 대해서 자세히 다루어 보았는데요!!
정말 다루기 쉽지 않나요?! ㅎㅎ
여러분들도 한번 적용해보셨으면 좋겠습니다~

 

그럼 안녕~!! 😁

 

 

 

 

 


전체코드

   func showSheetViewController() {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: SheetViewController.identifier) as! SheetViewController
           
        vc.delegate = self
        
        let nvc = UINavigationController(rootViewController: vc)
        nvc.modalPresentationStyle = .pageSheet
        
        /// 보여지는 sheetView를 중간 or 전체 , 아니면 중간 and 전체 다  보이게 할거냐~
        if let sheet = nvc.sheetPresentationController {
            sheet.detents = [.medium(), .large()]
           
            /// "sheet" present시 사용 가능한 Scroll을  "SheetViewController" 내부 Scroll 멈춤쇠 역할을 할 수 있는  용도로  확장할 것이냐?!?
            sheet.prefersScrollingExpandsWhenScrolledToEdge = false
            
            /// 가로 화면 일 때 전체 화면 대신 Scroll 가능한 형태의 sheet로 뜨도록 설정!
            sheet.prefersEdgeAttachedInCompactHeight = true
            
            /// 처음 "sheetViewController"를 띄울 때 큰 화면으로 띄우고 싶다면!
            sheet.selectedDetentIdentifier = .large
            
            /// "sheetViewController" 밑 화면이 흐리게 띄우지 않고 싶을 때
            sheet.largestUndimmedDetentIdentifier = .medium
            
            /// 상단 -- 부여 잡는 부분 보이게 할것인지!
            sheet.prefersGrabberVisible = true
            
            /// sheet 의 cornerRadius 주기!
            sheet.preferredCornerRadius = 30
        }
        
        /// 화면 띄우기!
        self.present(nvc, animated: true)
    }

 

 

 

 

 

~~~~~~~~~ 참조 ~~~~~~~~~

 

https://developer.apple.com/videos/play/wwdc2021/10063/

https://developer.apple.com/documentation/uikit/uisheetpresentationcontroller

'iOS > WWDC' 카테고리의 다른 글

[WWDC] CollectionView의 변천사 (iOS +14까지) - Diffable DataSource  (1) 2022.10.22