Skip to content

Latest commit

 

History

History
132 lines (103 loc) · 10.1 KB

README.md

File metadata and controls

132 lines (103 loc) · 10.1 KB

Tests codebeat badge

SplitViewKit

Easily config multi-column apps (iPad and macOS)

img

Table of Contents

  1. Problem
  2. Solution
  3. Example Usage
  4. Installation
  5. Gotchas
  6. References
  7. Resources
  8. Todo
  9. Future Improvements

Problem:

  1. NavigationSplitView Is fairly easy to setup. But has many edge cases to account for. Adding this complxity in the app scope makes the code uneccecaraly complex.
  2. Managing column-widths for different modes is challanging. Unless you use navigationSplitViewStyle: .automatic which solves it but is poorly implemented from a usability POV
  3. Customizing the navigation-bar in different modes is complex
  4. MacOS and iPad has slighly different nuances of how SplitView works.

Solution:

  1. Move the complexity that comes with implementing splitview support to this kit. Instead of sprinkling split-view code all over your app. There is an Example-project included in this package, that makes it easier to understand how to work with NavigationSplitView
  2. The kit supports providing your own column-width calculations. Letting you set your own "responsive breakpoints"
  3. The kit supports providing your own "navigation-UI" for the different modes, by reacting to sizeClass, orientation and winSize changes. Adding UI above the splitview is also supported.
  4. The kit handles the different ways SplitView works for iPad and macOS. Side effects are documented etc.

Example:

  • To use SplitViewContainer, you need to provide three SwiftUI views: SideBar, Content, and Detail. These views represent the left side menu-bar, the center main content, and the right side detail-view.
  • You can control the column visibility and preferred compact column through the columnVisibility and preferredCompactColumn properties in the SplitConfig struct.
  • There is also a comprehensive example project included in this package. See the xcode project for more details.
import SwiftUI
import SplitViewKit

struct ContentView: View {
    var body: some View {
        // Interact and react to splitview via splitConfig and sizeClass parameters
        SplitViewWrapper(
            sideBar: { splitConfig, sizeClass in Color.red }, // Set your sidebar content here
            content: { splitConfig, sizeClass in Color.green }, // Set your center content here
            detail: { splitConfig, sizeClass in Color.blue }, // Set your detail content here
            debug: { _, _ in nil } // Add debug-view here, or use it for floating UI above the view
            columnWidth: DefaultColumnWidth(), // Set custom column widths here
            splitConfig: SplitConfig() // set initial column arrangment here
        )
    }
}

Installation

Add this to xcode or your SPM package file:

.package(url: "https://github.com/sentryco/SplitViewKit", branch: "main")

Gotchas:

  • In NavigationSplitView, when in Portrait-mode it can either occupy 40% of 60% of the screen ("Slide-over-mode" on iPad is the same as 30% split-view)
  • In Landscape it can occupy 30%, 50%, and 70% of the screen
  • There are some bugs in NavigationSplitView https://forums.developer.apple.com/forums/thread/708721
  • Using NavigationSplitView is highly recommended over building your own SplitView with HStack etc. As a lot of features come toll free with NavigationSplitView

References

Here are some general tutorials and articles on how to use NavigationSplitView that was useful to read while building this framework.

Resources:

These are some of the resources that was founds when solving edge cases for the NavigationSplitView

macOS:

img

Todo:

  • Use darker transperancy background for sidebar for macOS
  • Add some sort of minHeight for detail column on macOS
  • Remove unit-test
  • Add UI-tests
  • Constrain code doc comments to 80char max etc
  • Reference local relative path in example project, instead of remote path
  • Using a propertywrapper might be better for making variables reactive to views

Future improvements:

  • Consider adding better support for 2-coulmn working right out of the box. Or add notes on how to do it (combining 2Column mode with prominentDetail)
  • Consider experimenting with overflow working in detail column (maybe not, better to contain content)
  • Consider adding buttons that toggle different split-view modes? (explore how this should look first etc)
  • Consider improving the datamodel in the example project. Make it simpler
  • Consider looking into using TupleView ? Research how it works etc. And how it might fit in here?
  • Consider adding an option for 70% landscape mode could be to not use .all, and use .double instead
  • Consider adding basic implementation on how to retain column-widths with user-default for macOS
  • Consider adding sidebar / main / detail column widths to debug container
  • Consider looking into how to avoid subduing the colors in compact mode (maybe because of hybrid color?, try pure black etc?) (surface level research on this came up empty)
  • Consider checking that lightmode works well in the example project
  • Consider adding info around how to remove the ability to create multiple windows of the same app on iPad. Write a note about it in the readme (might be out of scope)
  • Consider making selections in the lists not show in compact mode. In the example project.
  • Consider moving some debug tools from the SplitViewKit to the example project
  • Consider improving the model data in the example project. See https://www.kiloloco.com/articles/019-swiftui-macos-navigation-basics/ and https://medium.com/@jpmtech/swiftui-navigationsplitview-30ce87b5de03
  • Consider rebuilding NavigationSplitView with HStack. It might be a better solution and might not be very complicated to do. Rather then trying to wrap NavigationSplitView to fix NavigationSplitView shortcomings. The current wrapper works. But complexity cost is more than it should be. A HStack based solution that mimicks NavigationSplitView could reduce complexity and serve the same purpose. The implimentation would recuire a NavigationStack in compact mode. And HStack with 3 columns in regular mode. A drag implementation would be needed to account for draggable sidebar and main column. Also from swip in from left functionality would have to be implemented. Which is probably the most complicated part. They would also have to work for mac and ipad. However there is probably similar kits out there that we could extract solutions from.