├── LICENSE ├── docs ├── img │ ├── gh.png │ ├── carat.png │ └── dash.png ├── docsets │ ├── SplitView.tgz │ ├── SplitView.xml │ └── SplitView.docset │ │ └── Contents │ │ ├── Resources │ │ ├── docSet.dsidx │ │ └── Documents │ │ │ ├── img │ │ │ ├── gh.png │ │ │ ├── carat.png │ │ │ └── dash.png │ │ │ ├── js │ │ │ └── jazzy.js │ │ │ ├── index.html │ │ │ ├── Enums.html │ │ │ ├── Structs.html │ │ │ ├── css │ │ │ ├── highlight.css │ │ │ └── jazzy.css │ │ │ ├── Classes.html │ │ │ ├── search.json │ │ │ ├── Structs │ │ │ └── SplitViewSnapPoint.html │ │ │ └── Enums │ │ │ └── SplitViewSnapBehavior.html │ │ └── Info.plist ├── undocumented.json ├── badge.svg ├── js │ └── jazzy.js ├── index.html ├── Enums.html ├── Structs.html ├── css │ ├── highlight.css │ └── jazzy.css ├── Classes.html ├── search.json ├── Structs │ └── SplitViewSnapPoint.html ├── Enums │ └── SplitViewSnapBehavior.html └── Classes │ └── SplitViewHandle.html ├── images ├── vertical.png └── horizontal.png ├── app ├── Assets.xcassets │ ├── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── app.entitlements ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── AppDelegate.swift └── ViewController.swift ├── SplitView.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── app.xcscheme │ └── SplitView.xcscheme ├── .github ├── workflows │ ├── swift.yml │ └── create-release.yml └── FUNDING.yml ├── SplitView ├── SplitSupportingView.swift ├── SplitView.h ├── Info.plist ├── SplitViewSnapBehavior.swift ├── SplitViewHandle.swift └── SplitView.swift ├── Package@swift-4.2.swift ├── Package.swift ├── SplitViewTests ├── Info.plist └── splitviewTests.swift ├── SplitView.podspec ├── generate-docs.sh ├── README.md └── .gitignore /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/img/gh.png -------------------------------------------------------------------------------- /docs/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/img/carat.png -------------------------------------------------------------------------------- /docs/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/img/dash.png -------------------------------------------------------------------------------- /images/vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/images/vertical.png -------------------------------------------------------------------------------- /images/horizontal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/images/horizontal.png -------------------------------------------------------------------------------- /docs/docsets/SplitView.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/docsets/SplitView.tgz -------------------------------------------------------------------------------- /app/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /docs/docsets/SplitView.xml: -------------------------------------------------------------------------------- 1 | '2.0.0'https://twodayslate.github.io/SplitView/reference/docsets/SplitView.tgz 2 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/docSet.dsidx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/docsets/SplitView.docset/Contents/Resources/docSet.dsidx -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/img/gh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/docsets/SplitView.docset/Contents/Resources/Documents/img/gh.png -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/img/carat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/docsets/SplitView.docset/Contents/Resources/Documents/img/carat.png -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/img/dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/twodayslate/SplitView/HEAD/docs/docsets/SplitView.docset/Contents/Resources/Documents/img/dash.png -------------------------------------------------------------------------------- /SplitView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SplitView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/app.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/workflows/swift.yml: -------------------------------------------------------------------------------- 1 | name: Swift 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: macos-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v2 16 | - name: Build 17 | run: swift build -v 18 | - name: Run tests 19 | run: swift test -v 20 | -------------------------------------------------------------------------------- /SplitView/SplitSupportingView.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import UIKit 3 | 4 | internal struct SplitSupportingView: Equatable { 5 | public let view: UIView 6 | /// The current width/height ratio of `view` 7 | var ratio: CGFloat = .zero 8 | /// The minimum width/height ratio for `view` 9 | var minRatio: CGFloat = .zero 10 | /// The active constraints for width/height 11 | var constraint: NSLayoutConstraint? = nil 12 | } 13 | -------------------------------------------------------------------------------- /.github/workflows/create-release.yml: -------------------------------------------------------------------------------- 1 | name: Create Release 2 | 3 | # Create XCFramework when a version is tagged 4 | on: 5 | push: 6 | tags: 7 | 8 | jobs: 9 | create_release: 10 | name: Create Release 11 | runs-on: macos-latest 12 | steps: 13 | 14 | - uses: actions/checkout@v2 15 | 16 | - name: Create XCFramework 17 | uses: unsignedapps/swift-create-xcframework@v1 18 | 19 | # Create a release 20 | # Upload those artifacts to the release 21 | -------------------------------------------------------------------------------- /Package@swift-4.2.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:4.2 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "SplitView", 6 | products: [ 7 | .library(name: "SplitView", targets: ["SplitView"]) 8 | ], 9 | dependencies: [], 10 | targets: [ 11 | .target( 12 | name: "SplitView", 13 | dependencies: [], 14 | path: "SplitView"), 15 | .testTarget( 16 | name: "SplitViewTests", 17 | dependencies: ["SplitView"], 18 | path: "SplitViewTests"), 19 | ] 20 | ) 21 | -------------------------------------------------------------------------------- /SplitView/SplitView.h: -------------------------------------------------------------------------------- 1 | // 2 | // splitview.h 3 | // splitview 4 | // 5 | // Created by Zachary Gorak on 8/23/19. 6 | // Copyright © 2019 Zac Gorak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for splitview. 12 | FOUNDATION_EXPORT double splitviewVersionNumber; 13 | 14 | //! Project version string for splitview. 15 | FOUNDATION_EXPORT const unsigned char splitviewVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "SplitView", 6 | platforms: [ 7 | .iOS(.v9), 8 | .macOS(.v10_15) 9 | ], 10 | products: [ 11 | .library(name: "SplitView", targets: ["SplitView"]) 12 | ], 13 | dependencies: [], 14 | targets: [ 15 | .target( 16 | name: "SplitView", 17 | dependencies: [], 18 | path: "SplitView"), 19 | .testTarget( 20 | name: "SplitViewTests", 21 | dependencies: ["SplitView"], 22 | path: "SplitViewTests"), 23 | ] 24 | ) 25 | -------------------------------------------------------------------------------- /docs/undocumented.json: -------------------------------------------------------------------------------- 1 | { 2 | "warnings": [ 3 | { 4 | "file": "/Users/twodayslate/Development/splitview/SplitView/SplitView.swift", 5 | "line": 80, 6 | "symbol": "SplitView.init(frame:)", 7 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 8 | "warning": "undocumented" 9 | }, 10 | { 11 | "file": "/Users/twodayslate/Development/splitview/SplitView/SplitView.swift", 12 | "line": 97, 13 | "symbol": "SplitView.init()", 14 | "symbol_kind": "source.lang.swift.decl.function.method.instance", 15 | "warning": "undocumented" 16 | } 17 | ], 18 | "source_directory": "/Users/twodayslate/Development/splitview" 19 | } -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleIdentifier 6 | com.jazzy.splitview 7 | CFBundleName 8 | SplitView 9 | DocSetPlatformFamily 10 | splitview 11 | isDashDocset 12 | 13 | dashIndexFilePath 14 | index.html 15 | isJavaScriptEnabled 16 | 17 | DashDocSetFamily 18 | dashtoc 19 | 20 | 21 | -------------------------------------------------------------------------------- /SplitViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [twodayslate] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: twodayslate # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DU6YN99AQNAGQ&source=url'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /SplitView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | SplitView 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | 24 | 25 | -------------------------------------------------------------------------------- /SplitViewTests/splitviewTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // splitviewTests.swift 3 | // splitviewTests 4 | // 5 | // Created by Zachary Gorak on 8/23/19. 6 | // Copyright © 2019 Zac Gorak. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import SplitView 11 | 12 | class splitviewTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /docs/badge.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | documentation 17 | 18 | 19 | documentation 20 | 21 | 22 | 95% 23 | 24 | 25 | 95% 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /SplitView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint SplitViewTest.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'SplitView' 11 | s.version = '2.0.2' 12 | s.summary = 'A resizable Split View' 13 | s.swift_versions = ['4.2', '5.0', '5.1'] 14 | 15 | s.description = <<-DESC 16 | A resizable Split View inspired by Apple's Split View for iPadOS 17 | DESC 18 | 19 | s.homepage = 'https://github.com/twodayslate/SplitView' 20 | s.screenshots = 'https://github.com/twodayslate/SplitView/raw/master/images/horizontal.png', 'https://github.com/twodayslate/SplitView/raw/master/images/vertical.png' 21 | s.license = { :type => 'MIT', :file => 'LICENSE' } 22 | s.author = { 'twodayslate' => 'zac@gorak.us' } 23 | s.source = { :git => 'https://github.com/twodayslate/SplitView.git', :tag => "v#{s.version}" } 24 | s.social_media_url = 'https://twitter.com/twodayslate' 25 | 26 | s.ios.deployment_target = '11.0' 27 | #s.osx.deployment_target = '10.15' 28 | 29 | s.source_files = 'SplitView/*' 30 | s.exclude_files = [ 'SplitView/Info.plist'] 31 | 32 | s.public_header_files = 'splitview/*.h' 33 | s.frameworks = 'UIKit' 34 | end 35 | -------------------------------------------------------------------------------- /generate-docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | command -v jazzy 4 | 5 | if [ $? != 0 ]; then 6 | echo "jazzy not found. Install jazzy:" 7 | echo "\t[sudo] gem install jazzy" 8 | exit 1 9 | fi 10 | 11 | set -e # don't print 12 | 13 | module="SplitView" 14 | github="twodayslate/SplitView" 15 | project="splitview.xcodeproj" 16 | scheme="SplitView" 17 | 18 | # get version number from podspec 19 | version="$(egrep "^\s*s.version\s*" SplitView.podspec | awk '{ gsub("\"", "", $3); print $3 }')" 20 | today="$(date '+%Y-%m-%d')" 21 | 22 | if git rev-parse "v$version" >/dev/null 2>&1; then 23 | # Use the tagged commit when we have one 24 | ref="v$version" 25 | else 26 | # Otherwise, use the current commit. 27 | ref="$(git rev-parse HEAD)" 28 | fi 29 | 30 | # since tagging releases doesn't happen very much - let's just use head 31 | ref="master" 32 | 33 | jazzy \ 34 | --clean \ 35 | --github_url "https://github.com/$github" \ 36 | --github-file-prefix "https://github.com/$github/tree/$ref" \ 37 | --module-version "$version" \ 38 | --xcodebuild-arguments "-project,$project,-scheme,$scheme" \ 39 | --module "$module" \ 40 | --root-url "https://twodayslate.github.io/$module/reference/" \ 41 | --output docs \ 42 | --min-acl public\ 43 | --copyright "[© 2019 SplitView](https://github.com/twodayslate/SplitView/blob/master/LICENSE). (Last updated: $today)" \ 44 | --author "twodayslate" \ 45 | --author_url "https://github.com/twodayslate" \ 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SplitView 2 | 3 | Resizable Split View, inspired by [Apple's Split View](https://support.apple.com/en-us/HT207582#split) for iPadOS and [SplitKit](https://github.com/macteo/SplitKit) 4 | 5 |

6 | Vertical Horizontal 7 |

8 | 9 | ## Requirements 10 | 11 | ### Swift Package Manager (SPM) 12 | 13 | ``` 14 | .Package(url: "https://github.com/twodayslate/SplitView.git", majorVersion: 1) 15 | ``` 16 | 17 | For the latest updates use: 18 | ``` 19 | .Package(url: "https://github.com/twodayslate/SplitView.git", branch: "master") 20 | ``` 21 | 22 | ### CocoaPods 23 | 24 | ``` 25 | pod 'SplitView' 26 | ``` 27 | 28 | For the latest updates use: 29 | ``` 30 | pod 'SplitView', :git => 'https://github.com/twodayslate/SplitView.git' 31 | ``` 32 | 33 | ## Usage 34 | 35 | Using `SplitView` is easy! Simply create a `SplitView` and add your views to it - just like a `UIStackView`. 36 | 37 | ``` 38 | import SplitView 39 | // 40 | let mySplitView = SplitView() 41 | mySplitView.addSplitSubview(myFirstView) 42 | mySplitView.addSplitSubview(mySecondView) 43 | ``` 44 | 45 | There are certain customizations available including minimum sizing and snapping. Custom handles are also supported. 46 | 47 | Be sure to checkout the [example App](https://github.com/twodayslate/SplitView/tree/master/app). 48 | -------------------------------------------------------------------------------- /app/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /docs/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | function toggleItem($link, $content) { 12 | var animationDuration = 300; 13 | $link.toggleClass('token-open'); 14 | $content.slideToggle(animationDuration); 15 | } 16 | 17 | function itemLinkToContent($link) { 18 | return $link.parent().parent().next(); 19 | } 20 | 21 | // On doc load + hash-change, open any targetted item 22 | function openCurrentItemIfClosed() { 23 | if (window.jazzy.docset) { 24 | return; 25 | } 26 | var $link = $(`.token[href="${location.hash}"]`); 27 | $content = itemLinkToContent($link); 28 | if ($content.is(':hidden')) { 29 | toggleItem($link, $content); 30 | } 31 | } 32 | 33 | $(openCurrentItemIfClosed); 34 | $(window).on('hashchange', openCurrentItemIfClosed); 35 | 36 | // On item link ('token') click, toggle its discussion 37 | $('.token').on('click', function(event) { 38 | if (window.jazzy.docset) { 39 | return; 40 | } 41 | var $link = $(this); 42 | toggleItem($link, itemLinkToContent($link)); 43 | 44 | // Keeps the document from jumping to the hash. 45 | var href = $link.attr('href'); 46 | if (history.pushState) { 47 | history.pushState({}, '', href); 48 | } else { 49 | location.hash = href; 50 | } 51 | event.preventDefault(); 52 | }); 53 | 54 | // Clicks on links to the current, closed, item need to open the item 55 | $("a:not('.token')").on('click', function() { 56 | if (location == this.href) { 57 | openCurrentItemIfClosed(); 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /app/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSApplicationCategoryType 22 | public.app-category.developer-tools 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationPortrait 43 | UIInterfaceOrientationPortraitUpsideDown 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/js/jazzy.js: -------------------------------------------------------------------------------- 1 | window.jazzy = {'docset': false} 2 | if (typeof window.dash != 'undefined') { 3 | document.documentElement.className += ' dash' 4 | window.jazzy.docset = true 5 | } 6 | if (navigator.userAgent.match(/xcode/i)) { 7 | document.documentElement.className += ' xcode' 8 | window.jazzy.docset = true 9 | } 10 | 11 | function toggleItem($link, $content) { 12 | var animationDuration = 300; 13 | $link.toggleClass('token-open'); 14 | $content.slideToggle(animationDuration); 15 | } 16 | 17 | function itemLinkToContent($link) { 18 | return $link.parent().parent().next(); 19 | } 20 | 21 | // On doc load + hash-change, open any targetted item 22 | function openCurrentItemIfClosed() { 23 | if (window.jazzy.docset) { 24 | return; 25 | } 26 | var $link = $(`.token[href="${location.hash}"]`); 27 | $content = itemLinkToContent($link); 28 | if ($content.is(':hidden')) { 29 | toggleItem($link, $content); 30 | } 31 | } 32 | 33 | $(openCurrentItemIfClosed); 34 | $(window).on('hashchange', openCurrentItemIfClosed); 35 | 36 | // On item link ('token') click, toggle its discussion 37 | $('.token').on('click', function(event) { 38 | if (window.jazzy.docset) { 39 | return; 40 | } 41 | var $link = $(this); 42 | toggleItem($link, itemLinkToContent($link)); 43 | 44 | // Keeps the document from jumping to the hash. 45 | var href = $link.attr('href'); 46 | if (history.pushState) { 47 | history.pushState({}, '', href); 48 | } else { 49 | location.hash = href; 50 | } 51 | event.preventDefault(); 52 | }); 53 | 54 | // Clicks on links to the current, closed, item need to open the item 55 | $("a:not('.token')").on('click', function() { 56 | if (location == this.href) { 57 | openCurrentItemIfClosed(); 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /app/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /app/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // app 4 | // 5 | // Created by Zachary Gorak on 8/23/19. 6 | // Copyright © 2019 Zac Gorak. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | 92 | -------------------------------------------------------------------------------- /SplitView/SplitViewSnapBehavior.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SplitViewSnapBehavior.swift 3 | // SplitView 4 | // 5 | // Created by Zachary Gorak on 9/3/19. 6 | // Copyright © 2019 Zac Gorak. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | /// A structure that contains a snap point that is percentage based and a tolerance for when to snap 13 | public struct SplitViewSnapPoint: Equatable { 14 | /// The point at which to snap 15 | public let percentage: CGFloat 16 | /// The amount of range to induce a snap effects 17 | public let tolerance: CGFloat 18 | 19 | /// The global default tolernace 20 | public static var defaultTolerance:CGFloat = 0.04 21 | } 22 | 23 | /// The specefied snap behavior 24 | public enum SplitViewSnapBehavior: Equatable { 25 | /// Snap every 25% (0%, 25%, 50%, 75%, 80%) with the default tolerance 26 | case quarter 27 | /// Snap every 33% (0%, 33%, 66%, 100%) with a the default tolerance 28 | case third 29 | /// Snap at a given percentage and tolerance 30 | case custom(percentage: CGFloat, tolerance: CGFloat) 31 | /// Snap at a given SnapPoint 32 | case withPoint(SplitViewSnapPoint) 33 | /// Snap at the given SnapPoints 34 | case withPoints([SplitViewSnapPoint]) 35 | 36 | /// The points at which to snap 37 | var snapPoints: [SplitViewSnapPoint] { 38 | switch self { 39 | case .quarter: 40 | return [SplitViewSnapPoint(percentage: 0.0, tolerance: SplitViewSnapPoint.defaultTolerance), 41 | SplitViewSnapPoint(percentage: 0.25, tolerance: SplitViewSnapPoint.defaultTolerance), 42 | SplitViewSnapPoint(percentage: 0.50, tolerance: SplitViewSnapPoint.defaultTolerance), 43 | SplitViewSnapPoint(percentage: 0.75, tolerance: SplitViewSnapPoint.defaultTolerance), 44 | SplitViewSnapPoint(percentage: 1.0, tolerance: SplitViewSnapPoint.defaultTolerance)] 45 | case .third: 46 | return [SplitViewSnapPoint(percentage: 0.0, tolerance: SplitViewSnapPoint.defaultTolerance), 47 | SplitViewSnapPoint(percentage: 1.0/3.0, tolerance: SplitViewSnapPoint.defaultTolerance), 48 | SplitViewSnapPoint(percentage: 2.0/3.0, tolerance: SplitViewSnapPoint.defaultTolerance), 49 | SplitViewSnapPoint(percentage: 1.0, tolerance: SplitViewSnapPoint.defaultTolerance) 50 | ] 51 | case .withPoint(let point): 52 | return [point] 53 | case .withPoints(let points): 54 | return points 55 | case .custom(let percentage, let tolerance): 56 | return [SplitViewSnapPoint(percentage: percentage, tolerance: tolerance)] 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /SplitView.xcodeproj/xcshareddata/xcschemes/app.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SplitView.xcodeproj/xcshareddata/xcschemes/SplitView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 54 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /app/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // app 4 | // 5 | // Created by Zachary Gorak on 8/23/19. 6 | // Copyright © 2019 Zac Gorak. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SplitView 11 | import WebKit 12 | 13 | 14 | class ViewController: UIViewController { 15 | 16 | var splitView: SplitView! 17 | 18 | let browser = WKWebView() 19 | let label = UITextView() 20 | let removeButton = UIBarButtonItem(title: "Remove", style: .plain, target: self, action: #selector(removeView(_:))) 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | 25 | let stack = UIStackView() 26 | stack.translatesAutoresizingMaskIntoConstraints = false 27 | stack.axis = .vertical 28 | 29 | let toolbar = UIToolbar() 30 | stack.addArrangedSubview(toolbar) 31 | 32 | toolbar.items = [ 33 | UIBarButtonItem(title: "Rotate", style: .plain, target: self, action: #selector(rotate(_:))), 34 | UIBarButtonItem(title: "Toggle Snapping", style: .plain, target: self, action: #selector(toggleSnap(_:))), 35 | UIBarButtonItem(title: "Add", style: .plain, target: self, action: #selector(addView(_:))), 36 | removeButton 37 | ] 38 | 39 | splitView = SplitView() 40 | splitView.backgroundColor = .black 41 | stack.addArrangedSubview(splitView) 42 | 43 | browser.layer.cornerRadius = 15.0 44 | browser.backgroundColor = .systemBackground 45 | browser.layer.masksToBounds = true 46 | label.backgroundColor = .systemBackground 47 | label.layer.cornerRadius = 15.0 48 | label.layer.masksToBounds = true 49 | 50 | splitView.addSplitSubview(browser) 51 | splitView.addSplitSubview(label) 52 | 53 | self.view.addSubview(stack) 54 | 55 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-[stack]-|", options: .alignAllCenterY, metrics: nil, views: ["stack": stack])) 56 | view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[stack]|", options: .alignAllCenterY, metrics: nil, views: ["stack": stack])) 57 | } 58 | 59 | override func viewDidAppear(_ animated: Bool) { 60 | super.viewDidAppear(animated) 61 | 62 | let url = URL(string: "https://zac.gorak.us/")! 63 | 64 | browser.load(URLRequest(url: url)) 65 | 66 | DispatchQueue.init(label: "background", qos: .userInitiated).async { 67 | let source = (try? String(contentsOf: url)) ?? "UNABLE TO GET SOURCE" 68 | DispatchQueue.main.async { 69 | self.label.text = source 70 | } 71 | } 72 | 73 | } 74 | 75 | @objc func rotate(_ sender: UIBarButtonItem) { 76 | print("rotate") 77 | if self.splitView.axis == .horizontal { 78 | self.splitView.axis = .vertical 79 | } else { 80 | self.splitView.axis = .horizontal 81 | } 82 | } 83 | 84 | @objc func toggleSnap(_ sender: UIBarButtonItem) { 85 | if splitView.snap.isEmpty { 86 | sender.title = "Turn off Snapping" 87 | splitView.snap.append(SplitViewSnapBehavior.quarter) 88 | } else { 89 | sender.title = "Turn on Snapping" 90 | splitView.snap.removeAll() 91 | } 92 | } 93 | 94 | @objc func addView(_ sender: UIBarButtonItem) { 95 | 96 | let label = UILabel() 97 | label.text = splitView.splitSubviews.count.description 98 | label.textAlignment = .center 99 | label.font = UIFont.boldSystemFont(ofSize: 50.0) 100 | label.adjustsFontSizeToFitWidth = true 101 | label.backgroundColor = .systemBackground 102 | label.layer.cornerRadius = 15.0 103 | label.layer.masksToBounds = true 104 | 105 | splitView.addSplitSubview(label) 106 | 107 | removeButton.isEnabled = true 108 | } 109 | 110 | @objc func removeView(_ sender: UIBarButtonItem) { 111 | splitView.removeSplitSubview(splitView.splitSubviews.last!) 112 | if splitView.splitSubviews.count <= 0 { 113 | removeButton.isEnabled = false 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitView Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

SplitView '2.0.0' Docs (95% documented)

17 |

View on GitHub

18 |

Install in Dash

19 |
20 |
21 |
22 | 27 |
28 |
29 | 60 |
61 |
62 |
63 | 64 |

SplitView

65 | 66 |

Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

67 | 68 |

69 | Vertical Horizontal 70 |

71 |

Requirements

72 |

Swift Package Manager (SPM)

73 |
.Package(url: "https://github.com/twodayslate/SplitView.git", majorVersion: 1)
 74 | 
75 | 76 |

For the latest updates use:

77 |
.Package(url: "https://github.com/twodayslate/SplitView.git", branch: "master")
 78 | 
79 |

CocoaPods

80 |
pod 'SplitView'
 81 | 
82 | 83 |

For the latest updates use:

84 |
pod 'SplitView', :git => 'https://github.com/twodayslate/SplitView.git'
 85 | 
86 |

Usage

87 | 88 |

Using SplitView is easy! Simply create a SplitView and add your views to it - just like a UIStackView.

89 |
import SplitView
 90 | //
 91 | let mySplitView = SplitView()
 92 | mySplitView.addSplitSubview(myFirstView)
 93 | mySplitView.addSplitSubview(mySecondView)
 94 | 
95 | 96 |

There are certain customizations available including minimum sizing and snapping. Custom handles are also supported.

97 | 98 |

Be sure to checkout the example App.

99 | 100 |
101 |
102 | 106 |
107 |
108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitView Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 |

SplitView '2.0.0' Docs (95% documented)

17 |

View on GitHub

18 |

Install in Dash

19 |
20 |
21 |
22 | 27 |
28 |
29 | 60 |
61 |
62 |
63 | 64 |

SplitView

65 | 66 |

Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

67 | 68 |

69 | Vertical Horizontal 70 |

71 |

Requirements

72 |

Swift Package Manager (SPM)

73 |
.Package(url: "https://github.com/twodayslate/SplitView.git", majorVersion: 1)
 74 | 
75 | 76 |

For the latest updates use:

77 |
.Package(url: "https://github.com/twodayslate/SplitView.git", branch: "master")
 78 | 
79 |

CocoaPods

80 |
pod 'SplitView'
 81 | 
82 | 83 |

For the latest updates use:

84 |
pod 'SplitView', :git => 'https://github.com/twodayslate/SplitView.git'
 85 | 
86 |

Usage

87 | 88 |

Using SplitView is easy! Simply create a SplitView and add your views to it - just like a UIStackView.

89 |
import SplitView
 90 | //
 91 | let mySplitView = SplitView()
 92 | mySplitView.addSplitSubview(myFirstView)
 93 | mySplitView.addSplitSubview(mySecondView)
 94 | 
95 | 96 |

There are certain customizations available including minimum sizing and snapping. Custom handles are also supported.

97 | 98 |

Be sure to checkout the example App.

99 | 100 |
101 |
102 | 106 |
107 |
108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /docs/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enumerations Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Enumerations

65 |

The following enumerations are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitViewSnapBehavior 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    The specefied snap behavior

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    public enum SplitViewSnapBehavior : Equatable
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
106 | 110 |
111 |
112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structures Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Structures

65 |

The following structures are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitViewSnapPoint 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    A structure that contains a snap point that is percentage based and a tolerance for when to snap

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    public struct SplitViewSnapPoint : Equatable
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
106 | 110 |
111 |
112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/Enums.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Enumerations Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Enumerations

65 |

The following enumerations are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitViewSnapBehavior 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    The specefied snap behavior

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    public enum SplitViewSnapBehavior : Equatable
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
106 | 110 |
111 |
112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/Structs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Structures Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Structures

65 |

The following structures are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitViewSnapPoint 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    A structure that contains a snap point that is percentage based and a tolerance for when to snap

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    public struct SplitViewSnapPoint : Equatable
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
106 | 110 |
111 |
112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/css/highlight.css: -------------------------------------------------------------------------------- 1 | /* Credit to https://gist.github.com/wataru420/2048287 */ 2 | .highlight { 3 | /* Comment */ 4 | /* Error */ 5 | /* Keyword */ 6 | /* Operator */ 7 | /* Comment.Multiline */ 8 | /* Comment.Preproc */ 9 | /* Comment.Single */ 10 | /* Comment.Special */ 11 | /* Generic.Deleted */ 12 | /* Generic.Deleted.Specific */ 13 | /* Generic.Emph */ 14 | /* Generic.Error */ 15 | /* Generic.Heading */ 16 | /* Generic.Inserted */ 17 | /* Generic.Inserted.Specific */ 18 | /* Generic.Output */ 19 | /* Generic.Prompt */ 20 | /* Generic.Strong */ 21 | /* Generic.Subheading */ 22 | /* Generic.Traceback */ 23 | /* Keyword.Constant */ 24 | /* Keyword.Declaration */ 25 | /* Keyword.Pseudo */ 26 | /* Keyword.Reserved */ 27 | /* Keyword.Type */ 28 | /* Literal.Number */ 29 | /* Literal.String */ 30 | /* Name.Attribute */ 31 | /* Name.Builtin */ 32 | /* Name.Class */ 33 | /* Name.Constant */ 34 | /* Name.Entity */ 35 | /* Name.Exception */ 36 | /* Name.Function */ 37 | /* Name.Namespace */ 38 | /* Name.Tag */ 39 | /* Name.Variable */ 40 | /* Operator.Word */ 41 | /* Text.Whitespace */ 42 | /* Literal.Number.Float */ 43 | /* Literal.Number.Hex */ 44 | /* Literal.Number.Integer */ 45 | /* Literal.Number.Oct */ 46 | /* Literal.String.Backtick */ 47 | /* Literal.String.Char */ 48 | /* Literal.String.Doc */ 49 | /* Literal.String.Double */ 50 | /* Literal.String.Escape */ 51 | /* Literal.String.Heredoc */ 52 | /* Literal.String.Interpol */ 53 | /* Literal.String.Other */ 54 | /* Literal.String.Regex */ 55 | /* Literal.String.Single */ 56 | /* Literal.String.Symbol */ 57 | /* Name.Builtin.Pseudo */ 58 | /* Name.Variable.Class */ 59 | /* Name.Variable.Global */ 60 | /* Name.Variable.Instance */ 61 | /* Literal.Number.Integer.Long */ } 62 | .highlight .c { 63 | color: #999988; 64 | font-style: italic; } 65 | .highlight .err { 66 | color: #a61717; 67 | background-color: #e3d2d2; } 68 | .highlight .k { 69 | color: #000000; 70 | font-weight: bold; } 71 | .highlight .o { 72 | color: #000000; 73 | font-weight: bold; } 74 | .highlight .cm { 75 | color: #999988; 76 | font-style: italic; } 77 | .highlight .cp { 78 | color: #999999; 79 | font-weight: bold; } 80 | .highlight .c1 { 81 | color: #999988; 82 | font-style: italic; } 83 | .highlight .cs { 84 | color: #999999; 85 | font-weight: bold; 86 | font-style: italic; } 87 | .highlight .gd { 88 | color: #000000; 89 | background-color: #ffdddd; } 90 | .highlight .gd .x { 91 | color: #000000; 92 | background-color: #ffaaaa; } 93 | .highlight .ge { 94 | color: #000000; 95 | font-style: italic; } 96 | .highlight .gr { 97 | color: #aa0000; } 98 | .highlight .gh { 99 | color: #999999; } 100 | .highlight .gi { 101 | color: #000000; 102 | background-color: #ddffdd; } 103 | .highlight .gi .x { 104 | color: #000000; 105 | background-color: #aaffaa; } 106 | .highlight .go { 107 | color: #888888; } 108 | .highlight .gp { 109 | color: #555555; } 110 | .highlight .gs { 111 | font-weight: bold; } 112 | .highlight .gu { 113 | color: #aaaaaa; } 114 | .highlight .gt { 115 | color: #aa0000; } 116 | .highlight .kc { 117 | color: #000000; 118 | font-weight: bold; } 119 | .highlight .kd { 120 | color: #000000; 121 | font-weight: bold; } 122 | .highlight .kp { 123 | color: #000000; 124 | font-weight: bold; } 125 | .highlight .kr { 126 | color: #000000; 127 | font-weight: bold; } 128 | .highlight .kt { 129 | color: #445588; } 130 | .highlight .m { 131 | color: #009999; } 132 | .highlight .s { 133 | color: #d14; } 134 | .highlight .na { 135 | color: #008080; } 136 | .highlight .nb { 137 | color: #0086B3; } 138 | .highlight .nc { 139 | color: #445588; 140 | font-weight: bold; } 141 | .highlight .no { 142 | color: #008080; } 143 | .highlight .ni { 144 | color: #800080; } 145 | .highlight .ne { 146 | color: #990000; 147 | font-weight: bold; } 148 | .highlight .nf { 149 | color: #990000; } 150 | .highlight .nn { 151 | color: #555555; } 152 | .highlight .nt { 153 | color: #000080; } 154 | .highlight .nv { 155 | color: #008080; } 156 | .highlight .ow { 157 | color: #000000; 158 | font-weight: bold; } 159 | .highlight .w { 160 | color: #bbbbbb; } 161 | .highlight .mf { 162 | color: #009999; } 163 | .highlight .mh { 164 | color: #009999; } 165 | .highlight .mi { 166 | color: #009999; } 167 | .highlight .mo { 168 | color: #009999; } 169 | .highlight .sb { 170 | color: #d14; } 171 | .highlight .sc { 172 | color: #d14; } 173 | .highlight .sd { 174 | color: #d14; } 175 | .highlight .s2 { 176 | color: #d14; } 177 | .highlight .se { 178 | color: #d14; } 179 | .highlight .sh { 180 | color: #d14; } 181 | .highlight .si { 182 | color: #d14; } 183 | .highlight .sx { 184 | color: #d14; } 185 | .highlight .sr { 186 | color: #009926; } 187 | .highlight .s1 { 188 | color: #d14; } 189 | .highlight .ss { 190 | color: #990073; } 191 | .highlight .bp { 192 | color: #999999; } 193 | .highlight .vc { 194 | color: #008080; } 195 | .highlight .vg { 196 | color: #008080; } 197 | .highlight .vi { 198 | color: #008080; } 199 | .highlight .il { 200 | color: #009999; } 201 | -------------------------------------------------------------------------------- /SplitView/SplitViewHandle.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | import UIKit 3 | 4 | /// The seperator/handle that is between each view in a `SplitView` 5 | open class SplitViewHandle: UIView { 6 | // MARK: - Properties 7 | 8 | // MARK: Public 9 | /// The center view used for grabbing 10 | public var grabber: UIView 11 | /// The width/height of the view 12 | public var size: CGFloat 13 | /// Used for position tracking 14 | public var initialOrigin: CGPoint? = nil 15 | /// - returns: 16 | /// If being dragged returns `true`, `false` otherwise 17 | public var isBeingUsed = false 18 | 19 | /// This property determines the orientation of the arranged views. 20 | /// Assigning the `NSLayoutConstraint.Axis.vertical` value creates a column of views. 21 | /// Assigning the `NSLayoutConstraint.Axis.horizontal` value creates a row. 22 | public var axis: NSLayoutConstraint.Axis = .horizontal { 23 | didSet { 24 | self.layoutConstraints() 25 | } 26 | } 27 | 28 | /// The current constraints on the handle 29 | /// This is used when changing axises and should only be modified 30 | /// when overriding 31 | public var handleConstraints = [NSLayoutConstraint]() 32 | 33 | // MARK: - Initilizers 34 | init(with view: UIView, size: CGFloat) { 35 | self.size = size 36 | self.grabber = view 37 | 38 | super.init(frame: .zero) 39 | 40 | self.translatesAutoresizingMaskIntoConstraints = false 41 | 42 | self.addSubview(self.grabber) 43 | 44 | self.grabber.translatesAutoresizingMaskIntoConstraints = false 45 | self.grabber.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 46 | self.grabber.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true 47 | self.layoutConstraints() 48 | } 49 | 50 | /// Not implemented 51 | required public init?(coder aDecoder: NSCoder) { 52 | fatalError("init(coder:) has not been implemented") 53 | } 54 | 55 | // MARK: - View Handling 56 | 57 | /// Override this if you are cusomizing your seperator/handle 58 | /// Use `handleConstraints` as necessary 59 | open func layoutConstraints() { 60 | var tmpHandleConstraints = [NSLayoutConstraint]() 61 | 62 | // If they forgot to set a custom layout we will do the basics for them 63 | if self.axis == .vertical { 64 | tmpHandleConstraints.append(NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0.0, constant: self.size)) 65 | } else { 66 | tmpHandleConstraints.append(NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0.0, constant: self.size)) 67 | } 68 | 69 | NSLayoutConstraint.deactivate(self.handleConstraints) 70 | NSLayoutConstraint.activate(tmpHandleConstraints) 71 | self.handleConstraints = tmpHandleConstraints 72 | } 73 | } 74 | 75 | internal class DefaultSplitViewHandle: SplitViewHandle { 76 | override func layoutConstraints() { 77 | let defaultSize: CGFloat = 48.0 78 | var tmpHandleConstraints = [NSLayoutConstraint]() 79 | 80 | if self.axis == .vertical { 81 | tmpHandleConstraints = [ 82 | NSLayoutConstraint(item: self.grabber, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 0.5, constant: 0.0), 83 | NSLayoutConstraint(item: self.grabber, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0.0, constant: defaultSize), 84 | NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0.0, constant: self.size) 85 | ] 86 | } else { 87 | tmpHandleConstraints = [ 88 | NSLayoutConstraint(item: self.grabber, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 0.0, constant: defaultSize), 89 | NSLayoutConstraint(item: self.grabber, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.5, constant: 0.0), 90 | NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 0.0, constant: self.size) 91 | ] 92 | } 93 | 94 | NSLayoutConstraint.deactivate(self.handleConstraints) 95 | NSLayoutConstraint.activate(tmpHandleConstraints) 96 | self.handleConstraints = tmpHandleConstraints 97 | } 98 | 99 | override var isBeingUsed: Bool { 100 | didSet { 101 | if self.isBeingUsed { 102 | DispatchQueue.main.async { 103 | UIView.animate(withDuration: 0.5) { 104 | self.grabber.backgroundColor = self.grabber.backgroundColor?.withAlphaComponent(0.85) 105 | } 106 | } 107 | } else { 108 | DispatchQueue.main.async { 109 | UIView.animate(withDuration: 0.2) { 110 | self.grabber.backgroundColor = self.grabber.backgroundColor?.withAlphaComponent(0.6) 111 | } 112 | } 113 | } 114 | } 115 | } 116 | } 117 | 118 | // MARK: - Default 119 | extension SplitViewHandle { 120 | /// The default handle. 121 | public class func useDefault() -> SplitViewHandle { 122 | let innerHandle = UIView() 123 | innerHandle.backgroundColor = UIColor.white.withAlphaComponent(0.6) 124 | innerHandle.layer.cornerRadius = 4.0 125 | 126 | let handle = DefaultSplitViewHandle(with: innerHandle, size: 11.0) 127 | handle.backgroundColor = .black 128 | 129 | return handle 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /docs/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Classes

65 |

The following classes are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitView 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    open class SplitView : UIView
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
    106 |
  • 107 |
    108 | 109 | 110 | 111 | SplitViewHandle 112 | 113 |
    114 |
    115 |
    116 |
    117 |
    118 |
    119 |

    The seperator/handle that is between each view in a SplitView

    120 | 121 | See more 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    open class SplitViewHandle : UIView
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
138 |
139 |
140 |
141 | 145 |
146 |
147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/Classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Classes Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

Classes

65 |

The following classes are available globally.

66 | 67 |
68 |
69 |
70 |
    71 |
  • 72 |
    73 | 74 | 75 | 76 | SplitView 77 | 78 |
    79 |
    80 |
    81 |
    82 |
    83 |
    84 |

    Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

    85 | 86 | See more 87 |
    88 |
    89 |

    Declaration

    90 |
    91 |

    Swift

    92 |
    open class SplitView : UIView
    93 | 94 |
    95 |
    96 |
    97 | Show on GitHub 98 |
    99 |
    100 |
    101 |
  • 102 |
103 |
104 |
105 |
    106 |
  • 107 |
    108 | 109 | 110 | 111 | SplitViewHandle 112 | 113 |
    114 |
    115 |
    116 |
    117 |
    118 |
    119 |

    The seperator/handle that is between each view in a SplitView

    120 | 121 | See more 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    open class SplitViewHandle : UIView
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
138 |
139 |
140 |
141 | 145 |
146 |
147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /docs/search.json: -------------------------------------------------------------------------------- 1 | {"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV10percentage12CoreGraphics7CGFloatVvp":{"name":"percentage","abstract":"

The point at which to snap

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV9tolerance12CoreGraphics7CGFloatVvp":{"name":"tolerance","abstract":"

The amount of range to induce a snap effects

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV16defaultTolerance12CoreGraphics7CGFloatVvpZ":{"name":"defaultTolerance","abstract":"

The global default tolernace

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html":{"name":"SplitViewSnapPoint","abstract":"

A structure that contains a snap point that is percentage based and a tolerance for when to snap

"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO7quarteryA2CmF":{"name":"quarter","abstract":"

Snap every 25% (0%, 25%, 50%, 75%, 80%) with the default tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO5thirdyA2CmF":{"name":"third","abstract":"

Snap every 33% (0%, 33%, 66%, 100%) with a the default tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO6customyAC12CoreGraphics7CGFloatV_AGtcACmF":{"name":"custom(percentage:tolerance:)","abstract":"

Snap at a given percentage and tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO9withPointyAcA0abcF0VcACmF":{"name":"withPoint(_:)","abstract":"

Snap at a given SnapPoint

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO10withPointsyACSayAA0abC5PointVGcACmF":{"name":"withPoints(_:)","abstract":"

Snap at the given SnapPoints

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html":{"name":"SplitViewSnapBehavior","abstract":"

The specefied snap behavior

"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC7grabberSo6UIViewCvp":{"name":"grabber","abstract":"

The center view used for grabbing

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC4size12CoreGraphics7CGFloatVvp":{"name":"size","abstract":"

The width/height of the view

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC13initialOriginSo7CGPointVSgvp":{"name":"initialOrigin","abstract":"

Used for position tracking

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC11isBeingUsedSbvp":{"name":"isBeingUsed","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC4axisSo22UILayoutConstraintAxisVvp":{"name":"axis","abstract":"

This property determines the orientation of the arranged views.","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC17handleConstraintsSaySo18NSLayoutConstraintCGvp":{"name":"handleConstraints","abstract":"

The current constraints on the handle","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/c:@M@SplitView@objc(cs)SplitViewHandle(im)initWithCoder:":{"name":"init(coder:)","abstract":"

Not implemented

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC17layoutConstraintsyyF":{"name":"layoutConstraints()","abstract":"

Override this if you are cusomizing your seperator/handle","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC10useDefaultACyFZ":{"name":"useDefault()","abstract":"

The default handle.

","parent_name":"SplitViewHandle"},"Classes/SplitView.html#/s:9SplitViewAAC13splitSubviewsSaySo6UIViewCGvp":{"name":"splitSubviews","abstract":"

The list of views split by the split view.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC7handlesSayAA0aB6HandleCGvp":{"name":"handles","abstract":"

The handles between views

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC12minimumRatio12CoreGraphics7CGFloatVvp":{"name":"minimumRatio","abstract":"

The minimum width/height ratio for each view

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC17animationDurationSdvp":{"name":"animationDuration","abstract":"

The animation duration when resizing views

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC9precisionSivp":{"name":"precision","abstract":"

The precision of the movements. 1 is every 10%, 2 is every 1%, etc

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC4snapSayAA0aB12SnapBehaviorOGvp":{"name":"snap","abstract":"

Snap Behavior

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC4axisSo22UILayoutConstraintAxisVvp":{"name":"axis","abstract":"

The axis along which the split views are laid out.

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)initWithFrame:":{"name":"init(frame:)","abstract":"

Undocumented

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)init":{"name":"init()","abstract":"

Undocumented

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC13splitSubviewsABSaySo6UIViewCG_tcfc":{"name":"init(splitSubviews:)","abstract":"

Returns a new split view object that manages the provided views.

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)initWithCoder:":{"name":"init(coder:)","abstract":"

Not implemented

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC03addA7Subview_12desiredRatio07minimumF010withHandleySo6UIViewC_12CoreGraphics7CGFloatVAkA0abI0CSgtF":{"name":"addSplitSubview(_:desiredRatio:minimumRatio:withHandle:)","abstract":"

Adds a view to the end of the splitSupportingViews array

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC06insertA7Subview_2at12desiredRatio07minimumG010withHandleySo6UIViewC_Si12CoreGraphics7CGFloatVAlA0abJ0CSgtF":{"name":"insertSplitSubview(_:at:desiredRatio:minimumRatio:withHandle:)","abstract":"

Adds the provided view to the array of split subviews at the specified index.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC06removeA7SubviewyySo6UIViewCF":{"name":"removeSplitSubview(_:)","abstract":"

Removes the provided view from the stack’s array of split subviews.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC6ratiosSay12CoreGraphics7CGFloatVGvp":{"name":"ratios","abstract":"

The current ratio for all the split subviews

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC13minimumRatiosSay12CoreGraphics7CGFloatVGvp":{"name":"minimumRatios","abstract":"

The minimum ratios for all the split subviews

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC15setMinimumRatio_3fory12CoreGraphics7CGFloatV_So6UIViewCtF":{"name":"setMinimumRatio(_:for:)","abstract":"

Set the minimum ratio for a specific view

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC34isLayoutMarginsRelativeArrangementSbvp":{"name":"isLayoutMarginsRelativeArrangement","abstract":"

A Boolean value that determines whether the split view lays out its split views relative to","parent_name":"SplitView"},"Classes/SplitView.html":{"name":"SplitView","abstract":"

Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

"},"Classes/SplitViewHandle.html":{"name":"SplitViewHandle","abstract":"

The seperator/handle that is between each view in a SplitView

"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"}} -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/search.json: -------------------------------------------------------------------------------- 1 | {"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV10percentage12CoreGraphics7CGFloatVvp":{"name":"percentage","abstract":"

The point at which to snap

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV9tolerance12CoreGraphics7CGFloatVvp":{"name":"tolerance","abstract":"

The amount of range to induce a snap effects

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html#/s:9SplitView0aB9SnapPointV16defaultTolerance12CoreGraphics7CGFloatVvpZ":{"name":"defaultTolerance","abstract":"

The global default tolernace

","parent_name":"SplitViewSnapPoint"},"Structs/SplitViewSnapPoint.html":{"name":"SplitViewSnapPoint","abstract":"

A structure that contains a snap point that is percentage based and a tolerance for when to snap

"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO7quarteryA2CmF":{"name":"quarter","abstract":"

Snap every 25% (0%, 25%, 50%, 75%, 80%) with the default tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO5thirdyA2CmF":{"name":"third","abstract":"

Snap every 33% (0%, 33%, 66%, 100%) with a the default tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO6customyAC12CoreGraphics7CGFloatV_AGtcACmF":{"name":"custom(percentage:tolerance:)","abstract":"

Snap at a given percentage and tolerance

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO9withPointyAcA0abcF0VcACmF":{"name":"withPoint(_:)","abstract":"

Snap at a given SnapPoint

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html#/s:9SplitView0aB12SnapBehaviorO10withPointsyACSayAA0abC5PointVGcACmF":{"name":"withPoints(_:)","abstract":"

Snap at the given SnapPoints

","parent_name":"SplitViewSnapBehavior"},"Enums/SplitViewSnapBehavior.html":{"name":"SplitViewSnapBehavior","abstract":"

The specefied snap behavior

"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC7grabberSo6UIViewCvp":{"name":"grabber","abstract":"

The center view used for grabbing

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC4size12CoreGraphics7CGFloatVvp":{"name":"size","abstract":"

The width/height of the view

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC13initialOriginSo7CGPointVSgvp":{"name":"initialOrigin","abstract":"

Used for position tracking

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC11isBeingUsedSbvp":{"name":"isBeingUsed","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC4axisSo22UILayoutConstraintAxisVvp":{"name":"axis","abstract":"

This property determines the orientation of the arranged views.","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC17handleConstraintsSaySo18NSLayoutConstraintCGvp":{"name":"handleConstraints","abstract":"

The current constraints on the handle","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/c:@M@SplitView@objc(cs)SplitViewHandle(im)initWithCoder:":{"name":"init(coder:)","abstract":"

Not implemented

","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC17layoutConstraintsyyF":{"name":"layoutConstraints()","abstract":"

Override this if you are cusomizing your seperator/handle","parent_name":"SplitViewHandle"},"Classes/SplitViewHandle.html#/s:9SplitView0aB6HandleC10useDefaultACyFZ":{"name":"useDefault()","abstract":"

The default handle.

","parent_name":"SplitViewHandle"},"Classes/SplitView.html#/s:9SplitViewAAC13splitSubviewsSaySo6UIViewCGvp":{"name":"splitSubviews","abstract":"

The list of views split by the split view.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC7handlesSayAA0aB6HandleCGvp":{"name":"handles","abstract":"

The handles between views

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC12minimumRatio12CoreGraphics7CGFloatVvp":{"name":"minimumRatio","abstract":"

The minimum width/height ratio for each view

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC17animationDurationSdvp":{"name":"animationDuration","abstract":"

The animation duration when resizing views

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC9precisionSivp":{"name":"precision","abstract":"

The precision of the movements. 1 is every 10%, 2 is every 1%, etc

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC4snapSayAA0aB12SnapBehaviorOGvp":{"name":"snap","abstract":"

Snap Behavior

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC4axisSo22UILayoutConstraintAxisVvp":{"name":"axis","abstract":"

The axis along which the split views are laid out.

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)initWithFrame:":{"name":"init(frame:)","abstract":"

Undocumented

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)init":{"name":"init()","abstract":"

Undocumented

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC13splitSubviewsABSaySo6UIViewCG_tcfc":{"name":"init(splitSubviews:)","abstract":"

Returns a new split view object that manages the provided views.

","parent_name":"SplitView"},"Classes/SplitView.html#/c:@M@SplitView@objc(cs)SplitView(im)initWithCoder:":{"name":"init(coder:)","abstract":"

Not implemented

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC03addA7Subview_12desiredRatio07minimumF010withHandleySo6UIViewC_12CoreGraphics7CGFloatVAkA0abI0CSgtF":{"name":"addSplitSubview(_:desiredRatio:minimumRatio:withHandle:)","abstract":"

Adds a view to the end of the splitSupportingViews array

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC06insertA7Subview_2at12desiredRatio07minimumG010withHandleySo6UIViewC_Si12CoreGraphics7CGFloatVAlA0abJ0CSgtF":{"name":"insertSplitSubview(_:at:desiredRatio:minimumRatio:withHandle:)","abstract":"

Adds the provided view to the array of split subviews at the specified index.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC06removeA7SubviewyySo6UIViewCF":{"name":"removeSplitSubview(_:)","abstract":"

Removes the provided view from the stack’s array of split subviews.

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC6ratiosSay12CoreGraphics7CGFloatVGvp":{"name":"ratios","abstract":"

The current ratio for all the split subviews

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC13minimumRatiosSay12CoreGraphics7CGFloatVGvp":{"name":"minimumRatios","abstract":"

The minimum ratios for all the split subviews

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC15setMinimumRatio_3fory12CoreGraphics7CGFloatV_So6UIViewCtF":{"name":"setMinimumRatio(_:for:)","abstract":"

Set the minimum ratio for a specific view

","parent_name":"SplitView"},"Classes/SplitView.html#/s:9SplitViewAAC34isLayoutMarginsRelativeArrangementSbvp":{"name":"isLayoutMarginsRelativeArrangement","abstract":"

A Boolean value that determines whether the split view lays out its split views relative to","parent_name":"SplitView"},"Classes/SplitView.html":{"name":"SplitView","abstract":"

Resizable Split View, inspired by Apple’s Split View for iPadOS and SplitKit

"},"Classes/SplitViewHandle.html":{"name":"SplitViewHandle","abstract":"

The seperator/handle that is between each view in a SplitView

"},"Classes.html":{"name":"Classes","abstract":"

The following classes are available globally.

"},"Enums.html":{"name":"Enumerations","abstract":"

The following enumerations are available globally.

"},"Structs.html":{"name":"Structures","abstract":"

The following structures are available globally.

"}} -------------------------------------------------------------------------------- /docs/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 20px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token, .item .direct-link { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; 223 | transition: all 300ms; } 224 | .item .token-open { 225 | margin-left: 0px; } 226 | .item .discouraged { 227 | text-decoration: line-through; } 228 | .item .declaration-note { 229 | font-size: .85em; 230 | color: gray; 231 | font-style: italic; } 232 | 233 | .pointer-container { 234 | border-bottom: 1px solid #e2e2e2; 235 | left: -23px; 236 | padding-bottom: 13px; 237 | position: relative; 238 | width: 110%; } 239 | 240 | .pointer { 241 | background: #f9f9f9; 242 | border-left: 1px solid #e2e2e2; 243 | border-top: 1px solid #e2e2e2; 244 | height: 12px; 245 | left: 21px; 246 | top: -7px; 247 | -webkit-transform: rotate(45deg); 248 | -moz-transform: rotate(45deg); 249 | -o-transform: rotate(45deg); 250 | transform: rotate(45deg); 251 | position: absolute; 252 | width: 12px; } 253 | 254 | .height-container { 255 | display: none; 256 | left: -25px; 257 | padding: 0 25px; 258 | position: relative; 259 | width: 100%; 260 | overflow: hidden; } 261 | .height-container .section { 262 | background: #f9f9f9; 263 | border-bottom: 1px solid #e2e2e2; 264 | left: -25px; 265 | position: relative; 266 | width: 100%; 267 | padding-top: 10px; 268 | padding-bottom: 5px; } 269 | 270 | .aside, .language { 271 | padding: 6px 12px; 272 | margin: 12px 0; 273 | border-left: 5px solid #dddddd; 274 | overflow-y: hidden; } 275 | .aside .aside-title, .language .aside-title { 276 | font-size: 9px; 277 | letter-spacing: 2px; 278 | text-transform: uppercase; 279 | padding-bottom: 0; 280 | margin: 0; 281 | color: #aaa; 282 | -webkit-user-select: none; } 283 | .aside p:last-child, .language p:last-child { 284 | margin-bottom: 0; } 285 | 286 | .language { 287 | border-left: 5px solid #cde9f4; } 288 | .language .aside-title { 289 | color: #4b8afb; } 290 | 291 | .aside-warning, .aside-deprecated, .aside-unavailable { 292 | border-left: 5px solid #ff6666; } 293 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { 294 | color: #ff0000; } 295 | 296 | .graybox { 297 | border-collapse: collapse; 298 | width: 100%; } 299 | .graybox p { 300 | margin: 0; 301 | word-break: break-word; 302 | min-width: 50px; } 303 | .graybox td { 304 | border: 1px solid #e2e2e2; 305 | padding: 5px 25px 5px 10px; 306 | vertical-align: middle; } 307 | .graybox tr td:first-of-type { 308 | text-align: right; 309 | padding: 7px; 310 | vertical-align: top; 311 | word-break: normal; 312 | width: 40px; } 313 | 314 | .slightly-smaller { 315 | font-size: 0.9em; } 316 | 317 | #footer { 318 | position: relative; 319 | top: 10px; 320 | bottom: 0px; 321 | margin-left: 25px; } 322 | #footer p { 323 | margin: 0; 324 | color: #aaa; 325 | font-size: 0.8em; } 326 | 327 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 328 | display: none; } 329 | 330 | html.dash .main-content { 331 | width: 980px; 332 | margin-left: 0; 333 | border: none; 334 | width: 100%; 335 | top: 0; 336 | padding-bottom: 0; } 337 | 338 | html.dash .height-container { 339 | display: block; } 340 | 341 | html.dash .item .token { 342 | margin-left: 0; } 343 | 344 | html.dash .content-wrapper { 345 | width: auto; } 346 | 347 | html.dash #footer { 348 | position: static; } 349 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/css/jazzy.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, h1, h3, h4, p, a, code, em, img, ul, li, table, tbody, tr, td { 2 | background: transparent; 3 | border: 0; 4 | margin: 0; 5 | outline: 0; 6 | padding: 0; 7 | vertical-align: baseline; } 8 | 9 | body { 10 | background-color: #f2f2f2; 11 | font-family: Helvetica, freesans, Arial, sans-serif; 12 | font-size: 14px; 13 | -webkit-font-smoothing: subpixel-antialiased; 14 | word-wrap: break-word; } 15 | 16 | h1, h2, h3 { 17 | margin-top: 0.8em; 18 | margin-bottom: 0.3em; 19 | font-weight: 100; 20 | color: black; } 21 | 22 | h1 { 23 | font-size: 2.5em; } 24 | 25 | h2 { 26 | font-size: 2em; 27 | border-bottom: 1px solid #e2e2e2; } 28 | 29 | h4 { 30 | font-size: 13px; 31 | line-height: 1.5; 32 | margin-top: 21px; } 33 | 34 | h5 { 35 | font-size: 1.1em; } 36 | 37 | h6 { 38 | font-size: 1.1em; 39 | color: #777; } 40 | 41 | .section-name { 42 | color: gray; 43 | display: block; 44 | font-family: Helvetica; 45 | font-size: 22px; 46 | font-weight: 100; 47 | margin-bottom: 15px; } 48 | 49 | pre, code { 50 | font: 0.95em Menlo, monospace; 51 | color: #777; 52 | word-wrap: normal; } 53 | 54 | p code, li code { 55 | background-color: #eee; 56 | padding: 2px 4px; 57 | border-radius: 4px; } 58 | 59 | a { 60 | color: #0088cc; 61 | text-decoration: none; } 62 | 63 | ul { 64 | padding-left: 15px; } 65 | 66 | li { 67 | line-height: 1.8em; } 68 | 69 | img { 70 | max-width: 100%; } 71 | 72 | blockquote { 73 | margin-left: 0; 74 | padding: 0 10px; 75 | border-left: 4px solid #ccc; } 76 | 77 | .content-wrapper { 78 | margin: 0 auto; 79 | width: 980px; } 80 | 81 | header { 82 | font-size: 0.85em; 83 | line-height: 26px; 84 | background-color: #414141; 85 | position: fixed; 86 | width: 100%; 87 | z-index: 1; } 88 | header img { 89 | padding-right: 6px; 90 | vertical-align: -4px; 91 | height: 16px; } 92 | header a { 93 | color: #fff; } 94 | header p { 95 | float: left; 96 | color: #999; } 97 | header .header-right { 98 | float: right; 99 | margin-left: 16px; } 100 | 101 | #breadcrumbs { 102 | background-color: #f2f2f2; 103 | height: 27px; 104 | padding-top: 17px; 105 | position: fixed; 106 | width: 100%; 107 | z-index: 1; 108 | margin-top: 26px; } 109 | #breadcrumbs #carat { 110 | height: 10px; 111 | margin: 0 5px; } 112 | 113 | .sidebar { 114 | background-color: #f9f9f9; 115 | border: 1px solid #e2e2e2; 116 | overflow-y: auto; 117 | overflow-x: hidden; 118 | position: fixed; 119 | top: 70px; 120 | bottom: 0; 121 | width: 230px; 122 | word-wrap: normal; } 123 | 124 | .nav-groups { 125 | list-style-type: none; 126 | background: #fff; 127 | padding-left: 0; } 128 | 129 | .nav-group-name { 130 | border-bottom: 1px solid #e2e2e2; 131 | font-size: 1.1em; 132 | font-weight: 100; 133 | padding: 15px 0 15px 20px; } 134 | .nav-group-name > a { 135 | color: #333; } 136 | 137 | .nav-group-tasks { 138 | margin-top: 5px; } 139 | 140 | .nav-group-task { 141 | font-size: 0.9em; 142 | list-style-type: none; 143 | white-space: nowrap; } 144 | .nav-group-task a { 145 | color: #888; } 146 | 147 | .main-content { 148 | background-color: #fff; 149 | border: 1px solid #e2e2e2; 150 | margin-left: 246px; 151 | position: absolute; 152 | overflow: hidden; 153 | padding-bottom: 20px; 154 | top: 70px; 155 | width: 734px; } 156 | .main-content p, .main-content a, .main-content code, .main-content em, .main-content ul, .main-content table, .main-content blockquote { 157 | margin-bottom: 1em; } 158 | .main-content p { 159 | line-height: 1.8em; } 160 | .main-content section .section:first-child { 161 | margin-top: 0; 162 | padding-top: 0; } 163 | .main-content section .task-group-section .task-group:first-of-type { 164 | padding-top: 10px; } 165 | .main-content section .task-group-section .task-group:first-of-type .section-name { 166 | padding-top: 15px; } 167 | .main-content section .heading:before { 168 | content: ""; 169 | display: block; 170 | padding-top: 70px; 171 | margin: -70px 0 0; } 172 | 173 | .section { 174 | padding: 0 25px; } 175 | 176 | .highlight { 177 | background-color: #eee; 178 | padding: 10px 12px; 179 | border: 1px solid #e2e2e2; 180 | border-radius: 4px; 181 | overflow-x: auto; } 182 | 183 | .declaration .highlight { 184 | overflow-x: initial; 185 | padding: 0 40px 40px 0; 186 | margin-bottom: -25px; 187 | background-color: transparent; 188 | border: none; } 189 | 190 | .section-name { 191 | margin: 0; 192 | margin-left: 18px; } 193 | 194 | .task-group-section { 195 | padding-left: 6px; 196 | border-top: 1px solid #e2e2e2; } 197 | 198 | .task-group { 199 | padding-top: 0px; } 200 | 201 | .task-name-container a[name]:before { 202 | content: ""; 203 | display: block; 204 | padding-top: 70px; 205 | margin: -70px 0 0; } 206 | 207 | .item { 208 | padding-top: 8px; 209 | width: 100%; 210 | list-style-type: none; } 211 | .item a[name]:before { 212 | content: ""; 213 | display: block; 214 | padding-top: 70px; 215 | margin: -70px 0 0; } 216 | .item code { 217 | background-color: transparent; 218 | padding: 0; } 219 | .item .token, .item .direct-link { 220 | padding-left: 3px; 221 | margin-left: 15px; 222 | font-size: 11.9px; 223 | transition: all 300ms; } 224 | .item .token-open { 225 | margin-left: 0px; } 226 | .item .discouraged { 227 | text-decoration: line-through; } 228 | .item .declaration-note { 229 | font-size: .85em; 230 | color: gray; 231 | font-style: italic; } 232 | 233 | .pointer-container { 234 | border-bottom: 1px solid #e2e2e2; 235 | left: -23px; 236 | padding-bottom: 13px; 237 | position: relative; 238 | width: 110%; } 239 | 240 | .pointer { 241 | background: #f9f9f9; 242 | border-left: 1px solid #e2e2e2; 243 | border-top: 1px solid #e2e2e2; 244 | height: 12px; 245 | left: 21px; 246 | top: -7px; 247 | -webkit-transform: rotate(45deg); 248 | -moz-transform: rotate(45deg); 249 | -o-transform: rotate(45deg); 250 | transform: rotate(45deg); 251 | position: absolute; 252 | width: 12px; } 253 | 254 | .height-container { 255 | display: none; 256 | left: -25px; 257 | padding: 0 25px; 258 | position: relative; 259 | width: 100%; 260 | overflow: hidden; } 261 | .height-container .section { 262 | background: #f9f9f9; 263 | border-bottom: 1px solid #e2e2e2; 264 | left: -25px; 265 | position: relative; 266 | width: 100%; 267 | padding-top: 10px; 268 | padding-bottom: 5px; } 269 | 270 | .aside, .language { 271 | padding: 6px 12px; 272 | margin: 12px 0; 273 | border-left: 5px solid #dddddd; 274 | overflow-y: hidden; } 275 | .aside .aside-title, .language .aside-title { 276 | font-size: 9px; 277 | letter-spacing: 2px; 278 | text-transform: uppercase; 279 | padding-bottom: 0; 280 | margin: 0; 281 | color: #aaa; 282 | -webkit-user-select: none; } 283 | .aside p:last-child, .language p:last-child { 284 | margin-bottom: 0; } 285 | 286 | .language { 287 | border-left: 5px solid #cde9f4; } 288 | .language .aside-title { 289 | color: #4b8afb; } 290 | 291 | .aside-warning, .aside-deprecated, .aside-unavailable { 292 | border-left: 5px solid #ff6666; } 293 | .aside-warning .aside-title, .aside-deprecated .aside-title, .aside-unavailable .aside-title { 294 | color: #ff0000; } 295 | 296 | .graybox { 297 | border-collapse: collapse; 298 | width: 100%; } 299 | .graybox p { 300 | margin: 0; 301 | word-break: break-word; 302 | min-width: 50px; } 303 | .graybox td { 304 | border: 1px solid #e2e2e2; 305 | padding: 5px 25px 5px 10px; 306 | vertical-align: middle; } 307 | .graybox tr td:first-of-type { 308 | text-align: right; 309 | padding: 7px; 310 | vertical-align: top; 311 | word-break: normal; 312 | width: 40px; } 313 | 314 | .slightly-smaller { 315 | font-size: 0.9em; } 316 | 317 | #footer { 318 | position: relative; 319 | top: 10px; 320 | bottom: 0px; 321 | margin-left: 25px; } 322 | #footer p { 323 | margin: 0; 324 | color: #aaa; 325 | font-size: 0.8em; } 326 | 327 | html.dash header, html.dash #breadcrumbs, html.dash .sidebar { 328 | display: none; } 329 | 330 | html.dash .main-content { 331 | width: 980px; 332 | margin-left: 0; 333 | border: none; 334 | width: 100%; 335 | top: 0; 336 | padding-bottom: 0; } 337 | 338 | html.dash .height-container { 339 | display: block; } 340 | 341 | html.dash .item .token { 342 | margin-left: 0; } 343 | 344 | html.dash .content-wrapper { 345 | width: auto; } 346 | 347 | html.dash #footer { 348 | position: static; } 349 | -------------------------------------------------------------------------------- /docs/Structs/SplitViewSnapPoint.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitViewSnapPoint Structure Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

SplitViewSnapPoint

65 |
66 |
67 |
public struct SplitViewSnapPoint : Equatable
68 | 69 |
70 |
71 |

A structure that contains a snap point that is percentage based and a tolerance for when to snap

72 | 73 |
74 |
75 |
76 |
    77 |
  • 78 |
    79 | 80 | 81 | 82 | percentage 83 | 84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 |

    The point at which to snap

    91 | 92 |
    93 |
    94 |

    Declaration

    95 |
    96 |

    Swift

    97 |
    public let percentage: CGFloat
    98 | 99 |
    100 |
    101 |
    102 | Show on GitHub 103 |
    104 |
    105 |
    106 |
  • 107 |
  • 108 |
    109 | 110 | 111 | 112 | tolerance 113 | 114 |
    115 |
    116 |
    117 |
    118 |
    119 |
    120 |

    The amount of range to induce a snap effects

    121 | 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    public let tolerance: CGFloat
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
  • 138 |
    139 | 140 | 141 | 142 | defaultTolerance 143 | 144 |
    145 |
    146 |
    147 |
    148 |
    149 |
    150 |

    The global default tolernace

    151 | 152 |
    153 |
    154 |

    Declaration

    155 |
    156 |

    Swift

    157 |
    public static var defaultTolerance: CGFloat
    158 | 159 |
    160 |
    161 |
    162 | Show on GitHub 163 |
    164 |
    165 |
    166 |
  • 167 |
168 |
169 |
170 |
171 | 175 |
176 |
177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/Structs/SplitViewSnapPoint.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitViewSnapPoint Structure Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

SplitViewSnapPoint

65 |
66 |
67 |
public struct SplitViewSnapPoint : Equatable
68 | 69 |
70 |
71 |

A structure that contains a snap point that is percentage based and a tolerance for when to snap

72 | 73 |
74 |
75 |
76 |
    77 |
  • 78 |
    79 | 80 | 81 | 82 | percentage 83 | 84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 |

    The point at which to snap

    91 | 92 |
    93 |
    94 |

    Declaration

    95 |
    96 |

    Swift

    97 |
    public let percentage: CGFloat
    98 | 99 |
    100 |
    101 |
    102 | Show on GitHub 103 |
    104 |
    105 |
    106 |
  • 107 |
  • 108 |
    109 | 110 | 111 | 112 | tolerance 113 | 114 |
    115 |
    116 |
    117 |
    118 |
    119 |
    120 |

    The amount of range to induce a snap effects

    121 | 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    public let tolerance: CGFloat
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
  • 138 |
    139 | 140 | 141 | 142 | defaultTolerance 143 | 144 |
    145 |
    146 |
    147 |
    148 |
    149 |
    150 |

    The global default tolernace

    151 | 152 |
    153 |
    154 |

    Declaration

    155 |
    156 |

    Swift

    157 |
    public static var defaultTolerance: CGFloat
    158 | 159 |
    160 |
    161 |
    162 | Show on GitHub 163 |
    164 |
    165 |
    166 |
  • 167 |
168 |
169 |
170 |
171 | 175 |
176 |
177 | 178 | 179 | 180 | -------------------------------------------------------------------------------- /docs/Enums/SplitViewSnapBehavior.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitViewSnapBehavior Enumeration Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

SplitViewSnapBehavior

65 |
66 |
67 |
public enum SplitViewSnapBehavior : Equatable
68 | 69 |
70 |
71 |

The specefied snap behavior

72 | 73 |
74 |
75 |
76 |
    77 |
  • 78 |
    79 | 80 | 81 | 82 | quarter 83 | 84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 |

    Snap every 25% (0%, 25%, 50%, 75%, 80%) with the default tolerance

    91 | 92 |
    93 |
    94 |

    Declaration

    95 |
    96 |

    Swift

    97 |
    case quarter
    98 | 99 |
    100 |
    101 |
    102 | Show on GitHub 103 |
    104 |
    105 |
    106 |
  • 107 |
  • 108 |
    109 | 110 | 111 | 112 | third 113 | 114 |
    115 |
    116 |
    117 |
    118 |
    119 |
    120 |

    Snap every 33% (0%, 33%, 66%, 100%) with a the default tolerance

    121 | 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    case third
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
  • 138 |
    139 | 140 | 141 | 142 | custom(percentage:tolerance:) 143 | 144 |
    145 |
    146 |
    147 |
    148 |
    149 |
    150 |

    Snap at a given percentage and tolerance

    151 | 152 |
    153 |
    154 |

    Declaration

    155 |
    156 |

    Swift

    157 |
    case custom(percentage: CGFloat, tolerance: CGFloat)
    158 | 159 |
    160 |
    161 |
    162 | Show on GitHub 163 |
    164 |
    165 |
    166 |
  • 167 |
  • 168 |
    169 | 170 | 171 | 172 | withPoint(_:) 173 | 174 |
    175 |
    176 |
    177 |
    178 |
    179 |
    180 |

    Snap at a given SnapPoint

    181 | 182 |
    183 |
    184 |

    Declaration

    185 |
    186 |

    Swift

    187 |
    case withPoint(SplitViewSnapPoint)
    188 | 189 |
    190 |
    191 |
    192 | Show on GitHub 193 |
    194 |
    195 |
    196 |
  • 197 |
  • 198 |
    199 | 200 | 201 | 202 | withPoints(_:) 203 | 204 |
    205 |
    206 |
    207 |
    208 |
    209 |
    210 |

    Snap at the given SnapPoints

    211 | 212 |
    213 |
    214 |

    Declaration

    215 |
    216 |

    Swift

    217 |
    case withPoints([SplitViewSnapPoint])
    218 | 219 |
    220 |
    221 |
    222 | Show on GitHub 223 |
    224 |
    225 |
    226 |
  • 227 |
228 |
229 |
230 |
231 | 235 |
236 |
237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /docs/docsets/SplitView.docset/Contents/Resources/Documents/Enums/SplitViewSnapBehavior.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitViewSnapBehavior Enumeration Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

SplitViewSnapBehavior

65 |
66 |
67 |
public enum SplitViewSnapBehavior : Equatable
68 | 69 |
70 |
71 |

The specefied snap behavior

72 | 73 |
74 |
75 |
76 |
    77 |
  • 78 |
    79 | 80 | 81 | 82 | quarter 83 | 84 |
    85 |
    86 |
    87 |
    88 |
    89 |
    90 |

    Snap every 25% (0%, 25%, 50%, 75%, 80%) with the default tolerance

    91 | 92 |
    93 |
    94 |

    Declaration

    95 |
    96 |

    Swift

    97 |
    case quarter
    98 | 99 |
    100 |
    101 |
    102 | Show on GitHub 103 |
    104 |
    105 |
    106 |
  • 107 |
  • 108 |
    109 | 110 | 111 | 112 | third 113 | 114 |
    115 |
    116 |
    117 |
    118 |
    119 |
    120 |

    Snap every 33% (0%, 33%, 66%, 100%) with a the default tolerance

    121 | 122 |
    123 |
    124 |

    Declaration

    125 |
    126 |

    Swift

    127 |
    case third
    128 | 129 |
    130 |
    131 |
    132 | Show on GitHub 133 |
    134 |
    135 |
    136 |
  • 137 |
  • 138 |
    139 | 140 | 141 | 142 | custom(percentage:tolerance:) 143 | 144 |
    145 |
    146 |
    147 |
    148 |
    149 |
    150 |

    Snap at a given percentage and tolerance

    151 | 152 |
    153 |
    154 |

    Declaration

    155 |
    156 |

    Swift

    157 |
    case custom(percentage: CGFloat, tolerance: CGFloat)
    158 | 159 |
    160 |
    161 |
    162 | Show on GitHub 163 |
    164 |
    165 |
    166 |
  • 167 |
  • 168 |
    169 | 170 | 171 | 172 | withPoint(_:) 173 | 174 |
    175 |
    176 |
    177 |
    178 |
    179 |
    180 |

    Snap at a given SnapPoint

    181 | 182 |
    183 |
    184 |

    Declaration

    185 |
    186 |

    Swift

    187 |
    case withPoint(SplitViewSnapPoint)
    188 | 189 |
    190 |
    191 |
    192 | Show on GitHub 193 |
    194 |
    195 |
    196 |
  • 197 |
  • 198 |
    199 | 200 | 201 | 202 | withPoints(_:) 203 | 204 |
    205 |
    206 |
    207 |
    208 |
    209 |
    210 |

    Snap at the given SnapPoints

    211 | 212 |
    213 |
    214 |

    Declaration

    215 |
    216 |

    Swift

    217 |
    case withPoints([SplitViewSnapPoint])
    218 | 219 |
    220 |
    221 |
    222 | Show on GitHub 223 |
    224 |
    225 |
    226 |
  • 227 |
228 |
229 |
230 |
231 | 235 |
236 |
237 | 238 | 239 | 240 | -------------------------------------------------------------------------------- /SplitView/SplitView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SplitStackView.swift 3 | // ec3730 4 | // 5 | // Created by Zachary Gorak on 8/20/19. 6 | // Copyright © 2019 Zachary Gorak. All rights reserved. 7 | // 8 | // swiftlint:disable all 9 | import Foundation 10 | import UIKit 11 | 12 | 13 | extension CGFloat 14 | { 15 | /// https://stackoverflow.com/questions/35946499/how-to-truncate-decimals-to-x-places-in-swift 16 | func truncate(places : Int)-> CGFloat 17 | { 18 | return CGFloat(floor(pow(10.0, CGFloat(places)) * self)/pow(10.0, CGFloat(places))) 19 | } 20 | } 21 | 22 | /// Resizable Split View, inspired by [Apple’s Split View](https://support.apple.com/en-us/HT207582#split) for iPadOS and [SplitKit](https://github.com/macteo/SplitKit) 23 | open class SplitView: UIView { 24 | // MARK: - Properties 25 | // MARK: Private and internal 26 | private let stack = UIStackView() 27 | 28 | /// The list of supporting views split by the split view 29 | internal var splitSupportingViews = [SplitSupportingView]() 30 | 31 | // MARK: Public 32 | 33 | /// The list of views split by the split view. 34 | public var splitSubviews: [UIView] { 35 | return self.splitSupportingViews.compactMap({ $0.view }) 36 | } 37 | /// The handles between views 38 | public var handles = [SplitViewHandle]() 39 | 40 | /// The minimum width/height ratio for each view 41 | /// 42 | /// The default is 0.0 43 | public var minimumRatio: CGFloat { 44 | didSet { 45 | self.update() 46 | } 47 | } 48 | /// The animation duration when resizing views 49 | /// 50 | /// If you specify a negative value or 0, the changes are made without animating them. 51 | /// The default is 0.0 seconds 52 | public var animationDuration: TimeInterval = 0.0 53 | 54 | /// The precision of the movements. 1 is every 10%, 2 is every 1%, etc 55 | /// 56 | /// The default is 5 57 | public var precision = 5 58 | 59 | /// Snap Behavior 60 | public var snap = [SplitViewSnapBehavior]() { 61 | didSet { 62 | self.update() 63 | } 64 | } 65 | 66 | /// The axis along which the split views are laid out. 67 | /// 68 | /// This property determines the orientation of the split views. 69 | /// Assigning the `NSLayoutConstraint.Axis.vertical` value creates a column of views. 70 | /// Assigning the `NSLayoutConstraint.Axis.horizontal` value creates a row. 71 | /// The default value is `NSLayoutConstraint.Axis.horizontal`. 72 | public var axis: NSLayoutConstraint.Axis { 73 | didSet { 74 | self.update() 75 | } 76 | } 77 | 78 | // MARK: - Initializers 79 | 80 | public override init(frame: CGRect) { 81 | self.minimumRatio = 0.0 82 | self.axis = .horizontal 83 | 84 | super.init(frame: frame) 85 | 86 | stack.translatesAutoresizingMaskIntoConstraints = false 87 | stack.distribution = .fill 88 | stack.spacing = 0.0 89 | stack.alignment = .fill 90 | stack.axis = self.axis 91 | 92 | self.addSubview(stack) 93 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[stack]|", options: .alignAllCenterY, metrics: nil, views: ["stack": stack])) 94 | self.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[stack]|", options: .alignAllCenterY, metrics: nil, views: ["stack": stack])) 95 | } 96 | 97 | public convenience init() { 98 | self.init(frame: .zero) 99 | self.translatesAutoresizingMaskIntoConstraints = false 100 | } 101 | 102 | /// Returns a new split view object that manages the provided views. 103 | /// - parameters: 104 | /// - splitSubviews: The views to be split by the split view. 105 | public convenience init(splitSubviews: [UIView]) { 106 | self.init(frame: .zero) 107 | 108 | for view in splitSubviews { 109 | view.translatesAutoresizingMaskIntoConstraints = false 110 | self.addSplitSubview(view) 111 | } 112 | } 113 | 114 | /// Not implemented 115 | required public init?(coder aDecoder: NSCoder) { 116 | fatalError("init(coder:) has not been implemented") 117 | } 118 | 119 | // MARK: - View Handling 120 | 121 | private func addHandle(_ handle: SplitViewHandle, at: Int) { 122 | handle.axis = self.axis 123 | handle.translatesAutoresizingMaskIntoConstraints = false 124 | handles.append(handle) // XXX: make sure this is in the right order 125 | stack.insertArrangedSubview(handle, at: at) 126 | 127 | let gesture = UIPanGestureRecognizer(target: self, action: #selector(panHandle(_:))) 128 | handle.addGestureRecognizer(gesture) 129 | } 130 | 131 | /// Adds a view to the end of the splitSupportingViews array 132 | @available(swift, introduced: 1.3.0) 133 | open func addSplitSubview(_ view: UIView, desiredRatio: CGFloat = 0.5, minimumRatio: CGFloat = 0.0, withHandle: SplitViewHandle? = nil) { 134 | self.insertSplitSubview(view, at: self.splitSupportingViews.count, desiredRatio: desiredRatio, minimumRatio: minimumRatio, withHandle: withHandle) 135 | } 136 | 137 | /// Adds the provided view to the array of split subviews at the specified index. 138 | open func insertSplitSubview(_ view: UIView, at: Int, desiredRatio: CGFloat = 0.5, minimumRatio: CGFloat = 0.0, withHandle: SplitViewHandle? = nil) { 139 | precondition(desiredRatio >= 0.0, "Ratio must be greater than zero") 140 | precondition(desiredRatio <= 1.0, "Ratio must be less than one") 141 | 142 | var insertAtIndex = at 143 | 144 | view.translatesAutoresizingMaskIntoConstraints = false 145 | 146 | let beforeSize = splitSupportingViews.count 147 | 148 | let organizer = SplitSupportingView(view: view, ratio: desiredRatio, minRatio: minimumRatio, constraint: nil) 149 | splitSupportingViews.insert(organizer, at: at) 150 | 151 | if beforeSize != 0 && at >= beforeSize { 152 | let handle = withHandle ?? SplitViewHandle.useDefault() 153 | insertAtIndex = self.stack.arrangedSubviews.count 154 | self.addHandle(handle, at: insertAtIndex) 155 | insertAtIndex += 1 156 | } 157 | 158 | stack.insertArrangedSubview(organizer.view, at: insertAtIndex) 159 | 160 | if beforeSize != 0 && at < beforeSize { 161 | let handle = withHandle ?? SplitViewHandle.useDefault() 162 | self.addHandle(handle, at: insertAtIndex + 1) 163 | } 164 | 165 | self.assignRatios(newRatio: self.ratio(given: desiredRatio, for: organizer), for: at) 166 | self.setRatios() 167 | } 168 | 169 | /// Removes the provided view from the stack’s array of split subviews. 170 | open func removeSplitSubview(_ view: UIView) { 171 | guard let index = self.splitSubviews.firstIndex(of: view) else { 172 | return 173 | } 174 | 175 | let organizer = splitSupportingViews.remove(at: index) 176 | 177 | stack.removeArrangedSubview(organizer.view) 178 | organizer.view.removeFromSuperview() 179 | 180 | if handles.count > 0 { 181 | let handle = self.handles.remove(at: max(index-1,0)) 182 | stack.removeArrangedSubview(handle) 183 | handle.removeFromSuperview() 184 | } 185 | 186 | self.setRatios() 187 | } 188 | 189 | /// Add a view to your `SplitView` 190 | @available(swift, deprecated: 1.3.0, obsoleted: 2.0.0, renamed: "addSplitSubview") 191 | open func addView(_ view: UIView, ratio: CGFloat = 0.5, minRatio: CGFloat = 0.0, withHandle: SplitViewHandle? = nil) { 192 | self.addSplitSubview(view, desiredRatio: ratio, minimumRatio: minRatio, withHandle: withHandle) 193 | } 194 | 195 | private func update() { 196 | self.stack.axis = self.axis 197 | 198 | for handle in self.handles { 199 | handle.axis = self.axis 200 | } 201 | 202 | self.setRatios() 203 | 204 | UIView.animate(withDuration: self.animationDuration) { 205 | self.layoutIfNeeded() 206 | } 207 | } 208 | 209 | private func setRatios() { 210 | let minimumRatioToHoldHandle: CGFloat = 0.01 211 | let totalHandleSize: CGFloat = handles.reduce(0.0) { $0 + $1.size } 212 | let count = splitSupportingViews.filter({ $0.ratio > minimumRatioToHoldHandle }).count 213 | 214 | let handleConstant = totalHandleSize/CGFloat(count) 215 | 216 | let original_constraints = splitSupportingViews.compactMap({$0.constraint}) 217 | 218 | for (i, view) in splitSupportingViews.enumerated() { 219 | // using greaterThanOrEqual and lesser ratio to ignore rounding errors 220 | // also subtracting 0.01 to fix rounding errors 221 | 222 | let constant = view.ratio > minimumRatioToHoldHandle ? -handleConstant: 0.0 223 | let ratio = max(view.ratio, 0.0) 224 | 225 | if self.axis == .vertical { 226 | splitSupportingViews[i].constraint = NSLayoutConstraint(item: splitSupportingViews[i].view, attribute: .height, relatedBy: .greaterThanOrEqual, toItem: stack, attribute: .height, multiplier: ratio, constant: constant) 227 | } else { 228 | splitSupportingViews[i].constraint = NSLayoutConstraint(item: splitSupportingViews[i].view, attribute: .width, relatedBy: .greaterThanOrEqual, toItem: stack, attribute: .width, multiplier: ratio, constant: constant) 229 | } 230 | } 231 | 232 | let new_constraints = splitSupportingViews.compactMap({$0.constraint}) 233 | 234 | NSLayoutConstraint.deactivate(original_constraints) 235 | NSLayoutConstraint.activate(new_constraints) 236 | } 237 | 238 | private func ratio(given ratio: CGFloat, for organizer: SplitSupportingView)->CGFloat { 239 | if splitSupportingViews.count == 1 { 240 | return 1.0 241 | } 242 | 243 | var minRatio: CGFloat = 0.0 244 | for view in splitSupportingViews { 245 | if view == organizer { 246 | continue 247 | } 248 | minRatio += max(minimumRatio, view.minRatio) 249 | } 250 | if ratio >= 1.0 { 251 | return 1.0 - minRatio 252 | } 253 | 254 | let curMinRatio = max(minimumRatio, organizer.minRatio) 255 | 256 | if ratio <= curMinRatio { 257 | return curMinRatio 258 | } 259 | 260 | if ratio < curMinRatio { 261 | return curMinRatio 262 | } 263 | 264 | if ratio + minRatio >= 1.0 { 265 | return ratio - (ratio + minRatio - 1.0) 266 | } 267 | 268 | return ratio 269 | } 270 | 271 | private func assignRatios(newRatio: CGFloat, for index: Int) { 272 | var ratio = newRatio 273 | 274 | var maxRatio: CGFloat = 1.0 275 | 276 | if splitSupportingViews.count == 1 { 277 | splitSupportingViews[0].ratio = maxRatio 278 | return 279 | } 280 | 281 | for snapBehavior in self.snap { 282 | for point in snapBehavior.snapPoints { 283 | if ratio > (point.percentage - point.tolerance) && ratio < (point.percentage + point.tolerance) { 284 | ratio = point.percentage 285 | } 286 | } 287 | } 288 | 289 | var closestIndex = index == 0 ? 1 : 0 290 | 291 | if splitSupportingViews.count > 2 { 292 | // the handle controls this view and the view above 293 | closestIndex = index + 1 294 | if closestIndex >= splitSupportingViews.count { 295 | closestIndex = index - 1 296 | } 297 | 298 | // XXX: use reducers 299 | var ratioTotal: CGFloat = 0.0 300 | for (i, support) in splitSupportingViews.enumerated() { 301 | if i == index || i == closestIndex { 302 | continue 303 | } 304 | ratioTotal += support.ratio 305 | } 306 | maxRatio = maxRatio - ratioTotal 307 | } 308 | 309 | var secondRatio = (maxRatio - ratio) 310 | 311 | let secondSmallestRatio = max(self.minimumRatio, splitSupportingViews[closestIndex].minRatio) 312 | if secondRatio < secondSmallestRatio { 313 | secondRatio = secondSmallestRatio 314 | ratio = maxRatio - secondRatio 315 | } 316 | 317 | ratio = ratio.truncate(places: self.precision) 318 | secondRatio = secondRatio.truncate(places: self.precision) 319 | 320 | splitSupportingViews[index].ratio = ratio 321 | splitSupportingViews[closestIndex].ratio = secondRatio 322 | } 323 | 324 | @objc func panHandle(_ sender: UIPanGestureRecognizer) { 325 | guard let handle = sender.view as? SplitViewHandle else { 326 | return 327 | } 328 | 329 | guard let handleIndex = handles.firstIndex(of: handle) else { 330 | return 331 | } 332 | 333 | let organizer = splitSupportingViews[handleIndex] 334 | 335 | switch sender.state { 336 | case .began: 337 | handle.initialOrigin = handle.frame.origin 338 | handle.isBeingUsed = true 339 | break 340 | case .changed: 341 | var newPoint = handle.initialOrigin!.y + sender.translation(in: handle).y 342 | var curPoint = handle.frame.origin.y 343 | if self.axis == .horizontal { 344 | newPoint = handle.initialOrigin!.x + sender.translation(in: handle).x 345 | curPoint = handle.frame.origin.x 346 | } 347 | 348 | var ratio: CGFloat = 0.0 349 | if curPoint != 0 { 350 | if organizer.ratio <= 0 { 351 | ratio = max(0.0, (newPoint/curPoint) - 1.0) 352 | } else { 353 | ratio = organizer.ratio * (newPoint/curPoint) 354 | } 355 | } else { 356 | ratio = newPoint/stack.frame.height 357 | if self.axis == .horizontal { 358 | ratio = newPoint/stack.frame.width 359 | } 360 | 361 | ratio = max(ratio, self.minimumRatio) 362 | } 363 | 364 | splitSupportingViews[handleIndex].ratio = self.ratio(given: max(ratio, splitSupportingViews[handleIndex].minRatio), for: splitSupportingViews[handleIndex]) 365 | self.assignRatios(newRatio: splitSupportingViews[handleIndex].ratio, for: handleIndex) 366 | 367 | self.setRatios() 368 | UIView.animate(withDuration: self.animationDuration) { 369 | self.layoutIfNeeded() 370 | } 371 | 372 | break 373 | case .ended: 374 | handle.isBeingUsed = false 375 | handle.initialOrigin = nil 376 | default: 377 | break 378 | } 379 | } 380 | } 381 | 382 | // MARK: - Ratio 383 | extension SplitView { 384 | /// The current ratio for all the split subviews 385 | public var ratios: [CGFloat] { 386 | return self.splitSupportingViews.compactMap({ $0.ratio }) 387 | } 388 | 389 | /// The minimum ratios for all the split subviews 390 | public var minimumRatios: [CGFloat] { 391 | return self.splitSupportingViews.compactMap({ $0.minRatio }) 392 | } 393 | 394 | /// Set the minimum ratio for a specific view 395 | public func setMinimumRatio(_ ratio: CGFloat, for view: UIView) { 396 | precondition(minimumRatio >= 0.0, "Ratio must be 0.0 or greater") 397 | precondition(minimumRatio < 1.0, "Ratio must be less than 1.0") 398 | 399 | guard let index = self.splitSubviews.firstIndex(of: view) else { 400 | return 401 | } 402 | 403 | self.splitSupportingViews[index].minRatio = ratio 404 | } 405 | } 406 | 407 | // MARK: - Stack 408 | 409 | extension SplitView { 410 | /// A Boolean value that determines whether the split view lays out its split views relative to 411 | /// its layout margins. 412 | /// 413 | /// If `true`, the stack view will layout its split views relative to its layout margins. 414 | /// If `false`, it lays out the split views relative to its bounds. The default is `false`. 415 | public var isLayoutMarginsRelativeArrangement: Bool { 416 | set { 417 | stack.isLayoutMarginsRelativeArrangement = newValue 418 | } 419 | get { 420 | return stack.isLayoutMarginsRelativeArrangement 421 | } 422 | } 423 | } 424 | -------------------------------------------------------------------------------- /docs/Classes/SplitViewHandle.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SplitViewHandle Class Reference 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |

SplitView '2.0.0' Docs (95% documented)

18 |

View on GitHub

19 |

Install in Dash

20 |
21 |
22 |
23 | 28 |
29 |
30 | 61 |
62 |
63 |
64 |

SplitViewHandle

65 |
66 |
67 |
open class SplitViewHandle : UIView
68 | 69 |
70 |
71 |

The seperator/handle that is between each view in a SplitView

72 | 73 |
74 |
75 |
76 |
77 | 78 | 79 | 80 |

Public

81 |
82 |
83 |
    84 |
  • 85 |
    86 | 87 | 88 | 89 | grabber 90 | 91 |
    92 |
    93 |
    94 |
    95 |
    96 |
    97 |

    The center view used for grabbing

    98 | 99 |
    100 |
    101 |

    Declaration

    102 |
    103 |

    Swift

    104 |
    public var grabber: UIView
    105 | 106 |
    107 |
    108 |
    109 | Show on GitHub 110 |
    111 |
    112 |
    113 |
  • 114 |
  • 115 |
    116 | 117 | 118 | 119 | size 120 | 121 |
    122 |
    123 |
    124 |
    125 |
    126 |
    127 |

    The width/height of the view

    128 | 129 |
    130 |
    131 |

    Declaration

    132 |
    133 |

    Swift

    134 |
    public var size: CGFloat
    135 | 136 |
    137 |
    138 |
    139 | Show on GitHub 140 |
    141 |
    142 |
    143 |
  • 144 |
  • 145 |
    146 | 147 | 148 | 149 | initialOrigin 150 | 151 |
    152 |
    153 |
    154 |
    155 |
    156 |
    157 |

    Used for position tracking

    158 | 159 |
    160 |
    161 |

    Declaration

    162 |
    163 |

    Swift

    164 |
    public var initialOrigin: CGPoint?
    165 | 166 |
    167 |
    168 |
    169 | Show on GitHub 170 |
    171 |
    172 |
    173 |
  • 174 |
  • 175 |
    176 | 177 | 178 | 179 | isBeingUsed 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 |
    187 | 188 |
    189 |
    190 |

    Declaration

    191 |
    192 |

    Swift

    193 |
    public var isBeingUsed: Bool
    194 | 195 |
    196 |
    197 |
    198 |

    Return Value

    199 |

    If being dragged returns true, false otherwise

    200 |
    201 |
    202 | Show on GitHub 203 |
    204 |
    205 |
    206 |
  • 207 |
  • 208 |
    209 | 210 | 211 | 212 | axis 213 | 214 |
    215 |
    216 |
    217 |
    218 |
    219 |
    220 |

    This property determines the orientation of the arranged views. 221 | Assigning the NSLayoutConstraint.Axis.vertical value creates a column of views. 222 | Assigning the NSLayoutConstraint.Axis.horizontal value creates a row.

    223 | 224 |
    225 |
    226 |

    Declaration

    227 |
    228 |

    Swift

    229 |
    public var axis: NSLayoutConstraint.Axis { get set }
    230 | 231 |
    232 |
    233 |
    234 | Show on GitHub 235 |
    236 |
    237 |
    238 |
  • 239 |
  • 240 |
    241 | 242 | 243 | 244 | handleConstraints 245 | 246 |
    247 |
    248 |
    249 |
    250 |
    251 |
    252 |

    The current constraints on the handle 253 | This is used when changing axises and should only be modified 254 | when overriding

    255 | 256 |
    257 |
    258 |

    Declaration

    259 |
    260 |

    Swift

    261 |
    public var handleConstraints: [NSLayoutConstraint]
    262 | 263 |
    264 |
    265 |
    266 | Show on GitHub 267 |
    268 |
    269 |
    270 |
  • 271 |
272 |
273 |
274 |
275 | 276 | 277 | 278 |

Initilizers

279 |
280 |
281 |
    282 |
  • 283 |
    284 | 285 | 286 | 287 | init(coder:) 288 | 289 |
    290 |
    291 |
    292 |
    293 |
    294 |
    295 |

    Not implemented

    296 | 297 |
    298 |
    299 |

    Declaration

    300 |
    301 |

    Swift

    302 |
    required public init?(coder aDecoder: NSCoder)
    303 | 304 |
    305 |
    306 |
    307 | Show on GitHub 308 |
    309 |
    310 |
    311 |
  • 312 |
313 |
314 |
315 |
316 | 317 | 318 | 319 |

View Handling

320 |
321 |
322 |
    323 |
  • 324 |
    325 | 326 | 327 | 328 | layoutConstraints() 329 | 330 |
    331 |
    332 |
    333 |
    334 |
    335 |
    336 |

    Override this if you are cusomizing your seperator/handle 337 | Use handleConstraints as necessary

    338 | 339 |
    340 |
    341 |

    Declaration

    342 |
    343 |

    Swift

    344 |
    open func layoutConstraints()
    345 | 346 |
    347 |
    348 |
    349 | Show on GitHub 350 |
    351 |
    352 |
    353 |
  • 354 |
355 |
356 |
357 |
358 | 359 | 360 | 361 |

Default

362 |
363 |
364 |
    365 |
  • 366 |
    367 | 368 | 369 | 370 | useDefault() 371 | 372 |
    373 |
    374 |
    375 |
    376 |
    377 |
    378 |

    The default handle.

    379 | 380 |
    381 |
    382 |

    Declaration

    383 |
    384 |

    Swift

    385 |
    public class func useDefault() -> SplitViewHandle
    386 | 387 |
    388 |
    389 |
    390 | Show on GitHub 391 |
    392 |
    393 |
    394 |
  • 395 |
396 |
397 |
398 |
399 | 403 |
404 |
405 | 406 | 407 | 408 | --------------------------------------------------------------------------------