|
| 1 | +Attempts to control the height of modal controllers have been bothering developers for 4 years. [The libraries turn out to be bad](https://github.com/ivanvorobei/SPStorkController). They work ugly or don't work at all. The lead engineer of `UIKit` was thrown out of the window for trying to discuss this topic at the meeting. By iOS 15 Tim Cook took pity and discovered secret knowledge. |
| 2 | + |
| 3 | +[UISheetPresentationController Preview](https://cdn.ivanvorobei.by/websites/sparrowcode.io/uisheetpresentationcontroller/uisheetpresentationcontroller.mov) |
| 4 | + |
| 5 | +That looks cool and there are a lot of use cases. To show the default `sheet` controller use the code below: |
| 6 | + |
| 7 | +```swift |
| 8 | +let controller = UIViewController() |
| 9 | +if let sheetController = controller.sheetPresentationController { |
| 10 | + sheetController.detents = [.medium(), .large()] |
| 11 | +} |
| 12 | +present(controller, animated: true) |
| 13 | +``` |
| 14 | + |
| 15 | +That's a modal controller that has been added to advanced behavior. You can wrap it into a navigation controller add a header and buttons. Wrap the code with `sheetController` to `if #available(iOS 15.0, *) {}` if the project supports previous versions of iOS. |
| 16 | + |
| 17 | +## Detents |
| 18 | + |
| 19 | +The detent is the height to which the controller reaches. Just like in scroll paging or when the electron is not at its energy level. |
| 20 | + |
| 21 | +Two detents are available: `.medium()` with a size of about half the screen and `.large()`, which replicates a large modal controller. If you leave only `.medium()` detents, the controller opens at half the screen and won't go any higher. It's not possible to set its height. |
| 22 | + |
| 23 | +## Switching between detents |
| 24 | + |
| 25 | +To switch from one detent to another use the code below: |
| 26 | + |
| 27 | +```swift |
| 28 | +sheetController.animateChanges { |
| 29 | + sheetController.selectedDetentIdentifier = .medium |
| 30 | +} |
| 31 | +``` |
| 32 | + |
| 33 | +You can use it without the animation. |
| 34 | + |
| 35 | +## Landscape orientation |
| 36 | + |
| 37 | +By default, the `sheet` controller in landscape orientation looks like a usual controller. The thing is that `.medium()` detent is not available and `.large()` is the default mode of the modal controller. Also, you can add indentation around the edges. |
| 38 | + |
| 39 | +```swift |
| 40 | +sheetController.prefersEdgeAttachedInCompactHeight = true |
| 41 | +``` |
| 42 | + |
| 43 | +Here's how it looks: |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | +Set `.widthFollowsPreferredContentSizeWhenEdgeAttached` to `true` to let the controller consider the preferred size. |
| 48 | + |
| 49 | +## Indicator |
| 50 | + |
| 51 | +If you wanna add an indicator on top of the controller, set `.prefersGrabberVisible` to `true`. By default, the indicator is hidden. The indicator does not affect the safe area and layout margins, at least at the time of this article. |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +## Dimmed background |
| 56 | + |
| 57 | +Specify the largest detent that does not need to be dimmed. Anything larger than this detent will be dimmed. The code below: |
| 58 | + |
| 59 | +```swift |
| 60 | +sheetController.largestUndimmedDetentIdentifier = .medium |
| 61 | +``` |
| 62 | + |
| 63 | +It says that the `.medium' will not dim, but anything larger will. You can remove the dimming for the largest detent. |
| 64 | + |
| 65 | +## Corner Radius |
| 66 | + |
| 67 | +You can control the corner radius of the controller. To do this, set `.preferredCornerRadius`. Note that the rounding changes not only for the presented controller but also for the parent. |
| 68 | + |
| 69 | + |
| 70 | + |
| 71 | +On the screenshot, I set the corner radius to `22`. The radius is set for `.medium`. That's all. [Comment on the post](https://t.me/sparrowcode/71), if you will use sheet controllers in your projects. |
0 commit comments