Date: 2024/09/24.
Author: Takaya Shirai
Project Name: Twitter-Clone
# Enabling SideMenu Display with Custom Modal Animation
## Overview
We currently utilize `AppRootViewController` to display `SideMenuView` by linking it with `MainRootViewController`. We've explored an alternative approach to display the `SideMenuView` by introducing the [DrawererPresentation](https://github.com/noppefoxwolf/DrawerPresentation) package. Comparing these two approaches in several aspects, such as the view hierarchy or clean code, we propose using the package to improve the view hierarchy and the code simplicity of our Twitter-Clone project.
## Context
We aim to compare the current implementation that uses four UIViewController to show the `SideMenuView`, and the proposed implementation that uses the third-party package "DrawerPresentaion" to improve this project.
## Goals
Our goals for this design are:
- **Simplified View Hierarchy**: Reduce the complexity of the view hierarchy and facilitate easier understanding for developers of this project.
- **Cleaner Code**: Make the existing code simpler and enhance the readability and maintainability of this project.
## Current Approach
### View Hierarchy
The current approach relies on `ScrollView` to display the `SideMenuView`. Users can access the `SideMenuView` by swiping or tapping the `profileIconButton` in the `HomeViewController`, which changes the horizontal position of the `ScrollView`. When the `SideMenuView` is visible, an `overlayView` dims the `MainRootViewController`.


### ViewController Responsibilities
- `AppRootViewController` (UIViewController): Manages `ScrollView` and its position.
- `SideMenuViewController` (UIViewController): Manages the state of `SideMenuView`.
- `MainRootViewController` (UITabBarController): Manages the navigations and shows the corresponding view based on the current tab selected by a user (e.g., `HomeViewController`).
- `HomeViewController` (UIViewController): Manages the state of `HomeView`(the home view of Twitter).
### Pros
- **No Third-Party Dependency**: As this approach is written from scratch in this project, we have full control over the code, allowing us to modify it freely to fit our needs.
### Cons
- **Complicated View Hierarchy**: The view hierarchy involves multiple controllers and extra views, making it harder to understand and maintain.
- **Additional Code Required**: In the current code, we haven't implemented the view overlay functionality when the `SideMenuView` is shown via a swipe gesture. This will need to be implemented with additional code in the future.
## Proposed Approach
### View Hierarchy
The proposed approach uses the "DrawerPresentation" package, which provides a custom modal animation created with [UIViewControllerAnimatedTransitioning](https://developer.apple.com/documentation/uikit/uiviewcontrolleranimatedtransitioning) protocol to present the `SideMenuView`. This package allows us to recognize the user's pan gesture and swipe gesture, and enable the display of the side menu based on those gestures. The container view contains the views involved in the transition(animation) and it is part of the [UIViewControllerContextTransitioning](https://developer.apple.com/documentation/uikit/uiviewcontrollercontexttransitioning) protocol object.


### ViewController Responsibilities
- `AppRootViewController`(UITabBarController): Manages the navigations and shows the corresponding view based on the current tab selected by a user (e.g., HomeViewController).
- `SideMenuViewController`(UIHostingController): Manages the state of `SideMenuView`.
- `HomeViewController`(UIViewController): Manages the state of `HomeView`, recognizes user gestures (pan/swipe), and presents the `SideMenuView`.
### Pros
- **Simplified View Hierarchy**: This approach can simplify the view hierarchy by eliminating extra views such as `ScrollView` or `StackView`.
- **Cleaner Code**: We can implement the side menu functionality in a simple way and it is also easy to make a side menu in other views. The code below is needed to add the side menu functionality to other views and its amount is really small.
```
let drawerTransitionController = DrawerTransitionController()
// add interactive gesture and register drawer
drawerTransitionController.addDrawerGesture(to: self, drawerViewController: {
UIHostingController(rootView: Text("Interactive side menu"))
})
// present registered drawer manually
drawerTransitionController.presentRegisteredDrawer()
```
> https://github.com/noppefoxwolf/DrawerPresentation
### Cons
- **Dependence on Third Party**: The package introduces a third-party dependency, which may not be fully adaptable to future iOS updates or custom transition needs.
## Comparison
We compare these two approaches based on our goals for this design.
### View Hierarchy
The current approach involves four view controllers and extra views such as `ScrollView` or `StackView`, which increase the complexity of the view hierarchy. In contrast, the proposed approach gives us a simpler view hierarchy than the current approach.
### Code Simplicity
While the suggested approach depends on the third party's package, it reduces the amount of code needed, making it easier for developers to read and understand the code functionality.
## Conclusion
We propose adopting the DrawerPresentation package. Despite the introduction of a third-party dependency, it provides a significant improvement in terms of both the view hierarchy and code simplicity, matching well with our goals of creating a simplified view hierarchy and a clear code.
## References
DrawerPresentation package: https://github.com/noppefoxwolf/DrawerPresentation
UIViewControllerAnimatedTransitioning document: https://developer.apple.com/documentation/uikit/uiviewcontrolleranimatedtransitioning
UIViewControllerContextTransitioning document: https://developer.apple.com/documentation/uikit/uiviewcontrollercontexttransitioning