├── SETabView ├── Assets │ └── .gitkeep └── Classes │ └── .gitkeep ├── _Pods.xcodeproj ├── .build ├── manifest.db └── x86_64-apple-macosx │ ├── build.db │ └── debug │ ├── index │ └── store │ │ └── v5 │ │ ├── units │ │ ├── Helper.swift.o-1NF4RD9PFTAOH │ │ ├── SETabView.swift.o-28S4YQEOK5OZW │ │ ├── x86_64.swiftinterface-1DZ86EJZP8AVR │ │ └── SEViewController.swift.o-3D0K590ERCMIZ │ │ └── records │ │ ├── 20 │ │ └── Helper.swift-4H91YLBIVH20 │ │ ├── 31 │ │ └── SETabView.swift-D361JZ1WW31 │ │ ├── JF │ │ └── x86_64.swiftinterface-3CXT5LB78S3JF │ │ ├── G3 │ │ └── x86_64.swiftinterface_C-34WRX7VVQ15G3 │ │ ├── I7 │ │ └── SEViewController.swift-3EJQHSB645VI7 │ │ ├── 5S │ │ └── x86_64.swiftinterface_Misc-2QOU950HNIW5S │ │ ├── H0 │ │ └── x86_64.swiftinterface_Bool-40OL09C2T2H0 │ │ ├── S1 │ │ └── x86_64.swiftinterface_Math-1AQNC3D9CLDS1 │ │ ├── 3S │ │ └── x86_64.swiftinterface_Assert-V65YNMTP6C3S │ │ ├── 5Q │ │ └── x86_64.swiftinterface_String-H3HH1CSS8L5Q │ │ ├── B9 │ │ └── x86_64.swiftinterface_Hashing-1Y4B2U6G2NXB9 │ │ ├── DW │ │ └── x86_64.swiftinterface_Result-2AQN7BFZ1PVDW │ │ ├── L2 │ │ └── x86_64.swiftinterface_Optional-4I9DUJ3SK1L2 │ │ ├── P1 │ │ └── x86_64.swiftinterface_Pointer-QCJI3XVI5BP1 │ │ ├── PZ │ │ └── x86_64.swiftinterface_KeyPaths-H0WDHRNCUMPZ │ │ ├── VC │ │ └── x86_64.swiftinterface_Protocols-MCM8WJEDZ1VC │ │ ├── 0B │ │ └── x86_64.swiftinterface_Playground-2BDEY5WTUT30B │ │ ├── 3N │ │ └── x86_64.swiftinterface_Math_Integers-4FZ39UT9YN3N │ │ ├── BA │ │ └── x86_64.swiftinterface_Collection-1OOHYK7IC0VBA │ │ ├── P0 │ │ └── x86_64.swiftinterface_Reflection-2VIZ2H1FZUHP0 │ │ ├── Z6 │ │ └── x86_64.swiftinterface_Math_Vector-PNCOG8ZHQNZ6 │ │ ├── 1I │ │ └── x86_64.swiftinterface_Math_Integers-1KOR3A56TZW1I │ │ ├── PQ │ │ └── x86_64.swiftinterface_Math_Floating-1X1Z0YAIY8APQ │ │ ├── SK │ │ └── x86_64.swiftinterface_Collection_Array-1GZF7D7LHZVSK │ │ ├── BJ │ │ └── x86_64.swiftinterface_Collection_Type-erased-2GDE9N2H0B8BJ │ │ ├── KD │ │ └── x86_64.swiftinterface_Collection_Lazy_Views-3MDMH5FHKI4KD │ │ └── DX │ │ └── x86_64.swiftinterface_Collection_HashedCollections-29A182UK5FQDX │ ├── ModuleCache │ ├── 37NUFZOP9ZAD7 │ │ └── SwiftShims-2DA6NLEWJC11R.pcm │ ├── Swift-39YYAJQGEAJ2E.swiftmodule │ └── SwiftOnoneSupport-2RFMDLM7SUFB5.swiftmodule │ ├── SETabView.build │ ├── module.modulemap │ ├── master.swiftdeps │ ├── master.swiftdeps~moduleonly │ ├── Helper.d │ ├── output-file-map.json │ ├── Helper.swiftdeps │ ├── SETabView.d │ └── SEViewController.d │ ├── description.json │ └── SETabViewPackageTests.product │ └── Objects.LinkFileList ├── Gifs ├── HoleBall1.gif ├── HoleBall2.gif └── HoleBall3.gif ├── Example ├── SETabView │ ├── Images.xcassets │ │ ├── Contents.json │ │ ├── fifth.imageset │ │ │ ├── 031-death.png │ │ │ └── Contents.json │ │ ├── third.imageset │ │ │ ├── 011-mummy.png │ │ │ └── Contents.json │ │ ├── first.imageset │ │ │ ├── 029-dracula.png │ │ │ └── Contents.json │ │ ├── second.imageset │ │ │ ├── 030-devil.png │ │ │ └── Contents.json │ │ ├── fourth.imageset │ │ │ ├── 021-frankenstein.png │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── FifthViewController.swift │ ├── ThirdViewController.swift │ ├── FirstViewController.swift │ ├── FourthViewController.swift │ ├── SecondViewController.swift │ ├── ViewController.swift │ ├── Info.plist │ ├── AppDelegate.swift │ └── Base.lproj │ │ └── LaunchScreen.xib ├── Pods │ ├── Target Support Files │ │ ├── SETabView │ │ │ ├── SETabView.modulemap │ │ │ ├── SETabView-dummy.m │ │ │ ├── SETabView-prefix.pch │ │ │ ├── SETabView-umbrella.h │ │ │ ├── SETabView.debug.xcconfig │ │ │ ├── SETabView.release.xcconfig │ │ │ └── SETabView-Info.plist │ │ ├── Pods-SETabView_Tests │ │ │ ├── Pods-SETabView_Tests.modulemap │ │ │ ├── Pods-SETabView_Tests-acknowledgements.markdown │ │ │ ├── Pods-SETabView_Tests-dummy.m │ │ │ ├── Pods-SETabView_Tests-umbrella.h │ │ │ ├── Pods-SETabView_Tests.debug.xcconfig │ │ │ ├── Pods-SETabView_Tests.release.xcconfig │ │ │ ├── Pods-SETabView_Tests-Info.plist │ │ │ └── Pods-SETabView_Tests-acknowledgements.plist │ │ └── Pods-SETabView_Example │ │ │ ├── Pods-SETabView_Example.modulemap │ │ │ ├── Pods-SETabView_Example-dummy.m │ │ │ ├── Pods-SETabView_Example-umbrella.h │ │ │ ├── Pods-SETabView_Example.debug.xcconfig │ │ │ ├── Pods-SETabView_Example.release.xcconfig │ │ │ ├── Pods-SETabView_Example-Info.plist │ │ │ ├── Pods-SETabView_Example-acknowledgements.markdown │ │ │ └── Pods-SETabView_Example-acknowledgements.plist │ ├── Pods.xcodeproj │ │ └── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── Manifest.lock │ └── Local Podspecs │ │ └── SETabView.podspec.json ├── Podfile ├── SETabView.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── SETabView-Example.xcscheme ├── SETabView.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── Podfile.lock └── Tests │ ├── Info.plist │ └── Tests.swift ├── Tests ├── LinuxMain.swift └── SETabViewTests │ ├── XCTestManifests.swift │ └── SETabViewTests.swift ├── .swiftpm └── xcode │ └── package.xcworkspace │ └── contents.xcworkspacedata ├── Source ├── ViewControllers │ ├── SETabItemProvider.swift │ └── AnimatedTabViewDelegate.swift ├── Utilities │ ├── SETimingFunctions.swift │ ├── AnimationType.swift │ ├── SETabSettings.swift │ └── SELayerAnimationProvider.swift ├── OrderedCollections │ ├── OrderedSet │ │ ├── OrderedSet+CustomReflectable.swift │ │ ├── OrderedSet+Hashable.swift │ │ ├── OrderedSet+Equatable.swift │ │ ├── OrderedSet+CustomStringConvertible.swift │ │ ├── OrderedSet+CustomDebugStringConvertible.swift │ │ ├── OrderedSet+ExpressibleByArrayLiteral.swift │ │ ├── OrderedSet+UnstableInternals.swift │ │ ├── OrderedSet+Codable.swift │ │ ├── OrderedSet+Invariants.swift │ │ ├── OrderedSet+Partial SetAlgebra+Basics.swift │ │ ├── OrderedSet+Testing.swift │ │ ├── OrderedSet+Diffing.swift │ │ ├── OrderedSet+ReserveCapacity.swift │ │ └── OrderedSet+Initializers.swift │ ├── OrderedDictionary │ │ ├── OrderedDictionary+CustomReflectable.swift │ │ ├── OrderedDictionary+Invariants.swift │ │ ├── OrderedDictionary+Hashable.swift │ │ ├── OrderedDictionary+CustomStringConvertible.swift │ │ ├── OrderedDictionary+Equatable.swift │ │ ├── OrderedDictionary+ExpressibleByDictionaryLiteral.swift │ │ ├── OrderedDictionary+CustomDebugStringConvertible.swift │ │ ├── OrderedDictionary+Deprecations.swift │ │ ├── OrderedDictionary+Sequence.swift │ │ ├── OrderedDictionary+Codable.swift │ │ ├── OrderedDictionary+Partial RangeReplaceableCollection.swift │ │ └── OrderedDictionary+Partial MutableCollection.swift │ ├── Utilities │ │ └── RandomAccessCollection+Offsets.swift │ ├── HashTable │ │ ├── _HashTable+Bucket.swift │ │ ├── _HashTable+CustomStringConvertible.swift │ │ ├── _HashTable+Testing.swift │ │ ├── _HashTable+Constants.swift │ │ ├── _Hashtable+Header.swift │ │ └── _HashTable.swift │ └── CMakeLists.txt ├── Deprecated │ └── Deprecated.swift ├── TabViews │ ├── AnimatedTabViewProtocol.swift │ ├── HoleScaleTabView.swift │ ├── InvertedPlateauTabView.swift │ └── MorphPlateauTabView.swift └── Reusable │ ├── SEShapeLayer.swift │ └── SELayer.swift ├── .travis.yml ├── .gitignore ├── SETabView.podspec ├── LICENSE ├── Package.swift ├── README_olderVersions.md └── README.md /SETabView/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /SETabView/Classes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /.build/manifest.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/manifest.db -------------------------------------------------------------------------------- /Gifs/HoleBall1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Gifs/HoleBall1.gif -------------------------------------------------------------------------------- /Gifs/HoleBall2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Gifs/HoleBall2.gif -------------------------------------------------------------------------------- /Gifs/HoleBall3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Gifs/HoleBall3.gif -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/build.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/build.db -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Tests/LinuxMain.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | import SETabViewTests 4 | 5 | var tests = [XCTestCaseEntry]() 6 | tests += SETabViewTests.allTests() 7 | XCTMain(tests) 8 | -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/fifth.imageset/031-death.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Example/SETabView/Images.xcassets/fifth.imageset/031-death.png -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/third.imageset/011-mummy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Example/SETabView/Images.xcassets/third.imageset/011-mummy.png -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/first.imageset/029-dracula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Example/SETabView/Images.xcassets/first.imageset/029-dracula.png -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/second.imageset/030-devil.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Example/SETabView/Images.xcassets/second.imageset/030-devil.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView.modulemap: -------------------------------------------------------------------------------- 1 | framework module SETabView { 2 | umbrella header "SETabView-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/fourth.imageset/021-frankenstein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/Example/SETabView/Images.xcassets/fourth.imageset/021-frankenstein.png -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SETabView : NSObject 3 | @end 4 | @implementation PodsDummy_SETabView 5 | @end 6 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/units/Helper.swift.o-1NF4RD9PFTAOH: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/units/Helper.swift.o-1NF4RD9PFTAOH -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/20/Helper.swift-4H91YLBIVH20: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/20/Helper.swift-4H91YLBIVH20 -------------------------------------------------------------------------------- /.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/ModuleCache/37NUFZOP9ZAD7/SwiftShims-2DA6NLEWJC11R.pcm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/ModuleCache/37NUFZOP9ZAD7/SwiftShims-2DA6NLEWJC11R.pcm -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/31/SETabView.swift-D361JZ1WW31: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/31/SETabView.swift-D361JZ1WW31 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/units/SETabView.swift.o-28S4YQEOK5OZW: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/units/SETabView.swift.o-28S4YQEOK5OZW -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'SETabView_Example' do 4 | pod 'SETabView', :path => '../' 5 | 6 | target 'SETabView_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/units/x86_64.swiftinterface-1DZ86EJZP8AVR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/units/x86_64.swiftinterface-1DZ86EJZP8AVR -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/units/SEViewController.swift.o-3D0K590ERCMIZ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/units/SEViewController.swift.o-3D0K590ERCMIZ -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/JF/x86_64.swiftinterface-3CXT5LB78S3JF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/JF/x86_64.swiftinterface-3CXT5LB78S3JF -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SETabView_Tests { 2 | umbrella header "Pods-SETabView_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/G3/x86_64.swiftinterface_C-34WRX7VVQ15G3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/G3/x86_64.swiftinterface_C-34WRX7VVQ15G3 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/I7/SEViewController.swift-3EJQHSB645VI7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/I7/SEViewController.swift-3EJQHSB645VI7 -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SETabView_Example { 2 | umbrella header "Pods-SETabView_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SETabView_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SETabView_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Tests/SETabViewTests/XCTestManifests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | #if !canImport(ObjectiveC) 4 | public func allTests() -> [XCTestCaseEntry] { 5 | return [ 6 | testCase(SETabViewTests.allTests), 7 | ] 8 | } 9 | #endif 10 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/5S/x86_64.swiftinterface_Misc-2QOU950HNIW5S: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/5S/x86_64.swiftinterface_Misc-2QOU950HNIW5S -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/H0/x86_64.swiftinterface_Bool-40OL09C2T2H0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/H0/x86_64.swiftinterface_Bool-40OL09C2T2H0 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/S1/x86_64.swiftinterface_Math-1AQNC3D9CLDS1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/S1/x86_64.swiftinterface_Math-1AQNC3D9CLDS1 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/3S/x86_64.swiftinterface_Assert-V65YNMTP6C3S: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/3S/x86_64.swiftinterface_Assert-V65YNMTP6C3S -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/5Q/x86_64.swiftinterface_String-H3HH1CSS8L5Q: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/5Q/x86_64.swiftinterface_String-H3HH1CSS8L5Q -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/B9/x86_64.swiftinterface_Hashing-1Y4B2U6G2NXB9: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/B9/x86_64.swiftinterface_Hashing-1Y4B2U6G2NXB9 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/DW/x86_64.swiftinterface_Result-2AQN7BFZ1PVDW: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/DW/x86_64.swiftinterface_Result-2AQN7BFZ1PVDW -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/L2/x86_64.swiftinterface_Optional-4I9DUJ3SK1L2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/L2/x86_64.swiftinterface_Optional-4I9DUJ3SK1L2 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/P1/x86_64.swiftinterface_Pointer-QCJI3XVI5BP1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/P1/x86_64.swiftinterface_Pointer-QCJI3XVI5BP1 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/PZ/x86_64.swiftinterface_KeyPaths-H0WDHRNCUMPZ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/PZ/x86_64.swiftinterface_KeyPaths-H0WDHRNCUMPZ -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SETabView_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SETabView_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/SETabView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/VC/x86_64.swiftinterface_Protocols-MCM8WJEDZ1VC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/VC/x86_64.swiftinterface_Protocols-MCM8WJEDZ1VC -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap: -------------------------------------------------------------------------------- 1 | module SETabView { 2 | header "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView-Swift.h" 3 | requires objc 4 | } 5 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/0B/x86_64.swiftinterface_Playground-2BDEY5WTUT30B: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/0B/x86_64.swiftinterface_Playground-2BDEY5WTUT30B -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/3N/x86_64.swiftinterface_Math_Integers-4FZ39UT9YN3N: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/3N/x86_64.swiftinterface_Math_Integers-4FZ39UT9YN3N -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/BA/x86_64.swiftinterface_Collection-1OOHYK7IC0VBA: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/BA/x86_64.swiftinterface_Collection-1OOHYK7IC0VBA -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/P0/x86_64.swiftinterface_Reflection-2VIZ2H1FZUHP0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/P0/x86_64.swiftinterface_Reflection-2VIZ2H1FZUHP0 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/Z6/x86_64.swiftinterface_Math_Vector-PNCOG8ZHQNZ6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/Z6/x86_64.swiftinterface_Math_Vector-PNCOG8ZHQNZ6 -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/1I/x86_64.swiftinterface_Math_Integers-1KOR3A56TZW1I: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/1I/x86_64.swiftinterface_Math_Integers-1KOR3A56TZW1I -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/PQ/x86_64.swiftinterface_Math_Floating-1X1Z0YAIY8APQ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/PQ/x86_64.swiftinterface_Math_Floating-1X1Z0YAIY8APQ -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/SK/x86_64.swiftinterface_Collection_Array-1GZF7D7LHZVSK: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/SK/x86_64.swiftinterface_Collection_Array-1GZF7D7LHZVSK -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/BJ/x86_64.swiftinterface_Collection_Type-erased-2GDE9N2H0B8BJ: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/BJ/x86_64.swiftinterface_Collection_Type-erased-2GDE9N2H0B8BJ -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/KD/x86_64.swiftinterface_Collection_Lazy_Views-3MDMH5FHKI4KD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/KD/x86_64.swiftinterface_Collection_Lazy_Views-3MDMH5FHKI4KD -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/index/store/v5/records/DX/x86_64.swiftinterface_Collection_HashedCollections-29A182UK5FQDX: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eshwavin/SETabView/HEAD/.build/x86_64-apple-macosx/debug/index/store/v5/records/DX/x86_64.swiftinterface_Collection_HashedCollections-29A182UK5FQDX -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/SETabView.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/SETabView.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SETabView (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - SETabView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SETabView: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SETabView: f92ed6b3d86187651364f89a1209def164663b72 13 | 14 | PODFILE CHECKSUM: bd85a252b66fad279155167c04d6eb3727183d77 15 | 16 | COCOAPODS: 1.9.0 17 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SETabView (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - SETabView (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SETabView: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SETabView: f92ed6b3d86187651364f89a1209def164663b72 13 | 14 | PODFILE CHECKSUM: bd85a252b66fad279155167c04d6eb3727183d77 15 | 16 | COCOAPODS: 1.9.0 17 | -------------------------------------------------------------------------------- /Source/ViewControllers/SETabItemProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SETabItem.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 10/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public protocol SETabItemProvider { 12 | var seTabBarItem: UITabBarItem? {get} 13 | } 14 | -------------------------------------------------------------------------------- /Source/ViewControllers/AnimatedTabViewDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SETabViewDelegate.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 10/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | protocol AnimatedTabViewDelegate: AnyObject { 12 | func didSelectTab(at index: Int) 13 | func changeBottomFillerViewColor() 14 | } 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double SETabViewVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char SETabViewVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/fifth.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "031-death.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/first.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "029-dracula.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/second.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "030-devil.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/third.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "011-mummy.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/SETabView/Images.xcassets/fourth.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "021-frankenstein.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_SETabView_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SETabView_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Source/Utilities/SETimingFunctions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TimingFunctions.swift 3 | // SETabView 4 | // 5 | // Created by Vinayak Eshwa on 20/03/22. 6 | // 7 | 8 | import UIKit 9 | 10 | struct SETimingFunction { 11 | public static let seEaseIn = CAMediaTimingFunction(controlPoints: 0.6, 0, 1, 1) 12 | public static let seEaseOut = CAMediaTimingFunction(controlPoints: 0, 0, 0.4, 1) 13 | public static let seEaseInOut = CAMediaTimingFunction(controlPoints: 0.6, 0, 0.4, 1) 14 | } 15 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_SETabView_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SETabView_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Tests/SETabViewTests/SETabViewTests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | @testable import SETabView 3 | 4 | final class SETabViewTests: XCTestCase { 5 | func testExample() { 6 | // This is an example of a functional test case. 7 | // Use XCTAssert and related functions to verify your tests produce the correct 8 | // results. 9 | // XCTAssertEqual(SETabView().text, "Hello, World!") 10 | } 11 | 12 | static var allTests = [ 13 | ("testExample", testExample), 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SETabView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView.release.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SETabView 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode7.3 6 | language: objective-c 7 | # cache: cocoapods 8 | # podfile: Example/Podfile 9 | # before_install: 10 | # - gem install cocoapods # Since Travis is not always on latest version 11 | # - pod install --project-directory=Example 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/SETabView.xcworkspace -scheme SETabView-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint 15 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/master.swiftdeps: -------------------------------------------------------------------------------- 1 | version: "Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)" 2 | options: "e9eec284f24003f75bf274f15f857fc3" 3 | build_time: [1585439293, 618758000] 4 | inputs: 5 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/Helper.swift": !dirty [1584121033, 918609883] 6 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SETabView.swift": !dirty [1584130950, 394884860] 7 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SEViewController.swift": !dirty [1585437721, 912854964] 8 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/master.swiftdeps~moduleonly: -------------------------------------------------------------------------------- 1 | version: "Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)" 2 | options: "e9eec284f24003f75bf274f15f857fc3" 3 | build_time: [1585439293, 618758000] 4 | inputs: 5 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/Helper.swift": !dirty [1584121033, 918609883] 6 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SETabView.swift": !dirty [1584130950, 394884860] 7 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SEViewController.swift": !dirty [1585437721, 912854964] 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView/SETabView.framework/Headers" 4 | OTHER_LDFLAGS = $(inherited) -framework "SETabView" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView/SETabView.framework/Headers" 4 | OTHER_LDFLAGS = $(inherited) -framework "SETabView" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 10 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/description.json: -------------------------------------------------------------------------------- 1 | { 2 | "allExecutables" : [ 3 | 4 | ], 5 | "builtTestProducts" : [ 6 | { 7 | "packageName" : "SETabView", 8 | "productName" : "SETabViewPackageTests", 9 | "testBinary" : "\/Users\/eshwavin\/Documents\/App Dev 2019\/Custom Tab Bar\/Pod\/SETabView\/.build\/x86_64-apple-macosx\/debug\/SETabViewPackageTests.xctest\/Contents\/MacOS\/SETabViewPackageTests" 10 | } 11 | ], 12 | "copyCommands" : { 13 | 14 | }, 15 | "rootExecutables" : [ 16 | 17 | ], 18 | "swiftTargetMap" : { 19 | "C.SETabView-debug.module" : "SETabView", 20 | "C.SETabViewTests-debug.module" : "SETabViewTests" 21 | }, 22 | "testDiscoveryCommands" : { 23 | 24 | } 25 | } -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/ModuleCache/Swift-39YYAJQGEAJ2E.swiftmodule: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/Swift.swiftmodule/x86_64-apple-macos.swiftmodule' 3 | dependencies: 4 | - mtime: 1583600188000000000 5 | path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/Swift.swiftmodule/x86_64-apple-macos.swiftmodule' 6 | size: 9933936 7 | - mtime: 1583127163000000000 8 | path: 'usr/lib/swift/Swift.swiftmodule/x86_64.swiftinterface' 9 | size: 1488272 10 | sdk_relative: true 11 | version: 1 12 | ... 13 | -------------------------------------------------------------------------------- /Source/Utilities/AnimationType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 17/02/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public enum AnimationType { 12 | case holeBall1 13 | case holeBall2 14 | case holeBall3 15 | 16 | var tabView: AnimatedTabViewProtocol { 17 | get { 18 | switch self { 19 | case .holeBall1: 20 | return HoleScaleTabView() 21 | case .holeBall2: 22 | return InvertedPlateauTabView() 23 | case .holeBall3: 24 | return MorphPlateauTabView() 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+CustomReflectable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: CustomReflectable { 13 | /// The custom mirror for this instance. 14 | public var customMirror: Mirror { 15 | Mirror(self, unlabeledChildren: _elements, displayStyle: .collection) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabViewPackageTests.product/Objects.LinkFileList: -------------------------------------------------------------------------------- 1 | '/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper.swift.o' 2 | '/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.swift.o' 3 | '/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.swift.o' 4 | '/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabViewTests.build/SETabViewTests.swift.o' 5 | '/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabViewTests.build/XCTestManifests.swift.o' 6 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+CustomReflectable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: CustomReflectable { 13 | /// The custom mirror for this instance. 14 | public var customMirror: Mirror { 15 | Mirror(self, unlabeledChildren: self.elements, displayStyle: .dictionary) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/ModuleCache/SwiftOnoneSupport-2RFMDLM7SUFB5.swiftmodule: -------------------------------------------------------------------------------- 1 | --- 2 | path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule' 3 | dependencies: 4 | - mtime: 1583600190000000000 5 | path: '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule' 6 | size: 11620 7 | - mtime: 1583127166000000000 8 | path: 'usr/lib/swift/SwiftOnoneSupport.swiftmodule/x86_64.swiftinterface' 9 | size: 432 10 | sdk_relative: true 11 | version: 1 12 | ... 13 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/SETabView.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SETabView", 3 | "version": "1.0.0", 4 | "summary": "SETabView is a custom TabBar with really cool animations", 5 | "description": "'SETabView is a TabBar with simple yet beautiful animations that makes your apps look cool!'", 6 | "homepage": "https://github.com/eshwavin/SETabView", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "eshwavin": "eshwavin@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/eshwavin/SETabView.git", 16 | "tag": "1.0.0" 17 | }, 18 | "social_media_url": "https://www.instagram.com/eshwavin/", 19 | "platforms": { 20 | "ios": "11.0" 21 | }, 22 | "source_files": "Source/**/*.swift", 23 | "swift_versions": "5.0", 24 | "swift_version": "5.0" 25 | } 26 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView/SETabView.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SETabView" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/SETabView/SETabView.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "SETabView" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 13 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | import SETabView 3 | 4 | class Tests: XCTestCase { 5 | 6 | override func setUp() { 7 | super.setUp() 8 | // Put setup code here. This method is called before the invocation of each test method in the class. 9 | } 10 | 11 | override func tearDown() { 12 | // Put teardown code here. This method is called after the invocation of each test method in the class. 13 | super.tearDown() 14 | } 15 | 16 | func testExample() { 17 | // This is an example of a functional test case. 18 | XCTAssert(true, "Pass") 19 | } 20 | 21 | func testPerformanceExample() { 22 | // This is an example of a performance test case. 23 | self.measure() { 24 | // Put the code you want to measure the time of here. 25 | } 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | 4 | # Xcode 5 | build/ 6 | *.pbxuser 7 | !default.pbxuser 8 | *.mode1v3 9 | !default.mode1v3 10 | *.mode2v3 11 | !default.mode2v3 12 | *.perspectivev3 13 | !default.perspectivev3 14 | xcuserdata/ 15 | *.xccheckout 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | *.hmap 20 | *.ipa 21 | 22 | # Bundler 23 | .bundle 24 | 25 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 26 | # Carthage/Checkouts 27 | 28 | Carthage/Build 29 | 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 33 | # 34 | # Note: if you ignore the Pods directory, make sure to uncomment 35 | # `pod install` in .travis.yml 36 | # 37 | # Pods/ 38 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Hashable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: Hashable { 13 | /// Hashes the essential components of this value by feeding them into the 14 | /// given hasher. 15 | /// 16 | /// Complexity: O(`count`) 17 | @inlinable 18 | public func hash(into hasher: inout Hasher) { 19 | hasher.combine(count) // Discriminator 20 | for item in _elements { 21 | hasher.combine(item) 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Invariants.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary { 13 | #if COLLECTIONS_INTERNAL_CHECKS 14 | @inline(never) @_effects(releasenone) 15 | public func _checkInvariants() { 16 | precondition(_keys.count == _values.count) 17 | self._keys._checkInvariants() 18 | } 19 | #else 20 | @inline(__always) @inlinable 21 | public func _checkInvariants() {} 22 | #endif // COLLECTIONS_INTERNAL_CHECKS 23 | } 24 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Equatable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: Equatable { 13 | /// Returns a Boolean value indicating whether two values are equal. 14 | /// 15 | /// Two ordered sets are considered equal if they contain the same 16 | /// elements in the same order. 17 | /// 18 | /// - Complexity: O(`min(left.count, right.count)`) 19 | @inlinable 20 | public static func ==(left: Self, right: Self) -> Bool { 21 | left.elementsEqual(right) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/SETabView/SETabView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Source/Deprecated/Deprecated.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Deprecated.swift 3 | // Pods-SETabView_Example 4 | // 5 | // Created by Vinayak Eshwa on 20/03/22. 6 | // 7 | 8 | import UIKit 9 | 10 | @available(iOS, obsoleted: 2.0.0, renamed: "SETabViewController") 11 | open class SEViewController { } 12 | 13 | @available(iOS, obsoleted: 2.0.0, renamed: "SETabItemProvider") 14 | public protocol SETabItem { } 15 | 16 | public extension SETabViewController { 17 | @available(iOS, obsoleted: 2.0.0, message: "Use setTabColors(backgroundColor:ballColor:tintColor:unselectedItemTintColor:barTintColor:) instead") 18 | func setTabSettings(tabColor: UIColor, ballColor: UIColor, selectedTabTintColor: UIColor, deselectedTabTintColor: UIColor, animationDuration: Double) { } 19 | 20 | @available(iOS, obsoleted: 2.0.0, message: "Use setViewControllers(_:) instead") 21 | func setViewControllers(_ viewControllers: [UIViewController], initialSelectedIndex: Int, animationType: AnimationType) { } 22 | } 23 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Hashable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: Hashable where Value: Hashable { 13 | /// Hashes the essential components of this value by feeding them into the 14 | /// given hasher. 15 | /// 16 | /// Complexity: O(`count`) 17 | @inlinable 18 | public func hash(into hasher: inout Hasher) { 19 | hasher.combine(count) // Discriminator 20 | for (key, value) in self { 21 | hasher.combine(key) 22 | hasher.combine(value) 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+CustomStringConvertible.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: CustomStringConvertible { 13 | /// A textual representation of this instance. 14 | public var description: String { 15 | var result = "[" 16 | var first = true 17 | for item in self { 18 | if first { 19 | first = false 20 | } else { 21 | result += ", " 22 | } 23 | print(item, terminator: "", to: &result) 24 | } 25 | result += "]" 26 | return result 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Tests/Pods-SETabView_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Source/OrderedCollections/Utilities/RandomAccessCollection+Offsets.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension RandomAccessCollection { 13 | @inlinable 14 | @inline(__always) 15 | internal func _index(at offset: Int) -> Index { 16 | index(startIndex, offsetBy: offset) 17 | } 18 | 19 | @inlinable 20 | @inline(__always) 21 | internal func _offset(of index: Index) -> Int { 22 | distance(from: startIndex, to: index) 23 | } 24 | 25 | @inlinable 26 | @inline(__always) 27 | internal subscript(_offset offset: Int) -> Element { 28 | self[_index(at: offset)] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+CustomStringConvertible.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: CustomStringConvertible { 13 | /// A textual representation of this instance. 14 | public var description: String { 15 | if isEmpty { return "[:]" } 16 | var result = "[" 17 | var first = true 18 | for (key, value) in self { 19 | if first { 20 | first = false 21 | } else { 22 | result += ", " 23 | } 24 | result += "\(key): \(value)" 25 | } 26 | result += "]" 27 | return result 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Equatable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: Equatable where Value: Equatable { 13 | /// Returns a Boolean value indicating whether two values are equal. 14 | /// 15 | /// Two ordered dictionaries are considered equal if they contain the same 16 | /// key-value pairs, in the same order. 17 | /// 18 | /// - Complexity: O(`min(left.count, right.count)`) 19 | @inlinable 20 | public static func ==(left: Self, right: Self) -> Bool { 21 | left._keys == right._keys && left._values == right._values 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/SETabView/FifthViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FifthViewController.swift 3 | // SETabView_Example 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 13/03/20. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class FifthViewController: UIViewController, SETabItemProvider { 13 | 14 | var seTabBarItem: UITabBarItem? { 15 | return UITabBarItem(title: "", image: UIImage(named: "fifth"), tag: 0) 16 | } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destination. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Example/SETabView/ThirdViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ThirdViewController.swift 3 | // SETabView_Example 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 13/03/20. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class ThirdViewController: UIViewController, SETabItemProvider { 13 | 14 | var seTabBarItem: UITabBarItem? { 15 | return UITabBarItem(title: "", image: UIImage(named: "third"), tag: 0) 16 | } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destination. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Example/SETabView/FirstViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FirstViewController.swift 3 | // SETabView_Example 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 13/03/20. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class FirstViewController: UIViewController, SETabItemProvider { 13 | 14 | var seTabBarItem: UITabBarItem? { 15 | return UITabBarItem(title: "", image: UIImage(named: "first"), tag: 0) 16 | } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | 25 | 26 | /* 27 | // MARK: - Navigation 28 | 29 | // In a storyboard-based application, you will often want to do a little preparation before navigation 30 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 31 | // Get the new view controller using segue.destination. 32 | // Pass the selected object to the new view controller. 33 | } 34 | */ 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/SETabView/FourthViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FourthViewController.swift 3 | // SETabView_Example 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 13/03/20. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class FourthViewController: UIViewController, SETabItemProvider { 13 | 14 | var seTabBarItem: UITabBarItem? { 15 | return UITabBarItem(title: "", image: UIImage(named: "fourth"), tag: 0) 16 | } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destination. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Example/SETabView/SecondViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SecondViewController.swift 3 | // SETabView_Example 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 13/03/20. 6 | // Copyright © 2020 CocoaPods. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class SecondViewController: UIViewController, SETabItemProvider { 13 | 14 | var seTabBarItem: UITabBarItem? { 15 | return UITabBarItem(title: "", image: UIImage(named: "second"), tag: 0) 16 | } 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | 21 | // Do any additional setup after loading the view. 22 | } 23 | 24 | 25 | /* 26 | // MARK: - Navigation 27 | 28 | // In a storyboard-based application, you will often want to do a little preparation before navigation 29 | override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 30 | // Get the new view controller using segue.destination. 31 | // Pass the selected object to the new view controller. 32 | } 33 | */ 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Source/TabViews/AnimatedTabViewProtocol.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TabView.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 31/07/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | protocol AnimatedTabViewProtocol: UIView { 12 | 13 | var tabImages: [UIImage] { get set } 14 | var selectedTabIndex: Int { get set } 15 | var delegate: AnimatedTabViewDelegate? { get set } 16 | 17 | var isSetup: Bool { get set } 18 | var closureAfterSetup: (() -> Void)? { get set } 19 | 20 | func applyColors() 21 | func tabTintColorDidChange() 22 | func backgroundColorDidChange() 23 | func ballColorDidChange() 24 | func unselectedItemTintColorDidChange() 25 | func barTintColorDidChange() 26 | } 27 | 28 | public protocol AnimatedTabViewProperties { 29 | var tintColor: UIColor { get set } 30 | var backgroundColor: UIColor { get set } 31 | var ballColor: UIColor { get set } 32 | var unselectedItemTintColor: UIColor { get set } 33 | var barTintColor: UIColor { get set } 34 | } 35 | -------------------------------------------------------------------------------- /SETabView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'SETabView' 3 | s.version = '2.0.0' 4 | s.summary = 'SETabView is a custom TabBar with really cool animations' 5 | 6 | s.description = <<-DESC 7 | 'SETabView is a TabBar with simple yet beautiful animations that makes your apps look cool!' 8 | DESC 9 | 10 | s.homepage = 'https://github.com/eshwavin/SETabView' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'eshwavin' => 'eshwavin@gmail.com' } 13 | s.source = { :git => 'https://github.com/eshwavin/SETabView.git', :tag => s.version.to_s } 14 | s.social_media_url = 'https://www.instagram.com/eshwavin/' 15 | 16 | s.ios.deployment_target = '11.0' 17 | 18 | s.source_files = 'Source/**/*.swift' 19 | 20 | s.swift_version = '5.0' 21 | 22 | # s.resource_bundles = { 23 | # 'SETabView' => ['SETabView/Assets/*.png'] 24 | # } 25 | 26 | # s.public_header_files = 'Pod/Classes/**/*.h' 27 | # s.frameworks = 'UIKit', 'MapKit' 28 | # s.dependency 'AFNetworking', '~> 2.3' 29 | end 30 | -------------------------------------------------------------------------------- /Source/Utilities/SETabSettings.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SETabSettings.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 11/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class SETabSettings { 12 | 13 | static var current = SETabSettings() 14 | 15 | private init() {} 16 | 17 | private var animationDuration: Double = 1.5 18 | 19 | var switchTabAnimationDuration: Double { 20 | return animationDuration * 0.3 21 | } 22 | 23 | var ballAnimationDuration: Double { 24 | return animationDuration * 0.3 25 | } 26 | 27 | var changeTintColorAnimationDuration: Double { 28 | return animationDuration * 0.3 29 | } 30 | 31 | var scaleBallDelayTime: Double { 32 | return animationDuration * 0.2 33 | } 34 | 35 | var backgroundColor = UIColor.clear 36 | var ballColor = UIColor.clear 37 | var tintColor = UIColor.systemBlue 38 | var unselectedItemTintColor = UIColor.systemGray 39 | var barTintColor = UIColor.clear 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Example/SETabView/Images.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" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Srivinayak Chaitanya Eshwa 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.0 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "SETabView", 8 | platforms: [ 9 | .iOS(.v11) 10 | ], 11 | products: [ 12 | // Products define the executables and libraries produced by a package, and make them visible to other packages. 13 | .library( 14 | name: "SETabView", 15 | targets: ["SETabView"]), 16 | ], 17 | dependencies: [ 18 | // Dependencies declare other packages that this package depends on. 19 | // .package(url: /* package url */, from: "1.0.0"), 20 | ], 21 | targets: [ 22 | // Targets are the basic building blocks of a package. A target can define a module or a test suite. 23 | // Targets can depend on other targets in this package, and on products in packages which this package depends on. 24 | .target( 25 | name: "SETabView", 26 | dependencies: [], 27 | path:"Source"), 28 | .testTarget( 29 | name: "SETabViewTests", 30 | dependencies: ["SETabView"]), 31 | ] 32 | ) 33 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+CustomDebugStringConvertible.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: CustomDebugStringConvertible { 13 | /// A textual representation of this instance, suitable for debugging. 14 | public var debugDescription: String { 15 | _debugDescription(typeName: _debugTypeName()) 16 | } 17 | 18 | internal func _debugTypeName() -> String { 19 | "OrderedSet<\(Element.self)>" 20 | } 21 | 22 | internal func _debugDescription(typeName: String) -> String { 23 | var result = "\(typeName)([" 24 | var first = true 25 | for item in self { 26 | if first { 27 | first = false 28 | } else { 29 | result += ", " 30 | } 31 | debugPrint(item, terminator: "", to: &result) 32 | } 33 | result += "])" 34 | return result 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Source/Reusable/SEShapeLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SEShapeLayer.swift 3 | // SETabView 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 12/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class SEShapeLayer: CAShapeLayer { 12 | 13 | func translate(to toValue: CGFloat) { 14 | let translateAnimation = SELayerAnimationProvider.getTranslateXAnimation(runningFor: SETabSettings.current.switchTabAnimationDuration, fromValue: nil, toValue: toValue, timingFunction: SETimingFunction.seEaseInOut, fillMode: CAMediaTimingFillMode.both, beginTime: nil, isRemovedOnCompletion: false) 15 | 16 | add(translateAnimation, forKey: nil) 17 | } 18 | 19 | func morph(using paths: [CGPath]) { 20 | let morphAnimation = SELayerAnimationProvider.getKeyframePathAnimation(runningFor: SETabSettings.current.switchTabAnimationDuration, 21 | values: paths, 22 | keyTimes: [0.0, 0.25, 0.4, 0.65, 0.85, 1.0], 23 | timingFunctions: [SETimingFunction.seEaseIn, SETimingFunction.seEaseOut, CAMediaTimingFunction(name: .linear), SETimingFunction.seEaseIn, SETimingFunction.seEaseOut], 24 | fillMode: .both, isRemovedOnCompletion: true) 25 | 26 | add(morphAnimation, forKey: nil) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Example/SETabView/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SETabView 4 | // 5 | // Created by eshwavin on 03/13/2020. 6 | // Copyright (c) 2020 eshwavin. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SETabView 11 | 12 | class ViewController: SETabViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | 17 | // set tab bar look 18 | setTabColors(backgroundColor: .white, ballColor: .white, tintColor: .black, unselectedItemTintColor: .gray, barTintColor: .clear) 19 | 20 | // set view controllers 21 | setViewControllers(getViewControllers()) 22 | 23 | } 24 | 25 | private func getViewControllers() -> [UIViewController] { 26 | 27 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 28 | 29 | return [ 30 | storyboard.instantiateViewController(withIdentifier: "firstVC"), 31 | storyboard.instantiateViewController(withIdentifier: "secondVC"), 32 | storyboard.instantiateViewController(withIdentifier: "thirdVC"), 33 | storyboard.instantiateViewController(withIdentifier: "fourthVC"), 34 | storyboard.instantiateViewController(withIdentifier: "fifthVC") 35 | ] 36 | 37 | 38 | } 39 | 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_HashTable+Bucket.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension _HashTable { 13 | /// Identifies a particular bucket within a hash table by its offset. 14 | /// Having a dedicated wrapper type for this prevents passing a bucket number 15 | /// to a function that expects a word index, or vice versa. 16 | @usableFromInline 17 | @frozen 18 | internal struct Bucket { 19 | /// The distance of this bucket from the first bucket in the hash table. 20 | @usableFromInline 21 | internal var offset: Int 22 | 23 | @inlinable 24 | @inline(__always) 25 | internal init(offset: Int) { 26 | assert(offset >= 0) 27 | self.offset = offset 28 | } 29 | } 30 | } 31 | 32 | extension _HashTable.Bucket: Equatable { 33 | @_transparent 34 | public static func == (left: Self, right: Self) -> Bool { 35 | left.offset == right.offset 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Example/SETabView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 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 | $(MARKETING_VERSION) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 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 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SETabView 5 | 6 | Copyright (c) 2020 eshwavin 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | Generated by CocoaPods - https://cocoapods.org 27 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+ExpressibleByDictionaryLiteral.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: ExpressibleByDictionaryLiteral { 13 | /// Creates a new ordered dictionary from the contents of a dictionary 14 | /// literal. 15 | /// 16 | /// Do not call this initializer directly. It is used by the compiler when you 17 | /// use a dictionary literal. Instead, create a new ordered dictionary using a 18 | /// dictionary literal as its value by enclosing a comma-separated list of 19 | /// key-value pairs in square brackets. You can use a dictionary literal 20 | /// anywhere an ordered dictionary is expected by the type context. 21 | /// 22 | /// - Parameter elements: A variadic list of key-value pairs for the new 23 | /// ordered dictionary. 24 | /// 25 | /// - Complexity: O(`elements.count`) if `Key` implements 26 | /// high-quality hashing. 27 | @inlinable 28 | public init(dictionaryLiteral elements: (Key, Value)...) { 29 | self.init(uniqueKeysWithValues: elements) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+ExpressibleByArrayLiteral.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: ExpressibleByArrayLiteral { 13 | /// Creates a new ordered set from the contents of an array literal. 14 | /// 15 | /// Duplicate elements in the literal are allowed, but the resulting ordered 16 | /// set will only contain the first occurrence of each. 17 | /// 18 | /// Do not call this initializer directly. It is used by the compiler when 19 | /// you use an array literal. Instead, create a new ordered set using an array 20 | /// literal as its value by enclosing a comma-separated list of values in 21 | /// square brackets. You can use an array literal anywhere an ordered set is 22 | /// expected by the type context. 23 | /// 24 | /// - Parameter elements: A variadic list of elements of the new ordered set. 25 | /// 26 | /// - Complexity: O(`elements.count`) if `Element` implements 27 | /// high-quality hashing. 28 | @inlinable 29 | public init(arrayLiteral elements: Element...) { 30 | self.init(elements) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+CustomDebugStringConvertible.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: CustomDebugStringConvertible { 13 | /// A textual representation of this instance, suitable for debugging. 14 | public var debugDescription: String { 15 | _debugDescription(typeName: _debugTypeName()) 16 | } 17 | 18 | internal func _debugTypeName() -> String { 19 | "OrderedDictionary<\(Key.self), \(Value.self)>" 20 | } 21 | 22 | internal func _debugDescription(typeName: String) -> String { 23 | var result = "\(typeName)(" 24 | if isEmpty { 25 | result += "[:]" 26 | } else { 27 | result += "[" 28 | var first = true 29 | for (key, value) in self { 30 | if first { 31 | first = false 32 | } else { 33 | result += ", " 34 | } 35 | debugPrint(key, terminator: "", to: &result) 36 | result += ": " 37 | debugPrint(value, terminator: "", to: &result) 38 | } 39 | result += "]" 40 | } 41 | result += ")" 42 | return result 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+UnstableInternals.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet { 13 | /// Exposes some private implementation details and low-level unsafe 14 | /// operations, primarily to allow clear box testing. 15 | /// 16 | /// This struct is a private implementation detail, therefore it and its 17 | /// members are not covered by any source compatibility promises -- they 18 | /// may disappear in any new release. 19 | @frozen 20 | public struct _UnstableInternals { 21 | @usableFromInline 22 | internal typealias _Bucket = _HashTable.Bucket 23 | 24 | @usableFromInline 25 | internal var base: OrderedSet 26 | 27 | @inlinable 28 | init(_ base: OrderedSet) { 29 | self.base = base 30 | } 31 | } 32 | 33 | @inlinable 34 | public var __unstable: _UnstableInternals { 35 | @inline(__always) 36 | get { 37 | _UnstableInternals(self) 38 | } 39 | 40 | @inline(__always) 41 | _modify { 42 | var view = _UnstableInternals(self) 43 | self = OrderedSet() 44 | defer { self = view.base } 45 | yield &view 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Deprecations.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary { 13 | /// Accesses the element at the specified index. 14 | /// 15 | /// - Parameter offset: The offset of the element to access, measured from 16 | /// the start of the collection. `offset` must be greater than or equal to 17 | /// `0` and less than `count`. 18 | /// 19 | /// - Complexity: O(1) 20 | @available(*, unavailable, // deprecated in 0.0.6, obsoleted in 1.0.0 21 | message: "Please use `elements[offset]`") 22 | @inlinable 23 | @inline(__always) 24 | public subscript(offset offset: Int) -> Element { 25 | fatalError() 26 | } 27 | } 28 | 29 | extension OrderedDictionary { 30 | @available(*, unavailable, // deprecated in 0.0.6, obsoleted in 1.0.0 31 | renamed: "updateValue(forKey:default:with:)") 32 | @inlinable 33 | public mutating func modifyValue( 34 | forKey key: Key, 35 | default defaultValue: @autoclosure () -> Value, 36 | _ body: (inout Value) throws -> R 37 | ) rethrows -> R { 38 | fatalError() 39 | } 40 | 41 | @available(*, unavailable, // deprecated in 0.0.6, obsoleted in 1.0.0 42 | renamed: "updateValue(forKey:insertingDefault:at:with:)") 43 | @inlinable 44 | public mutating func modifyValue( 45 | forKey key: Key, 46 | insertingDefault defaultValue: @autoclosure () -> Value, 47 | at index: Int, 48 | _ body: (inout Value) throws -> R 49 | ) rethrows -> R { 50 | fatalError() 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_HashTable+CustomStringConvertible.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | // These are primarily for debugging. 13 | 14 | extension _HashTable.Header: CustomStringConvertible { 15 | @usableFromInline 16 | internal var _description: String { 17 | "(scale: \(scale), reservedScale: \(reservedScale), bias: \(bias), seed: \(String(seed, radix: 16)))" 18 | } 19 | 20 | @usableFromInline 21 | internal var description: String { 22 | "_HashTable.Header\(_description)" 23 | } 24 | } 25 | 26 | extension _HashTable.UnsafeHandle: CustomStringConvertible { 27 | internal func _description(type: String) -> String { 28 | var d = """ 29 | \(type)\(_header.pointee._description) 30 | load factor: \(debugLoadFactor()) 31 | """ 32 | if bucketCount < 128 { 33 | d += "\n " 34 | d += debugContents() 35 | .lazy 36 | .map { $0 == nil ? "_" : "\($0!)" } 37 | .joined(separator: " ") 38 | } 39 | return d 40 | } 41 | 42 | @usableFromInline 43 | internal var description: String { 44 | _description(type: "_HashTable.UnsafeHandle") 45 | } 46 | } 47 | 48 | extension _HashTable: CustomStringConvertible { 49 | @usableFromInline 50 | internal var description: String { 51 | read { $0._description(type: "_HashTable") } 52 | } 53 | } 54 | 55 | extension _HashTable.Storage: CustomStringConvertible { 56 | @usableFromInline 57 | internal var description: String { 58 | _HashTable(self).read { $0._description(type: "_HashTable.Storage") } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Codable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet: Encodable where Element: Encodable { 13 | /// Encodes the elements of this ordered set into the given encoder. 14 | /// 15 | /// - Parameter encoder: The encoder to write data to. 16 | @inlinable 17 | public func encode(to encoder: Encoder) throws { 18 | var container = encoder.singleValueContainer() 19 | try container.encode(_elements) 20 | } 21 | } 22 | 23 | extension OrderedSet: Decodable where Element: Decodable { 24 | /// Creates a new ordered set by decoding from the given decoder. 25 | /// 26 | /// This initializer throws an error if reading from the decoder fails, or 27 | /// if the decoded contents contain duplicate values. 28 | /// 29 | /// - Parameter decoder: The decoder to read data from. 30 | @inlinable 31 | public init(from decoder: Decoder) throws { 32 | let container = try decoder.singleValueContainer() 33 | let elements = try container.decode(ContiguousArray.self) 34 | 35 | let (table, end) = _HashTable.create(untilFirstDuplicateIn: elements) 36 | guard end == elements.endIndex else { 37 | let context = DecodingError.Context( 38 | codingPath: container.codingPath, 39 | debugDescription: "Decoded elements aren't unique (first duplicate at offset \(end))") 40 | throw DecodingError.dataCorrupted(context) 41 | } 42 | self.init( 43 | _uniqueElements: elements, 44 | elements.count > _HashTable.maximumUnhashedCount ? table : nil) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Sequence.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: Sequence { 13 | /// The element type of a dictionary: a tuple containing an individual 14 | /// key-value pair. 15 | public typealias Element = (key: Key, value: Value) 16 | 17 | /// The type that allows iteration over an ordered dictionary's elements. 18 | @frozen 19 | public struct Iterator: IteratorProtocol { 20 | @usableFromInline 21 | internal let _base: OrderedDictionary 22 | 23 | @usableFromInline 24 | internal var _position: Int 25 | 26 | @inlinable 27 | @inline(__always) 28 | internal init(_base: OrderedDictionary) { 29 | self._base = _base 30 | self._position = 0 31 | } 32 | 33 | /// Advances to the next element and returns it, or nil if no next 34 | /// element exists. 35 | /// 36 | /// - Complexity: O(1) 37 | @inlinable 38 | public mutating func next() -> Element? { 39 | guard _position < _base._values.count else { return nil } 40 | let result = (_base._keys[_position], _base._values[_position]) 41 | _position += 1 42 | return result 43 | } 44 | } 45 | 46 | /// The number of elements in the collection. 47 | /// 48 | /// - Complexity: O(1) 49 | @inlinable 50 | @inline(__always) 51 | public var underestimatedCount: Int { 52 | count 53 | } 54 | 55 | /// Returns an iterator over the elements of this collection. 56 | /// 57 | /// - Complexity: O(1) 58 | @inlinable 59 | @inline(__always) 60 | public func makeIterator() -> Iterator { 61 | Iterator(_base: self) 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Invariants.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet { 13 | #if COLLECTIONS_INTERNAL_CHECKS 14 | @inlinable 15 | @inline(never) @_effects(releasenone) 16 | public func _checkInvariants() { 17 | if _table == nil { 18 | precondition(_elements.count <= _HashTable.maximumUnhashedCount, 19 | "Oversized set without a hash table") 20 | precondition(Set(_elements).count == _elements.count, 21 | "Duplicate items in set") 22 | return 23 | } 24 | // Check that each element in _elements can be found in the hash table. 25 | for index in _elements.indices { 26 | let item = _elements[index] 27 | let i = _find(item).index 28 | precondition(i != nil, 29 | "Index \(index) not found in hash table (element: \(item))") 30 | precondition( 31 | i == index, 32 | "Offset of element '\(item)' in hash table differs from its position") 33 | } 34 | // Check that the hash table has exactly as many entries as there are elements. 35 | _table!.read { hashTable in 36 | var it = hashTable.bucketIterator(startingAt: _Bucket(offset: 0)) 37 | var c = 0 38 | repeat { 39 | it.advance() 40 | if it.isOccupied { c += 1 } 41 | } while it.currentBucket.offset != 0 42 | precondition( 43 | c == _elements.count, 44 | """ 45 | Number of entries in hash table (\(c)) differs 46 | from number of elements (\(_elements.count)) 47 | """) 48 | } 49 | } 50 | #else 51 | @inline(__always) @inlinable 52 | public func _checkInvariants() {} 53 | #endif // COLLECTIONS_INTERNAL_CHECKS 54 | } 55 | -------------------------------------------------------------------------------- /Source/TabViews/HoleScaleTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HoleScaleTabView.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 10/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class HoleScaleTabView: AnimatedTabView { 12 | 13 | } 14 | 15 | // MARK: Setup 16 | 17 | extension HoleScaleTabView { 18 | 19 | override func setupTabLayers() { 20 | super.setupTabLayers() 21 | 22 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 23 | let ballLayerY = itemHeight * 0.25 - (ballSize * 0.5) 24 | ballLayer.frame = CGRect(x: ballLayerX, y: ballLayerY, width: ballSize, height: ballSize) 25 | ballLayer.cornerRadius = ballSize / 2.0 26 | 27 | // setup shape layer 28 | tabShapeLayer.frame = bounds 29 | tabShapeLayer.path = createHolePath() 30 | 31 | setupTabImagePositions() 32 | 33 | } 34 | 35 | } 36 | 37 | // MARK: Paths 38 | 39 | extension HoleScaleTabView { 40 | 41 | private func createHolePath() -> CGPath { 42 | 43 | let startOffset = ((sectionWidth - itemWidth) / 2) 44 | let coverOffset = CGFloat(numberOfTabs - 1) * sectionWidth 45 | 46 | return SEPathProvider.getHolePath(for: bounds, startOffset: startOffset, coverOffset: coverOffset, itemWidth: itemWidth, sectionHeight: sectionHeight, heightScalingFactor: heightScalingFactor) 47 | 48 | } 49 | 50 | } 51 | 52 | // MARK: Animations 53 | 54 | extension HoleScaleTabView { 55 | 56 | override func performAnimations() { 57 | super.performAnimations() 58 | scaleBall() 59 | } 60 | 61 | private func scaleBall() { 62 | 63 | // move ball to new location 64 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 65 | let ballLayerY = itemHeight * 0.25 - (ballSize * 0.5) 66 | ballLayer.frame = CGRect(x: ballLayerX, y: ballLayerY, width: ballSize, height: ballSize) 67 | 68 | // animate ball 69 | ballLayer.scale() 70 | 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/Helper.d: -------------------------------------------------------------------------------- 1 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper.swift.o : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 2 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper~partial.swiftmodule : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 3 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper~partial.swiftdoc : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 4 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper~partial.swiftsourceinfo : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 5 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_HashTable+Testing.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension _HashTable.Bucket: CustomStringConvertible { 13 | public var description: String { "Bucket(@\(offset))"} 14 | } 15 | 16 | extension _UnsafeHashTable { 17 | internal func debugOccupiedCount() -> Int { 18 | var count = 0 19 | var it = bucketIterator(startingAt: Bucket(offset: 0)) 20 | repeat { 21 | if it.isOccupied { 22 | count += 1 23 | } 24 | it.advance() 25 | } while it.currentBucket.offset != 0 26 | return count 27 | } 28 | 29 | internal func debugLoadFactor() -> Double { 30 | return Double(debugOccupiedCount()) / Double(bucketCount) 31 | } 32 | 33 | internal func debugContents() -> [Int?] { 34 | var result: [Int?] = [] 35 | result.reserveCapacity(bucketCount) 36 | var it = bucketIterator(startingAt: Bucket(offset: 0)) 37 | repeat { 38 | result.append(it.currentValue) 39 | it.advance() 40 | } while it.currentBucket.offset != 0 41 | return result 42 | } 43 | } 44 | 45 | extension _UnsafeHashTable.BucketIterator: CustomStringConvertible { 46 | @usableFromInline 47 | var description: String { 48 | func pad(_ s: String, to length: Int, by padding: Character = " ") -> String { 49 | let c = s.count 50 | guard c < length else { return s } 51 | return String(repeating: padding, count: length - c) + s 52 | } 53 | let offset = pad(String(_currentBucket.offset), to: 4) 54 | let value: String 55 | if let v = currentValue { 56 | value = pad(String(v), to: 4) 57 | } else { 58 | value = " nil" 59 | } 60 | let remainingBits = pad(String(_nextBits, radix: 2), to: _remainingBitCount, by: "0") 61 | return "BucketIterator(scale: \(_scale), bucket: \(offset), value: \(value), bits: \(remainingBits) (\(_remainingBitCount) bits))" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Example/SETabView/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SETabView 4 | // 5 | // Created by eshwavin on 03/13/2020. 6 | // Copyright (c) 2020 eshwavin. 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 throttle down OpenGL ES frame rates. 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 inactive 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 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-SETabView_Example/Pods-SETabView_Example-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Copyright (c) 2020 eshwavin <eshwavin@gmail.com> 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | SETabView 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | Generated by CocoaPods - https://cocoapods.org 47 | Title 48 | 49 | Type 50 | PSGroupSpecifier 51 | 52 | 53 | StringsTable 54 | Acknowledgements 55 | Title 56 | Acknowledgements 57 | 58 | 59 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/output-file-map.json: -------------------------------------------------------------------------------- 1 | { 2 | "": { 3 | "swift-dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/master.swiftdeps" 4 | }, 5 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/Helper.swift": { 6 | "dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper.d", 7 | "object": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper.swift.o", 8 | "swiftmodule": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper~partial.swiftmodule", 9 | "swift-dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/Helper.swiftdeps" 10 | }, 11 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SETabView.swift": { 12 | "dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.d", 13 | "object": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.swift.o", 14 | "swiftmodule": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView~partial.swiftmodule", 15 | "swift-dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.swiftdeps" 16 | }, 17 | "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/Source/SEViewController.swift": { 18 | "dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.d", 19 | "object": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.swift.o", 20 | "swiftmodule": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController~partial.swiftmodule", 21 | "swift-dependencies": "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.swiftdeps" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Source/TabViews/InvertedPlateauTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InvertedPlateauTabView.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 11/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class InvertedPlateauTabView: AnimatedTabView { 12 | 13 | } 14 | 15 | // MARK: Setup 16 | 17 | extension InvertedPlateauTabView { 18 | 19 | override func setupTabLayers() { 20 | super.setupTabLayers() 21 | // setup ball layer 22 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 23 | let ballLayerY = itemHeight * 0.25 - (ballSize * 0.5) 24 | ballLayer.frame = CGRect(x: ballLayerX, y: ballLayerY, width: ballSize, height: ballSize) 25 | ballLayer.cornerRadius = ballSize / 2.0 26 | 27 | // setup shape layer 28 | tabShapeLayer.frame = bounds 29 | tabShapeLayer.path = createInvertedPlateauPath(withOffset: true) 30 | 31 | setupTabImagePositions() 32 | } 33 | 34 | } 35 | 36 | // MARK: Paths 37 | 38 | extension InvertedPlateauTabView { 39 | 40 | private func createInvertedPlateauPath(withOffset: Bool) -> CGPath { 41 | 42 | var startOffset: CGFloat{ 43 | if withOffset { 44 | return (sectionWidth - itemWidth) / 2 45 | } 46 | else { 47 | return 0 48 | } 49 | } 50 | 51 | let coverOffset = CGFloat(numberOfTabs - 1) * sectionWidth 52 | 53 | return SEPathProvider.getInvertedPlateauPath(for: bounds, startOffset: startOffset, coverOffset: coverOffset, itemWidth: itemWidth, sectionHeight: sectionHeight, heightScalingFactor: heightScalingFactor) 54 | } 55 | 56 | 57 | } 58 | 59 | // MARK: Animations 60 | 61 | extension InvertedPlateauTabView { 62 | 63 | override func performAnimations() { 64 | super.performAnimations() 65 | translateBallTriangular() 66 | } 67 | 68 | private func translateBallTriangular() { 69 | 70 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 71 | let ballLayerY = itemHeight * 0.25 - (ballSize * 0.5) 72 | 73 | let previousPosition = ballLayer.position 74 | let newPosition = CGPoint(x: ballLayerX + ballSize / 2, y: ballLayerY + ballSize / 2) 75 | let midPosition = CGPoint(x: (newPosition.x + previousPosition.x) * 0.5 , y: bounds.height * 1.5) 76 | 77 | ballLayer.position = newPosition 78 | 79 | ballLayer.translateTriangular(with: [previousPosition, midPosition, newPosition].map{NSValue(cgPoint: $0)}) 80 | 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/Helper.swiftdeps: -------------------------------------------------------------------------------- 1 | ### Swift dependencies file v0 ### 2 | provides-top-level: 3 | - "SETabViewDelegate" 4 | - "SETabItem" 5 | - "SETabSettings" 6 | - "AnimationTypes" 7 | - "seEaseIn" 8 | - "seEaseOut" 9 | - "seEaseInOut" 10 | provides-nominal: 11 | - "9SETabView0aB8DelegateP" 12 | - "9SETabView0A4ItemP" 13 | - "9SETabView0A8SettingsC" 14 | - "9SETabView14AnimationTypesO" 15 | provides-member: 16 | - ["9SETabView0aB8DelegateP", ""] 17 | - ["9SETabView0A4ItemP", ""] 18 | - ["9SETabView0A8SettingsC", ""] 19 | - ["9SETabView14AnimationTypesO", ""] 20 | provides-dynamic-lookup: 21 | - "animationDuration" 22 | - "ballAnimationDuration" 23 | - "ballColor" 24 | - "changeTintColorAnimationDuration" 25 | - "scaleBallDelayTime" 26 | - "selectedTabTintColor" 27 | - "switchTabAnimationDuration" 28 | - "tabColor" 29 | - "unselectedTabTintColor" 30 | depends-top-level: 31 | - !private "*" 32 | - "==" 33 | - "AnimationTypes" 34 | - "AnyObject" 35 | - "CAMediaTimingFunction" 36 | - "Double" 37 | - "FloatLiteralType" 38 | - "Int" 39 | - !private "IntegerLiteralType" 40 | - "SETabItem" 41 | - "SETabSettings" 42 | - "SETabViewDelegate" 43 | - "UIColor" 44 | - "UIImage" 45 | depends-member: 46 | - ["9SETabView14AnimationTypesO", "=="] 47 | - ["9SETabView14AnimationTypesO", "__derived_enum_equals"] 48 | - ["9SETabView14AnimationTypesO", "_rawHashValue"] 49 | - ["9SETabView14AnimationTypesO", "deinit"] 50 | - ["9SETabView14AnimationTypesO", "hash"] 51 | - ["9SETabView14AnimationTypesO", "hashValue"] 52 | - ["9SETabView14AnimationTypesO", "holeBall1"] 53 | - ["9SETabView14AnimationTypesO", "holeBall2"] 54 | - ["9SETabView14AnimationTypesO", "holeBall3"] 55 | - ["SQ", "=="] 56 | - ["SQ", ""] 57 | - ["SQ", "_rawHashValue"] 58 | - ["SQ", "hash"] 59 | - ["SQ", "hashValue"] 60 | - ["SH", "=="] 61 | - ["SH", ""] 62 | - ["SH", "_rawHashValue"] 63 | - ["SH", "hash"] 64 | - ["SH", "hashValue"] 65 | - !private ["s6HasherV", "combine"] 66 | - ["9SETabView0A4ItemP", "UIImage"] 67 | - ["9SETabView0A8SettingsC", "Double"] 68 | - ["9SETabView0A8SettingsC", "UIColor"] 69 | - ["9SETabView0A8SettingsC", "animationDuration"] 70 | - ["9SETabView0A8SettingsC", "ballAnimationDuration"] 71 | - ["9SETabView0A8SettingsC", "changeTintColorAnimationDuration"] 72 | - ["9SETabView0A8SettingsC", "deinit"] 73 | - ["9SETabView0A8SettingsC", "init"] 74 | - ["9SETabView0A8SettingsC", "scaleBallDelayTime"] 75 | - ["9SETabView0A8SettingsC", "switchTabAnimationDuration"] 76 | - ["9SETabView0aB8DelegateP", "Int"] 77 | - ["9SETabView0aB8DelegateP", "didSelectTab"] 78 | depends-nominal: 79 | - "9SETabView14AnimationTypesO" 80 | - "SQ" 81 | - "SH" 82 | - !private "s6HasherV" 83 | - "9SETabView0A4ItemP" 84 | - "9SETabView0A8SettingsC" 85 | - "9SETabView0aB8DelegateP" 86 | depends-dynamic-lookup: 87 | depends-external: 88 | - "/Users/eshwavin/Documents/App Dev 2019/Custom Tab Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap" 89 | interface-hash: "12aa21835f8bfa2ac5b368eda204cd68" 90 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.d: -------------------------------------------------------------------------------- 1 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView.swift.o : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 2 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView~partial.swiftmodule : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 3 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView~partial.swiftdoc : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 4 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SETabView~partial.swiftsourceinfo : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 5 | -------------------------------------------------------------------------------- /.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.d: -------------------------------------------------------------------------------- 1 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController.swift.o : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 2 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController~partial.swiftmodule : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 3 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController~partial.swiftdoc : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 4 | /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/SEViewController~partial.swiftsourceinfo : /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SEViewController.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/Helper.swift /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/Source/SETabView.swift /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx/prebuilt-modules/SwiftOnoneSupport.swiftmodule/x86_64-apple-macos.swiftmodule /Users/eshwavin/Documents/App\ Dev\ 2019/Custom\ Tab\ Bar/Pod/SETabView/.build/x86_64-apple-macosx/debug/SETabView.build/module.modulemap 5 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Partial SetAlgebra+Basics.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | // `OrderedSet` does not directly conform to `SetAlgebra` because its definition 13 | // of equality conflicts with `SetAlgebra` requirements. However, it still 14 | // implements most `SetAlgebra` requirements (except `insert`, which is replaced 15 | // by `append`). 16 | // 17 | // `OrderedSet` also provides an `unordered` view that explicitly conforms to 18 | // `SetAlgebra`. That view implements `Equatable` by ignoring element order, 19 | // so it can satisfy `SetAlgebra` requirements. 20 | 21 | extension OrderedSet { 22 | /// Creates an empty set. 23 | /// 24 | /// This initializer is equivalent to initializing with an empty array 25 | /// literal. 26 | /// 27 | /// - Complexity: O(1) 28 | @inlinable 29 | public init() { 30 | __storage = nil 31 | _elements = [] 32 | } 33 | } 34 | 35 | extension OrderedSet { 36 | /// Returns a Boolean value that indicates whether the given element exists 37 | /// in the set. 38 | /// 39 | /// - Parameter element: An element to look for in the set. 40 | /// 41 | /// - Returns: `true` if `member` exists in the set; otherwise, `false`. 42 | /// 43 | /// - Complexity: This operation is expected to perform O(1) comparisons on 44 | /// average, provided that `Element` implements high-quality hashing. 45 | @inlinable 46 | public func contains(_ element: Element) -> Bool { 47 | _find_inlined(element).index != nil 48 | } 49 | } 50 | 51 | extension OrderedSet { 52 | /// Removes the given element from the set. 53 | /// 54 | /// - Parameter member: The element of the set to remove. 55 | /// 56 | /// - Returns: The element equal to `member` if `member` is contained in the 57 | /// set; otherwise, `nil`. In some cases, the returned element may be 58 | /// distinguishable from `newMember` by identity comparison or some other 59 | /// means. 60 | /// 61 | /// - Complexity: O(`count`). Removing an element from the middle of the 62 | /// underlying ordered set needs to rearrange the remaining elements to 63 | /// close the resulting gap. 64 | /// 65 | /// Removing the last element only takes (amortized) O(1) 66 | /// hashing/comparisons operations, if `Element` implements high quality 67 | /// hashing. 68 | @inlinable 69 | @discardableResult 70 | public mutating func remove(_ member: Element) -> Element? { 71 | let (idx, bucket) = _find(member) 72 | guard let index = idx else { return nil } 73 | return _removeExistingMember(at: index, in: bucket) 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /Source/OrderedCollections/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #[[ 2 | This source file is part of the Swift Collections Open Source Project 3 | 4 | Copyright (c) 2021 Apple Inc. and the Swift project authors 5 | Licensed under Apache License v2.0 with Runtime Library Exception 6 | 7 | See https://swift.org/LICENSE.txt for license information 8 | #]] 9 | 10 | add_library(OrderedCollections 11 | "HashTable/_HashTable.swift" 12 | "HashTable/_HashTable+Bucket.swift" 13 | "HashTable/_HashTable+BucketIterator.swift" 14 | "HashTable/_HashTable+Constants.swift" 15 | "HashTable/_HashTable+CustomStringConvertible.swift" 16 | "HashTable/_Hashtable+Header.swift" 17 | "HashTable/_HashTable+Testing.swift" 18 | "HashTable/_HashTable+UnsafeHandle.swift" 19 | 20 | "OrderedDictionary/OrderedDictionary.swift" 21 | "OrderedDictionary/OrderedDictionary+Codable.swift" 22 | "OrderedDictionary/OrderedDictionary+CustomDebugStringConvertible.swift" 23 | "OrderedDictionary/OrderedDictionary+CustomReflectable.swift" 24 | "OrderedDictionary/OrderedDictionary+CustomStringConvertible.swift" 25 | "OrderedDictionary/OrderedDictionary+Elements+SubSequence.swift" 26 | "OrderedDictionary/OrderedDictionary+Elements.swift" 27 | "OrderedDictionary/OrderedDictionary+Equatable.swift" 28 | "OrderedDictionary/OrderedDictionary+ExpressibleByDictionaryLiteral.swift" 29 | "OrderedDictionary/OrderedDictionary+Hashable.swift" 30 | "OrderedDictionary/OrderedDictionary+Initializers.swift" 31 | "OrderedDictionary/OrderedDictionary+Invariants.swift" 32 | "OrderedDictionary/OrderedDictionary+Partial MutableCollection.swift" 33 | "OrderedDictionary/OrderedDictionary+Partial RangeReplaceableCollection.swift" 34 | "OrderedDictionary/OrderedDictionary+Sequence.swift" 35 | "OrderedDictionary/OrderedDictionary+Values.swift" 36 | "OrderedDictionary/OrderedDictionary+Deprecations.swift" 37 | 38 | "OrderedSet/OrderedSet.swift" 39 | "OrderedSet/OrderedSet+Codable.swift" 40 | "OrderedSet/OrderedSet+CustomDebugStringConvertible.swift" 41 | "OrderedSet/OrderedSet+CustomReflectable.swift" 42 | "OrderedSet/OrderedSet+CustomStringConvertible.swift" 43 | "OrderedSet/OrderedSet+Diffing.swift" 44 | "OrderedSet/OrderedSet+Equatable.swift" 45 | "OrderedSet/OrderedSet+ExpressibleByArrayLiteral.swift" 46 | "OrderedSet/OrderedSet+Hashable.swift" 47 | "OrderedSet/OrderedSet+Initializers.swift" 48 | "OrderedSet/OrderedSet+Insertions.swift" 49 | "OrderedSet/OrderedSet+Invariants.swift" 50 | "OrderedSet/OrderedSet+Partial MutableCollection.swift" 51 | "OrderedSet/OrderedSet+Partial RangeReplaceableCollection.swift" 52 | "OrderedSet/OrderedSet+Partial SetAlgebra+Basics.swift" 53 | "OrderedSet/OrderedSet+Partial SetAlgebra+Operations.swift" 54 | "OrderedSet/OrderedSet+Partial SetAlgebra+Predicates.swift" 55 | "OrderedSet/OrderedSet+RandomAccessCollection.swift" 56 | "OrderedSet/OrderedSet+ReserveCapacity.swift" 57 | "OrderedSet/OrderedSet+SubSequence.swift" 58 | "OrderedSet/OrderedSet+Testing.swift" 59 | "OrderedSet/OrderedSet+UnorderedView.swift" 60 | "OrderedSet/OrderedSet+UnstableInternals.swift" 61 | 62 | "Utilities/_UnsafeBitset.swift" 63 | "Utilities/RandomAccessCollection+Offsets.swift") 64 | set_target_properties(OrderedCollections PROPERTIES 65 | INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) 66 | 67 | _install_target(OrderedCollections) 68 | set_property(GLOBAL APPEND PROPERTY SWIFT_COLLECTIONS_EXPORTS OrderedCollections) 69 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_HashTable+Constants.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension _HashTable { 13 | /// The minimum hash table scale. 14 | @usableFromInline 15 | @inline(__always) 16 | internal static var minimumScale: Int { 17 | @_effects(readnone) 18 | get { 19 | 5 20 | } 21 | } 22 | 23 | /// The maximum hash table scale. 24 | @usableFromInline 25 | @inline(__always) 26 | internal static var maximumScale: Int { 27 | @_effects(readnone) 28 | get { 29 | Swift.min(Int.bitWidth, 56) 30 | } 31 | } 32 | 33 | /// The maximum number of items for which we do not create a hash table. 34 | @usableFromInline 35 | @inline(__always) 36 | internal static var maximumUnhashedCount: Int { 37 | @_effects(readnone) 38 | get { 39 | (1 &<< (minimumScale - 1)) - 1 40 | } 41 | } 42 | 43 | /// The maximum hash table load factor. 44 | @inline(__always) 45 | internal static var maximumLoadFactor: Double { 3 / 4 } 46 | 47 | /// The minimum hash table load factor. 48 | @inline(__always) 49 | internal static var minimumLoadFactor: Double { 1 / 4 } 50 | 51 | /// The maximum number of items that can be held in a hash table of the given scale. 52 | @usableFromInline 53 | @_effects(readnone) 54 | internal static func minimumCapacity(forScale scale: Int) -> Int { 55 | guard scale >= minimumScale else { return 0 } 56 | let bucketCount = 1 &<< scale 57 | return Int(Double(bucketCount) * minimumLoadFactor) 58 | } 59 | 60 | /// The maximum number of items that can be held in a hash table of the given scale. 61 | @usableFromInline 62 | @_effects(readnone) 63 | internal static func maximumCapacity(forScale scale: Int) -> Int { 64 | guard scale >= minimumScale else { return maximumUnhashedCount } 65 | let bucketCount = 1 &<< scale 66 | return Int(Double(bucketCount) * maximumLoadFactor) 67 | } 68 | 69 | /// The minimum hash table scale that can hold the specified number of elements. 70 | @usableFromInline 71 | @_effects(readnone) 72 | internal static func scale(forCapacity capacity: Int) -> Int { 73 | guard capacity > maximumUnhashedCount else { return 0 } 74 | let capacity = Swift.max(capacity, 1) 75 | // Calculate the minimum number of entries we need to allocate to satisfy 76 | // the maximum load factor. `capacity + 1` below ensures that we always 77 | // leave at least one hole. 78 | let minimumEntries = Swift.max( 79 | Int((Double(capacity) / maximumLoadFactor).rounded(.up)), 80 | capacity + 1) 81 | // The actual number of entries we need to allocate is the lowest power of 82 | // two greater than or equal to the minimum entry count. Calculate its 83 | // exponent. 84 | let scale = (Swift.max(minimumEntries, 2) - 1)._binaryLogarithm() + 1 85 | assert(scale >= minimumScale && scale < Int.bitWidth) 86 | // The scale is the exponent corresponding to the bucket count. 87 | assert(self.maximumCapacity(forScale: scale) >= capacity) 88 | return scale 89 | } 90 | 91 | /// The count of 64-bit words that a hash table of the specified scale 92 | /// will need to have in its storage. 93 | internal static func wordCount(forScale scale: Int) -> Int { 94 | ((scale &<< scale) + 63) / 64 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /Source/Reusable/SELayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SELayer.swift 3 | // SETabView 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 12/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class SELayer: CALayer { 12 | 13 | func scale() { 14 | 15 | let animation = SELayerAnimationProvider.getScaleAnimation(runningFor: SETabSettings.current.ballAnimationDuration, fromValue: 0.5, toValue: 1.0, timingFunction: CAMediaTimingFunction(name: CAMediaTimingFunctionName.default), fillMode: .both, beginTime: CACurrentMediaTime() + SETabSettings.current.scaleBallDelayTime, isRemovedOnCompletion: true) 16 | 17 | add(animation, forKey: nil) 18 | 19 | } 20 | 21 | func moveUp(to toValue: CGFloat) { 22 | let moveUpAnimation = SELayerAnimationProvider.getTranslateYAnimation(runningFor: SETabSettings.current.changeTintColorAnimationDuration, fromValue: nil, toValue: toValue, timingFunction: SETimingFunction.seEaseInOut, fillMode: .both, isRemovedOnCompletion: false) 23 | 24 | 25 | add(moveUpAnimation, forKey: nil) 26 | 27 | } 28 | 29 | func highlight(inDuration duration: Double = SETabSettings.current.changeTintColorAnimationDuration) { 30 | let highlightAnimation = SELayerAnimationProvider.getBackgroundChangeAnimation(runningFor: duration, toValue: SETabSettings.current.tintColor.cgColor, timingFunction: SETimingFunction.seEaseInOut, fillMode: .both, isRemovedOnCompletion: false) 31 | 32 | add(highlightAnimation, forKey: nil) 33 | } 34 | 35 | func moveDown(to toValue: CGFloat) { 36 | let downMovementAnimation = SELayerAnimationProvider.getTranslateYAnimation(runningFor: SETabSettings.current.changeTintColorAnimationDuration, toValue: toValue, timingFunction: SETimingFunction.seEaseInOut, fillMode: .both, isRemovedOnCompletion: false) 37 | 38 | add(downMovementAnimation, forKey: nil) 39 | 40 | } 41 | 42 | func removeHighlight(inDuration duration: Double = SETabSettings.current.changeTintColorAnimationDuration) { 43 | let removeHighlightAnimation = SELayerAnimationProvider.getBackgroundChangeAnimation(runningFor: duration, toValue: SETabSettings.current.unselectedItemTintColor.cgColor, timingFunction: SETimingFunction.seEaseInOut, fillMode: .both, isRemovedOnCompletion: false) 44 | 45 | add(removeHighlightAnimation, forKey: nil) 46 | 47 | } 48 | 49 | func translateLinear(to toValue: CGFloat) { 50 | let linearAnimation = SELayerAnimationProvider.getTranslateXAnimation(runningFor: SETabSettings.current.ballAnimationDuration, toValue: toValue, timingFunction: SETimingFunction.seEaseInOut, fillMode: .both, isRemovedOnCompletion: false) 51 | 52 | 53 | add(linearAnimation, forKey: nil) 54 | 55 | } 56 | 57 | func translateTriangular(with values: [NSValue]) { 58 | let translateTriangularAnimation = SELayerAnimationProvider.getKeyframePositionAnimation(runningFor: SETabSettings.current.ballAnimationDuration, values: values, keyTimes: [0.0, 0.5, 1.0], timingFunctions: [SETimingFunction.seEaseIn, SETimingFunction.seEaseOut], fillMode: .forwards) 59 | 60 | 61 | add(translateTriangularAnimation, forKey: nil) 62 | } 63 | 64 | func moveInPath(_ path: CGPath?, fillMode: CAMediaTimingFillMode = .removed) { 65 | let rotateAnimation = SELayerAnimationProvider.getKeyframePositionAnimation(runningFor: SETabSettings.current.ballAnimationDuration, path: path, timingFunction: SETimingFunction.seEaseInOut, fillMode: fillMode, isRemovedOnCompletion: false) 66 | 67 | add(rotateAnimation, forKey: nil) 68 | } 69 | 70 | } 71 | 72 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Codable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary: Encodable where Key: Encodable, Value: Encodable { 13 | /// Encodes the contents of this dictionary into the given encoder. 14 | /// 15 | /// The dictionary's contents are encoded as alternating key-value pairs in 16 | /// an unkeyed container. 17 | /// 18 | /// This function throws an error if any values are invalid for the given 19 | /// encoder's format. 20 | /// 21 | /// - Note: Unlike the standard `Dictionary` type, ordered dictionaries 22 | /// always encode themselves into an unkeyed container, because 23 | /// `Codable`'s keyed containers do not guarantee that they preserve the 24 | /// ordering of the items they contain. (And in popular encoding formats, 25 | /// keyed containers tend to map to unordered data structures -- e.g., 26 | /// JSON's "object" construct is explicitly unordered.) 27 | /// 28 | /// - Parameter encoder: The encoder to write data to. 29 | @inlinable 30 | public func encode(to encoder: Encoder) throws { 31 | // Encode contents as an array of alternating key-value pairs. 32 | var container = encoder.unkeyedContainer() 33 | for (key, value) in self { 34 | try container.encode(key) 35 | try container.encode(value) 36 | } 37 | } 38 | } 39 | 40 | extension OrderedDictionary: Decodable where Key: Decodable, Value: Decodable { 41 | /// Creates a new dictionary by decoding from the given decoder. 42 | /// 43 | /// `OrderedDictionary` expects its contents to be encoded as alternating 44 | /// key-value pairs in an unkeyed container. 45 | /// 46 | /// This initializer throws an error if reading from the decoder fails, or 47 | /// if the decoded contents are not in the expected format. 48 | /// 49 | /// - Note: Unlike the standard `Dictionary` type, ordered dictionaries 50 | /// always encode themselves into an unkeyed container, because 51 | /// `Codable`'s keyed containers do not guarantee that they preserve the 52 | /// ordering of the items they contain. (And in popular encoding formats, 53 | /// keyed containers tend to map to unordered data structures -- e.g., 54 | /// JSON's "object" construct is explicitly unordered.) 55 | /// 56 | /// - Parameter decoder: The decoder to read data from. 57 | @inlinable 58 | public init(from decoder: Decoder) throws { 59 | // We expect to be encoded as an array of alternating key-value pairs. 60 | var container = try decoder.unkeyedContainer() 61 | 62 | self.init() 63 | while !container.isAtEnd { 64 | let key = try container.decode(Key.self) 65 | let (index, bucket) = self._keys._find(key) 66 | guard index == nil else { 67 | let context = DecodingError.Context( 68 | codingPath: container.codingPath, 69 | debugDescription: "Duplicate key at offset \(container.currentIndex - 1)") 70 | throw DecodingError.dataCorrupted(context) 71 | } 72 | 73 | guard !container.isAtEnd else { 74 | throw DecodingError.dataCorrupted( 75 | DecodingError.Context( 76 | codingPath: container.codingPath, 77 | debugDescription: "Unkeyed container reached end before value in key-value pair" 78 | ) 79 | ) 80 | } 81 | let value = try container.decode(Value.self) 82 | _keys._appendNew(key, in: bucket) 83 | _values.append(value) 84 | } 85 | _checkInvariants() 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Example/SETabView/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_Hashtable+Header.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension _HashTable { 13 | /// The storage header for hash table buffers. 14 | /// 15 | /// Note that we don't store the number of items currently in the table; 16 | /// that information can be easily retrieved from the element storage. 17 | @usableFromInline 18 | internal struct Header { 19 | /// We are packing the scale data into the lower bits of the seed & bias 20 | /// to saves a bit of space that would be otherwise taken up by padding. 21 | /// 22 | /// Layout: 23 | /// 24 | /// 63 6 5 0 25 | /// ├──────────────────────────────────────────────┼────────┤ 26 | /// │ seed │ scale │ 27 | /// └──────────────────────────────────────────────┴────────┘ 28 | /// 63 6 5 0 29 | /// ├──────────────────────────────────────────────┼────────┤ 30 | /// │ bias │ rsvd │ 31 | /// └──────────────────────────────────────────────┴────────┘ 32 | @usableFromInline 33 | var _scaleAndSeed: UInt64 34 | @usableFromInline 35 | var _reservedScaleAndBias: UInt64 36 | 37 | init(scale: Int, reservedScale: Int, seed: Int) { 38 | assert(scale >= _HashTable.minimumScale && scale <= _HashTable.maximumScale) 39 | assert(reservedScale >= 0 && reservedScale <= _HashTable.maximumScale) 40 | _scaleAndSeed = UInt64(truncatingIfNeeded: seed) << (Swift.max(UInt64.bitWidth - Int.bitWidth, 6)) 41 | _scaleAndSeed &= ~0x3F 42 | _scaleAndSeed |= UInt64(truncatingIfNeeded: scale) 43 | _reservedScaleAndBias = UInt64(truncatingIfNeeded: reservedScale) 44 | assert(self.scale == scale) 45 | assert(self.reservedScale == reservedScale) 46 | assert(self.bias == 0) 47 | } 48 | 49 | /// The scale of the hash table. A table of scale *n* holds 2^*n* buckets, 50 | /// each of which contain an *n*-bit value. 51 | @inlinable 52 | @inline(__always) 53 | var scale: Int { Int(_scaleAndSeed & 0x3F) } 54 | 55 | /// The scale corresponding to the last call to `reserveCapacity`. 56 | /// We remember this here to make sure we don't shrink the table below its reserved size. 57 | @inlinable 58 | var reservedScale: Int { 59 | @inline(__always) 60 | get { Int(_reservedScaleAndBias & 0x3F) } 61 | set { 62 | assert(newValue >= 0 && newValue < 64) 63 | _reservedScaleAndBias &= ~0x3F 64 | _reservedScaleAndBias |= UInt64(truncatingIfNeeded: newValue) & 0x3F 65 | } 66 | } 67 | 68 | /// The hasher seed to use within this hash table. 69 | @inlinable 70 | @inline(__always) 71 | var seed: Int { 72 | Int(truncatingIfNeeded: _scaleAndSeed) 73 | } 74 | 75 | /// A bias value that needs to be added to buckets to convert them into offsets 76 | /// into element storage. (This allows O(1) insertions at the front when the 77 | /// underlying storage supports it.) 78 | @inlinable 79 | var bias: Int { 80 | @inline(__always) 81 | get { Int(truncatingIfNeeded: _reservedScaleAndBias) &>> 6 } 82 | set { 83 | let limit = (1 &<< scale) - 1 84 | var bias = newValue 85 | if bias < 0 { bias += limit } 86 | if bias >= limit { bias -= limit } 87 | assert(bias >= 0 && bias < limit) 88 | _reservedScaleAndBias &= 0x3F 89 | _reservedScaleAndBias |= UInt64(truncatingIfNeeded: bias) &<< 6 90 | assert(self.bias >= 0 && self.bias < limit) 91 | } 92 | } 93 | 94 | /// The maximum number of items that can fit into this table. 95 | @inlinable 96 | @inline(__always) 97 | var capacity: Int { _HashTable.maximumCapacity(forScale: scale) } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Testing.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet._UnstableInternals { 13 | @_spi(Testing) public var capacity: Int { base._capacity } 14 | @_spi(Testing) public var minimumCapacity: Int { base._minimumCapacity } 15 | @_spi(Testing) public var scale: Int { base._scale } 16 | @_spi(Testing) public var reservedScale: Int { base._reservedScale } 17 | @_spi(Testing) public var bias: Int { base._bias } 18 | } 19 | 20 | extension OrderedSet { 21 | @_spi(Testing) 22 | @_alwaysEmitIntoClient 23 | public static var _minimumScale: Int { 24 | _HashTable.minimumScale 25 | } 26 | 27 | @_spi(Testing) 28 | @_alwaysEmitIntoClient 29 | public static func _minimumCapacity(forScale scale: Int) -> Int { 30 | _HashTable.minimumCapacity(forScale: scale) 31 | } 32 | 33 | @_spi(Testing) 34 | @_alwaysEmitIntoClient 35 | public static func _maximumCapacity(forScale scale: Int) -> Int { 36 | _HashTable.maximumCapacity(forScale: scale) 37 | } 38 | 39 | @_spi(Testing) 40 | @_alwaysEmitIntoClient 41 | public static func _scale(forCapacity capacity: Int) -> Int { 42 | _HashTable.scale(forCapacity: capacity) 43 | } 44 | 45 | @_spi(Testing) 46 | @_alwaysEmitIntoClient 47 | public static func _biasRange(scale: Int) -> Range { 48 | guard scale != 0 else { return Range(uncheckedBounds: (0, 1)) } 49 | return Range(uncheckedBounds: (0, (1 &<< scale) - 1)) 50 | } 51 | } 52 | 53 | extension OrderedSet._UnstableInternals { 54 | @_spi(Testing) 55 | @_alwaysEmitIntoClient 56 | public var hasHashTable: Bool { base._table != nil } 57 | 58 | @_spi(Testing) 59 | @_alwaysEmitIntoClient 60 | public var hashTableIdentity: ObjectIdentifier? { 61 | guard let storage = base.__storage else { return nil } 62 | return ObjectIdentifier(storage) 63 | } 64 | 65 | @_spi(Testing) 66 | public var hashTableContents: [Int?] { 67 | guard let table = base._table else { return [] } 68 | return table.read { hashTable in 69 | hashTable.debugContents() 70 | } 71 | } 72 | 73 | @_spi(Testing) 74 | @_alwaysEmitIntoClient 75 | mutating public func _regenerateHashTable(bias: Int) { 76 | base._ensureUnique() 77 | let new = base._table!.copy() 78 | base._table!.read { source in 79 | new.update { target in 80 | target.bias = bias 81 | var it = source.bucketIterator(startingAt: _Bucket(offset: 0)) 82 | repeat { 83 | target[it.currentBucket] = it.currentValue 84 | it.advance() 85 | } while it.currentBucket.offset != 0 86 | } 87 | } 88 | base._table = new 89 | base._checkInvariants() 90 | } 91 | 92 | @_spi(Testing) 93 | @_alwaysEmitIntoClient 94 | public mutating func reserveCapacity( 95 | _ minimumCapacity: Int, 96 | persistent: Bool 97 | ) { 98 | base._reserveCapacity(minimumCapacity, persistent: persistent) 99 | base._checkInvariants() 100 | } 101 | } 102 | 103 | extension OrderedSet { 104 | @_spi(Testing) 105 | public init( 106 | _scale scale: Int, 107 | bias: Int, 108 | contents: S 109 | ) where S.Element == Element { 110 | let contents = ContiguousArray(contents) 111 | precondition(scale >= _HashTable.scale(forCapacity: contents.count)) 112 | precondition(scale <= _HashTable.maximumScale) 113 | precondition(bias >= 0 && Self._biasRange(scale: scale).contains(bias)) 114 | precondition(scale >= _HashTable.minimumScale || bias == 0) 115 | let table = _HashTable(scale: Swift.max(scale, _HashTable.minimumScale)) 116 | table.header.bias = bias 117 | let (success, index) = table.update { hashTable in 118 | hashTable.fill(untilFirstDuplicateIn: contents) 119 | } 120 | precondition(success, "Duplicate element at index \(index)") 121 | self.init( 122 | _uniqueElements: contents, 123 | scale < _HashTable.minimumScale ? nil : table) 124 | precondition(self._scale == scale) 125 | precondition(self._bias == bias) 126 | _checkInvariants() 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Diffing.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet { 13 | /// Returns the collection difference between the parameter and the 14 | /// receiver, using an algorithm specialized to exploit fast membership 15 | /// testing and the member uniqueness guarantees of `OrderedSet`. 16 | /// 17 | /// - Complexity: O(`self.count + other.count`) 18 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 19 | public func difference( 20 | from other: Self 21 | ) -> CollectionDifference { 22 | /* While admitting that variables with names like "a", "b", "x", and "y" are not especially readable, their use (and meaning) is standard in the diffing literature and familiarity with that literature will help if you're reading this code anyway. */ 23 | let a = other // The collection we're diffing "from". An element present in this collection but not the other is a "remove" 24 | var x = 0 // The working index into `a` 25 | let b = self // The collection we're diffing "to". An element present in this collection but not the other is an "insert" 26 | var y = 0 // The working index into `b` 27 | 28 | var changes = Array.Change>() 29 | func remove() { 30 | let ax = a[x] 31 | changes.append(.remove(offset: x, element: ax, associatedWith: b.lastIndex(of: ax))) 32 | x += 1 33 | } 34 | func insert() { 35 | let by = b[y] 36 | changes.append(.insert(offset: y, element: by, associatedWith: a.lastIndex(of: by))) 37 | y += 1 38 | } 39 | 40 | while x < a.count || y < b.count { 41 | if y == b.count { 42 | // No more elements to process in `b`, `a[x]` must have been removed 43 | remove() 44 | } else if x == a.count { 45 | // No more elements to process in `a`, `b[y]` must have been inserted 46 | insert() 47 | } else if let axinb = b.lastIndex(of: a[x]) { 48 | if axinb < y { 49 | // Element has already been processed as an insertion in `b`, generate associated remove for move 50 | remove() 51 | } 52 | else if let byina = a.lastIndex(of: b[y]) { 53 | if byina < x { 54 | // Element has already been processed as a remove in `a`, generate associated insert for move 55 | insert() 56 | } else if x == byina { 57 | assert(y == axinb) 58 | // `a[x]` == `b[y]` 59 | x += 1; y += 1 60 | } else if byina - x < axinb - y { 61 | // `a[x]` exists further away from the current position in `b` than `b[y] does in `a` 62 | insert() 63 | } else { 64 | // `b[y]` exists further away from the current position in `a` than `a[x]` does in `b` 65 | remove() 66 | } 67 | } else { 68 | // `b[y]` does not exist in `a`, the element must have been inserted 69 | insert() 70 | } 71 | } else { 72 | // `a[x]` does not exist in `b`, the element must have been removed 73 | remove() 74 | } 75 | } 76 | return CollectionDifference(changes)! 77 | } 78 | 79 | /* Replicating RangeReplaceableCollection.applying here would involve 80 | * duplicating a ton of IPI from the stdlib. Dropping down to Array and back 81 | * to OrderedSet is still O(n)-ish which still beats the naïve application 82 | * algorithm of "remove, then insert" 83 | */ 84 | /// Applies the given difference to this collection. 85 | /// 86 | /// - Parameter difference: The difference to be applied. 87 | /// 88 | /// - Returns: An instance representing the state of the receiver with the 89 | /// difference applied, or `nil` if the difference is incompatible with 90 | /// the receiver's state. 91 | /// 92 | /// - Complexity: O(*n* + *c*), where *n* is `self.count` and *c* 93 | /// is the number of changes contained by the parameter. 94 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 95 | public func applying(_ difference: CollectionDifference) -> Self? { 96 | guard let array = self.elements.applying(difference) else { return nil } 97 | let result = OrderedSet(array) 98 | return result.count == array.count ? result : nil 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Example/SETabView.xcodeproj/xcshareddata/xcschemes/SETabView-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 51 | 52 | 53 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 76 | 78 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /README_olderVersions.md: -------------------------------------------------------------------------------- 1 | [![CI Status](https://img.shields.io/travis/eshwavin/SETabView.svg?style=flat)](https://travis-ci.org/eshwavin/SETabView) 2 | [![Version](https://img.shields.io/cocoapods/v/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 3 | [![License](https://img.shields.io/cocoapods/l/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 4 | [![Platform](https://img.shields.io/cocoapods/p/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 5 | 6 | ## Animations 7 | 8 | .holeBall1 | .holeBall2 | .holeBall3 9 | ---------| --------------|---------| 10 | | | 11 | 12 | ## Requirements 13 | 14 | - Swift 5+ 15 | - iOS 11.0+ 16 | - Swift tools version 5.0+ (For Swift Package Manager) 17 | 18 | ## Integration 19 | 20 | ### CocoaPods 21 | 22 | SETabView is available through [CocoaPods](https://cocoapods.org). To install 23 | it, simply add the following line to your Podfile: 24 | 25 | ```ruby 26 | pod 'SETabView' 27 | ``` 28 | 29 | In case the latest version (0.3.0) is not the one being installed, update the pod. 30 | 31 | ``` 32 | pod update 'SETabView' 33 | ``` 34 | 35 | ### Swift Package Manager 36 | 37 | The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. 38 | 39 | Once you have your Swift package set up, adding SETabView as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. 40 | 41 | ```swift 42 | dependencies: [ 43 | .package(url: "https://github.com/eshwavin/SETabView.git", .upToNextMajor(from: "0.3.0")) 44 | ] 45 | ``` 46 | 47 | ### Directly include source files 48 | 49 | Download and add the files in the [Source](https://github.com/eshwavin/SETabView/tree/master/Source) folder directly into your Xcode Project. In this case you should **skip** 50 | 51 | ```swift 52 | import SETabView 53 | ``` 54 | 55 | in the usage instructions. 56 | 57 | ## Usage 58 | 59 | Import `VCTabView` into the parent ViewController and any child View Controllers 60 | 61 | ```swift 62 | import SETabView 63 | ``` 64 | 65 | Inherit the `SEViewController` class in the parent ViewController 66 | ```swift 67 | class ViewController: SEViewController { 68 | 69 | override func viewDidLoad() { 70 | super.viewDidLoad() 71 | 72 | } 73 | } 74 | ``` 75 | 76 | In `viewDidLoad` of the parent ViewController, set the child ViewControllers. 77 | 78 | ```swift 79 | class ViewController: SEViewController { 80 | 81 | override func viewDidLoad() { 82 | super.viewDidLoad() 83 | // set the child View Controllers 84 | setViewControllers() 85 | 86 | } 87 | 88 | private func setViewControllers() { 89 | 90 | // instantiate the child View Controllers 91 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 92 | let firstVC = storyboard.instantiateViewController(withIdentifier: "firstVC") 93 | let secondVC = storyboard.instantiateViewController(withIdentifier: "secondVC") 94 | let thirdVC = storyboard.instantiateViewController(withIdentifier: "thirdVC") 95 | let fourthVC = storyboard.instantiateViewController(withIdentifier: "fourthVC") 96 | 97 | // assign the child View Controllers 98 | self.viewControllers = [firstVC, secondVC, thirdVC, fourthVC] 99 | 100 | } 101 | 102 | } 103 | ``` 104 | The child ViewControllers need to conform to the `SETabItem` protocol 105 | 106 | ```swift 107 | class FirstViewController: UIViewController, SETabItem { 108 | 109 | var tabImage: UIImage? { 110 | return UIImage(named: "first") 111 | } 112 | 113 | override func viewDidLoad() { 114 | super.viewDidLoad() 115 | } 116 | } 117 | ``` 118 | 119 | The selected tab can be changed programmatically 120 | 121 | ```swift 122 | self.selectedTabIndex = 3 123 | ``` 124 | 125 | ## Customization 126 | 127 | Customise the appearance and animation type of the TabBar by overriding the `setTabSettings()` and `setAnimationType()` functions in the parent ViewController 128 | ```swift 129 | override func setTabSettings() { 130 | 131 | // customise tab bar appearance 132 | SETabView.settings.tabColor = UIColor.black 133 | SETabView.settings.ballColor = UIColor.black 134 | SETabView.settings.selectedTabTintColor = UIColor.white 135 | SETabView.settings.unselectedTabTintColor = UIColor.gray 136 | 137 | // customise animation duration 138 | SETabView.settings.animationDuration = 1.5 // optimal duration = 1.5 139 | } 140 | 141 | override func setAnimationType() { 142 | self.animationType = .holeBall3 // defaults to .holeBall3 143 | } 144 | ``` 145 | 146 | ## Restrictions 147 | 148 | - Max 5 Tabs 149 | - Tab Bar look cannot be changed once set in `setTabSettings()` 150 | 151 | ## Example 152 | 153 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 154 | 155 | ## Author 156 | 157 | Srivinayak Chaitanya Eshwa, eshwavin@gmail.com 158 | 159 | ## License 160 | 161 | SETabView is available under the MIT license. See the LICENSE file for more info. 162 | 163 | ## Acknowledgement 164 | 165 | [Animation Inspiration](https://www.behance.net/gallery/79473185/25-Animated-Tab-Bar-Designs-for-Inspiration) 166 | 167 | [Icons](https://www.flaticon.com/authors/nikita-golubev) 168 | -------------------------------------------------------------------------------- /Source/TabViews/MorphPlateauTabView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MorphPlateauTabView.swift 3 | // SETabViewControl 4 | // 5 | // Created by Srivinayak Chaitanya Eshwa on 11/08/20. 6 | // Copyright © 2020 Srivinayak Chaitanya Eshwa. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | final class MorphPlateauTabView: AnimatedTabView { 12 | 13 | // MARK: Properties: Layer 14 | private var ballLayerReplica = SELayer() 15 | 16 | // MARK: Properties: Path 17 | private var invertedPlateauPath: CGPath? 18 | private var rectangularMorphPath: CGPath? 19 | private var bumpPath: CGPath? 20 | 21 | override func layoutSubviewsAfterSetup() { 22 | super.layoutSubviewsAfterSetup() 23 | rotateBall() 24 | } 25 | } 26 | 27 | // MARK: Colors 28 | 29 | extension MorphPlateauTabView { 30 | override func setBallColor() { 31 | super.setBallColor() 32 | ballLayerReplica.backgroundColor = SETabSettings.current.ballColor.cgColor 33 | } 34 | } 35 | 36 | // MARK: Setup 37 | 38 | extension MorphPlateauTabView { 39 | 40 | override func setupView() { 41 | super.setupView() 42 | layer.insertSublayer(ballLayerReplica, below: ballLayer) 43 | } 44 | 45 | override func setupTabLayers() { 46 | super.setupTabLayers() 47 | // setup ball layer 48 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 49 | let ballLayerY = itemHeight * 0.25 - (ballSize * 0.5) 50 | ballLayer.frame = CGRect(x: ballLayerX, y: ballLayerY, width: ballSize, height: ballSize) 51 | ballLayer.cornerRadius = ballSize / 2.0 52 | 53 | // setup shape layer 54 | tabShapeLayer.frame = bounds 55 | tabShapeLayer.path = createInvertedPlateauPath(withOffset: true) 56 | 57 | // setup replica ball layer 58 | ballLayerReplica.frame = CGRect(x: 200, y: 200, width: ballLayer.bounds.width, height: ballLayer.bounds.height) 59 | ballLayerReplica.cornerRadius = ballSize / 2.0 60 | 61 | self.invertedPlateauPath = self.createInvertedPlateauPath(withOffset: true) 62 | self.bumpPath = self.createBumpMorph() 63 | self.rectangularMorphPath = self.createRectangularMorphForPlateau() 64 | 65 | setupTabImagePositions() 66 | } 67 | 68 | } 69 | 70 | // MARK: Paths 71 | 72 | extension MorphPlateauTabView { 73 | 74 | private func createInvertedPlateauPath(withOffset: Bool) -> CGPath { 75 | 76 | var startOffset: CGFloat{ 77 | if withOffset { 78 | return (sectionWidth - itemWidth) / 2 79 | } 80 | else { 81 | return 0 82 | } 83 | } 84 | 85 | let coverOffset = CGFloat(numberOfTabs - 1) * sectionWidth 86 | 87 | return SEPathProvider.getInvertedPlateauPath(for: bounds, startOffset: startOffset, coverOffset: coverOffset, itemWidth: itemWidth, sectionHeight: sectionHeight, heightScalingFactor: heightScalingFactor) 88 | 89 | } 90 | 91 | private func createRectangularMorphForPlateau() -> CGPath{ 92 | 93 | let startOffset: CGFloat = (sectionWidth - itemWidth) / 2 94 | let coverOffset = CGFloat(numberOfTabs - 1) * sectionWidth 95 | 96 | return SEPathProvider.getRectangularMorphForPlateau(for: bounds, startOffset: startOffset, coverOffset: coverOffset, itemWidth: itemWidth, sectionHeight: sectionHeight) 97 | 98 | } 99 | 100 | private func createBumpMorph() -> CGPath { 101 | 102 | let startOffset: CGFloat = (sectionWidth - itemWidth) / 2 103 | let coverOffset = CGFloat(numberOfTabs - 1) * sectionWidth 104 | 105 | return SEPathProvider.getBumpMorph(for: bounds, startOffset: startOffset, coverOffset: coverOffset, itemWidth: itemWidth, sectionHeight: sectionHeight, heightScalingFactor: heightScalingFactor) 106 | 107 | } 108 | 109 | private func createRotateBallPaths() -> [String: CGPath] { 110 | 111 | return SEPathProvider.createRotateBallPaths(forSelectedIndex: selectedTabIndex, previousTabIndex: previousTabIndex, sectionWidth: sectionWidth, ballLayerYPosition: ballLayer.position.y) 112 | 113 | } 114 | 115 | } 116 | 117 | // MARK: Animations 118 | 119 | extension MorphPlateauTabView { 120 | 121 | override func performAnimations() { 122 | super.performAnimations() 123 | if (abs(previousTabIndex - selectedTabIndex) == 1) { 124 | rotateBall() 125 | } 126 | else { 127 | morphShapeLayer() 128 | translateBallLinear() 129 | } 130 | } 131 | 132 | private func morphShapeLayer() { 133 | 134 | tabShapeLayer.morph(using: [invertedPlateauPath!, rectangularMorphPath!, bumpPath!, bumpPath!, rectangularMorphPath!, invertedPlateauPath!]) 135 | 136 | } 137 | 138 | private func translateBallLinear() { 139 | 140 | let ballLayerX = sectionWidth * 0.5 - (ballSize * 0.5) + (CGFloat(selectedTabIndex) * sectionWidth) 141 | let toValue = ballLayerX + ballSize / 2 142 | 143 | ballLayer.translateLinear(to: toValue) 144 | } 145 | 146 | private func rotateBall() { 147 | 148 | let rotatePaths = createRotateBallPaths() 149 | 150 | ballLayerReplica.moveInPath(rotatePaths["hide"]) 151 | ballLayer.moveInPath(rotatePaths["show"], fillMode: .both) 152 | 153 | } 154 | 155 | } 156 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+ReserveCapacity.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet { 13 | /// Creates an empty set with preallocated space for at least the 14 | /// specified number of elements. 15 | /// 16 | /// Use this initializer to avoid intermediate reallocations of a 17 | /// set's storage buffer when you know in advance how many elements 18 | /// you'll insert into the set after creation. 19 | /// 20 | /// If you have a good idea of the expected working size of the set, calling 21 | /// this initializer with `persistent` set to true can sometimes improve 22 | /// performance by eliminating churn due to repeated rehashings when the set 23 | /// temporarily shrinks below its regular size. 24 | /// 25 | /// - Parameter minimumCapacity: The minimum number of elements that the newly 26 | /// created set should be able to store without reallocating its storage. 27 | /// 28 | /// - Parameter persistent: If set to true, prevent removals from shrinking 29 | /// storage below the specified capacity. By default, removals are allowed 30 | /// to shrink storage below any previously reserved capacity. 31 | /// 32 | /// - Complexity: O(`minimumCapacity`) 33 | @inlinable 34 | public init(minimumCapacity: Int, persistent: Bool = false) { 35 | self.init() 36 | self._reserveCapacity(minimumCapacity, persistent: persistent) 37 | } 38 | } 39 | 40 | extension OrderedSet { 41 | /// Reserves enough space to store the specified number of elements. 42 | /// 43 | /// This method ensures that the set has unique mutable storage, with space 44 | /// allocated for at least the requested number of elements. 45 | /// 46 | /// If you are adding a known number of elements to a set, call this method 47 | /// once before the first insertion to avoid multiple reallocations. 48 | /// 49 | /// Do not call this method in a loop -- it does not use an exponential 50 | /// allocation strategy, so doing that can result in quadratic instead of 51 | /// linear performance. 52 | /// 53 | /// - Parameter minimumCapacity: The minimum number of elements that the set 54 | /// should be able to store without reallocating its storage. 55 | /// 56 | /// - Complexity: O(`max(count, minimumCapacity)`) 57 | @inlinable 58 | public mutating func reserveCapacity(_ minimumCapacity: Int) { 59 | self._reserveCapacity(minimumCapacity, persistent: false) 60 | } 61 | } 62 | 63 | extension OrderedSet { 64 | /// Reserves enough space to store the specified number of elements. 65 | /// 66 | /// This method ensures that the set has unique mutable storage, with space 67 | /// allocated for at least the requested number of elements. 68 | /// 69 | /// If you are adding a known number of elements to a set, call this method 70 | /// once before the first insertion to avoid multiple reallocations. 71 | /// 72 | /// Do not call this method in a loop -- it does not use an exponential 73 | /// allocation strategy, so doing that can result in quadratic instead of 74 | /// linear performance. 75 | /// 76 | /// If you have a good idea of the expected working size of the set, calling 77 | /// this method with `persistent` set to true can sometimes improve 78 | /// performance by eliminating churn due to repeated rehashings when the set 79 | /// temporarily shrinks below its regular size. You can cancel any capacity 80 | /// you've previously reserved by persistently reserving a capacity of zero. 81 | /// (This also shrinks the hash table to the ideal size for its current number 82 | /// elements.) 83 | /// 84 | /// - Parameter minimumCapacity: The minimum number of elements that the set 85 | /// should be able to store without reallocating its storage. 86 | /// 87 | /// - Parameter persistent: If set to true, prevent removals from shrinking 88 | /// storage below the specified capacity. By default, removals are allowed 89 | /// to shrink storage below any previously reserved capacity. 90 | /// 91 | /// - Complexity: O(`max(count, minimumCapacity)`) 92 | @inlinable 93 | internal mutating func _reserveCapacity( 94 | _ minimumCapacity: Int, 95 | persistent: Bool 96 | ) { 97 | precondition(minimumCapacity >= 0, "Minimum capacity cannot be negative") 98 | defer { _checkInvariants() } 99 | 100 | _elements.reserveCapacity(minimumCapacity) 101 | 102 | let currentScale = _scale 103 | let newScale = _HashTable.scale(forCapacity: minimumCapacity) 104 | 105 | let reservedScale = persistent ? newScale : _reservedScale 106 | 107 | if currentScale < newScale { 108 | // Grow the table. 109 | _regenerateHashTable(scale: newScale, reservedScale: reservedScale) 110 | return 111 | } 112 | 113 | let requiredScale = _HashTable.scale(forCapacity: self.count) 114 | let minScale = Swift.max(Swift.max(newScale, reservedScale), requiredScale) 115 | if minScale < currentScale { 116 | // Shrink the table. 117 | _regenerateHashTable(scale: minScale, reservedScale: reservedScale) 118 | return 119 | } 120 | 121 | // When we have the right size table, ensure it's unique and it has the 122 | // right persisted reservation. 123 | _ensureUnique() 124 | if _reservedScale != reservedScale { 125 | // Remember reserved scale. 126 | __storage!.header.reservedScale = reservedScale 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedSet/OrderedSet+Initializers.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedSet { 13 | /// Creates a set with the contents of the given sequence, which 14 | /// must not include duplicate elements. 15 | /// 16 | /// In optimized builds, this initializer does not verify that the 17 | /// elements are actually unique. This makes creating the set 18 | /// somewhat faster if you know for sure that the elements are 19 | /// unique (e.g., because they come from another collection with 20 | /// guaranteed-unique members, such as a `Set`). However, if you 21 | /// accidentally call this initializer with duplicate members, it 22 | /// can return a corrupt set value that may be difficult to debug. 23 | /// 24 | /// - Parameter elements: A finite sequence of unique elements. 25 | /// 26 | /// - Complexity: Expected to be O(*n*) on average, where *n* is the 27 | /// number of elements in the sequence, if `Element` implements 28 | /// high-quality hashing. 29 | @inlinable 30 | @inline(__always) 31 | public init(uncheckedUniqueElements elements: S) 32 | where S.Element == Element { 33 | let elements = ContiguousArray(elements) 34 | #if DEBUG 35 | let (table, firstDupe) = _HashTable.create(untilFirstDuplicateIn: elements) 36 | precondition(firstDupe == elements.endIndex, 37 | "Duplicate elements found in input") 38 | #else 39 | let table = _HashTable.create(uncheckedUniqueElements: elements) 40 | #endif 41 | self.init( 42 | _uniqueElements: elements, 43 | elements.count > _HashTable.maximumUnhashedCount ? table : nil) 44 | _checkInvariants() 45 | } 46 | } 47 | 48 | extension OrderedSet { 49 | /// Creates a new set from a finite sequence of items. 50 | /// 51 | /// - Parameter elements: The elements to use as members of the new set. 52 | /// 53 | /// - Complexity: This operation is expected to perform O(*n*) 54 | /// comparisons on average (where *n* is the number of elements 55 | /// in the sequence), provided that `Element` implements 56 | /// high-quality hashing. 57 | @inlinable 58 | public init(_ elements: S) where S.Element == Element { 59 | if S.self == Self.self { 60 | self = elements as! Self 61 | return 62 | } 63 | // Fast paths for when we know elements are all unique 64 | if S.self == Set.self || S.self == SubSequence.self { 65 | self.init(uncheckedUniqueElements: elements) 66 | return 67 | } 68 | 69 | self.init() 70 | append(contentsOf: elements) 71 | } 72 | 73 | // Specializations 74 | 75 | /// Creates a new set from a an existing set. This is functionally the same as 76 | /// copying the value of `elements` into a new variable. 77 | /// 78 | /// - Parameter elements: The elements to use as members of the new set. 79 | /// 80 | /// - Complexity: O(1) 81 | @inlinable 82 | public init(_ elements: Self) { 83 | self = elements 84 | } 85 | 86 | /// Creates a new set from an existing slice of another set. 87 | /// 88 | /// - Parameter elements: The elements to use as members of the new set. 89 | /// 90 | /// - Complexity: This operation is expected to perform 91 | /// O(`elements.count`) operations on average, provided that 92 | /// `Element` implements high-quality hashing. 93 | @inlinable 94 | public init(_ elements: SubSequence) { 95 | self.init(uncheckedUniqueElements: elements._slice) 96 | } 97 | 98 | /// Creates a new set from an existing `Set` value. 99 | /// 100 | /// - Parameter elements: The elements to use as members of the new set. 101 | /// 102 | /// - Complexity: This operation is expected to perform 103 | /// O(`elements.count`) operations on average, provided that 104 | /// `Element` implements high-quality hashing. 105 | @inlinable 106 | public init(_ elements: Set) { 107 | self.init(uncheckedUniqueElements: elements) 108 | } 109 | 110 | /// Creates a new set from the keys view of a dictionary. 111 | /// 112 | /// - Parameter elements: The elements to use as members of the new set. 113 | /// 114 | /// - Complexity: This operation is expected to perform 115 | /// O(`elements.count`) operations on average, provided that 116 | /// `Element` implements high-quality hashing. 117 | @inlinable 118 | public init(_ elements: Dictionary.Keys) { 119 | self._elements = ContiguousArray(elements) 120 | _regenerateHashTable() 121 | _checkInvariants() 122 | } 123 | 124 | /// Creates a new set from a collection of items. 125 | /// 126 | /// - Parameter elements: The elements to use as members of the new set. 127 | /// 128 | /// - Complexity: This operation is expected to perform O(*n*) 129 | /// comparisons on average (where *n* is the number of elements 130 | /// in the sequence), provided that `Element` implements 131 | /// high-quality hashing. 132 | @inlinable 133 | public init( 134 | _ elements: C 135 | ) where C.Element == Element { 136 | // This code is careful not to copy storage if `C` is an Array 137 | // or ContiguousArray and the elements are already unique. 138 | let (table, firstDupe) = _HashTable.create( 139 | untilFirstDuplicateIn: elements) 140 | if firstDupe == elements.endIndex { 141 | // Fast path: `elements` consists of unique values. 142 | self.init(_uniqueElements: ContiguousArray(elements), table) 143 | return 144 | } 145 | 146 | // Otherwise keep the elements we've processed and add the rest one by one. 147 | self.init(_uniqueElements: ContiguousArray(elements[.. CABasicAnimation { 16 | let animation = CABasicAnimation(keyPath: "position.x") 17 | 18 | setupBasicAnimation(animation, duration: duration, fromValue: fromValue, toValue: toValue, timingFunction: timingFunction, fillMode: fillMode, beginTime: beginTime, isRemovedOnCompletion: isRemovedOnCompletion) 19 | 20 | return animation 21 | } 22 | 23 | static func getScaleAnimation(runningFor duration: CFTimeInterval, fromValue: Any? = nil, toValue: Any, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode, beginTime: CFTimeInterval? = nil, isRemovedOnCompletion: Bool) -> CABasicAnimation { 24 | let animation = CABasicAnimation(keyPath: "transform.scale") 25 | 26 | setupBasicAnimation(animation, duration: duration, fromValue: fromValue, toValue: toValue, timingFunction: timingFunction, fillMode: fillMode, beginTime: beginTime, isRemovedOnCompletion: isRemovedOnCompletion) 27 | 28 | return animation 29 | } 30 | 31 | static func getTranslateYAnimation(runningFor duration: CFTimeInterval, fromValue: Any? = nil, toValue: Any, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode, beginTime: CFTimeInterval? = nil, isRemovedOnCompletion: Bool) -> CABasicAnimation { 32 | let animation = CABasicAnimation(keyPath: "position.y") 33 | 34 | setupBasicAnimation(animation, duration: duration, fromValue: fromValue, toValue: toValue, timingFunction: timingFunction, fillMode: fillMode, beginTime: beginTime, isRemovedOnCompletion: isRemovedOnCompletion) 35 | 36 | return animation 37 | } 38 | 39 | static func getBackgroundChangeAnimation(runningFor duration: CFTimeInterval, fromValue: Any? = nil, toValue: Any, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode, beginTime: CFTimeInterval? = nil, isRemovedOnCompletion: Bool) -> CABasicAnimation { 40 | let animation = CABasicAnimation(keyPath: "backgroundColor") 41 | 42 | setupBasicAnimation(animation, duration: duration, fromValue: fromValue, toValue: toValue, timingFunction: timingFunction, fillMode: fillMode, beginTime: beginTime, isRemovedOnCompletion: isRemovedOnCompletion) 43 | 44 | return animation 45 | } 46 | 47 | static func getKeyframePositionAnimation(runningFor duration: CFTimeInterval, values: [NSValue], keyTimes: [NSNumber]?, timingFunctions: [CAMediaTimingFunction], fillMode: CAMediaTimingFillMode, isRemovedOnCompletion: Bool = true) -> CAKeyframeAnimation { 48 | 49 | let animation = CAKeyframeAnimation(keyPath: "position") 50 | 51 | setupKeyframeAnimation(animation, duration: duration, values: values, keyTimes: keyTimes, timingFunctions: timingFunctions, fillMode: fillMode, isRemovedOnCompletion: isRemovedOnCompletion) 52 | 53 | return animation 54 | } 55 | 56 | static func getKeyframePositionAnimation(runningFor duration: CFTimeInterval, path: CGPath?, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode = .removed, isRemovedOnCompletion: Bool = true) -> CAKeyframeAnimation { 57 | let animation = CAKeyframeAnimation(keyPath: "position") 58 | 59 | setupKeyframeAnimation(animation, duration: duration, path: path, timingFunction: timingFunction, fillMode: fillMode, isRemovedOnCompletion: isRemovedOnCompletion) 60 | 61 | return animation 62 | } 63 | 64 | static func getKeyframePathAnimation(runningFor duration: CFTimeInterval, values: [CGPath], keyTimes: [NSNumber]?, timingFunctions: [CAMediaTimingFunction], fillMode: CAMediaTimingFillMode, isRemovedOnCompletion: Bool = true) -> CAKeyframeAnimation { 65 | 66 | let animation = CAKeyframeAnimation(keyPath: "path") 67 | 68 | setupKeyframeAnimation(animation, duration: duration, values: values, keyTimes: keyTimes, timingFunctions: timingFunctions, fillMode: fillMode, isRemovedOnCompletion: isRemovedOnCompletion) 69 | 70 | return animation 71 | } 72 | 73 | // MARK: Utility Functions 74 | 75 | private static func setupBasicAnimation(_ animation: CABasicAnimation, duration: CFTimeInterval, fromValue: Any?, toValue: Any, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode, beginTime: CFTimeInterval?, isRemovedOnCompletion: Bool) { 76 | 77 | if let fromValue = fromValue { 78 | animation.fromValue = fromValue 79 | } 80 | animation.toValue = toValue 81 | animation.duration = duration 82 | animation.fillMode = fillMode 83 | 84 | if let beginTime = beginTime { 85 | animation.beginTime = beginTime 86 | } 87 | animation.isRemovedOnCompletion = isRemovedOnCompletion 88 | } 89 | 90 | private static func setupKeyframeAnimation(_ animation: CAKeyframeAnimation, duration: CFTimeInterval, values: [Any], keyTimes: [NSNumber]?, timingFunctions: [CAMediaTimingFunction], fillMode: CAMediaTimingFillMode, isRemovedOnCompletion: Bool = true) { 91 | 92 | animation.duration = duration 93 | animation.values = values 94 | 95 | if let keyTimes = keyTimes { 96 | animation.keyTimes = keyTimes 97 | } 98 | 99 | animation.timingFunctions = timingFunctions 100 | animation.fillMode = fillMode 101 | animation.isRemovedOnCompletion = isRemovedOnCompletion 102 | 103 | } 104 | 105 | private static func setupKeyframeAnimation(_ animation: CAKeyframeAnimation, duration: CFTimeInterval, path: CGPath?, timingFunction: CAMediaTimingFunction, fillMode: CAMediaTimingFillMode, isRemovedOnCompletion: Bool) { 106 | animation.duration = duration 107 | animation.path = path 108 | animation.timingFunction = timingFunction 109 | animation.fillMode = fillMode 110 | animation.isRemovedOnCompletion = isRemovedOnCompletion 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![CI Status](https://img.shields.io/travis/eshwavin/SETabView.svg?style=flat)](https://travis-ci.org/eshwavin/SETabView) 2 | [![Version](https://img.shields.io/cocoapods/v/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 3 | [![License](https://img.shields.io/cocoapods/l/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 4 | [![Platform](https://img.shields.io/cocoapods/p/SETabView.svg?style=flat)](https://cocoapods.org/pods/SETabView) 5 | 6 | ## Animations 7 | 8 | .holeBall1 | .holeBall2 | .holeBall3 9 | ---------| --------------|---------| 10 | | | 11 | 12 | ## What's New? 13 | 14 | #### The API has been changed to resemble `UITabBarController` 15 | - Colors have been renamed to conform to colors specified by `UITabBar` 16 | - Colors can be set collectively as before (function parameter names have been changed to reflect the changed color names) or individually 17 | - Colors can now be changed at any point in time 18 | - The view controllers at any time 19 | - The animation type can be changed at any time to switch between available animations by setting the `animationType` property! 20 | - `animationDuration` can no longer be changed 21 | 22 | #### Bug fixes 23 | - A bug that caused holeBall3 to behave weirdly in larger screen sizes has been squashed 24 | - Glitchy landscape mode behaviour has been fixed 25 | 26 | A whole lot of performance optimizations have been added so that our library does not slow down your app. Hurray! 27 | 28 | ## Requirements 29 | 30 | - Swift 5+ 31 | - iOS 11.0+ 32 | - Swift tools version 5.0+ (For Swift Package Manager) 33 | 34 | ## Integration 35 | 36 | ### CocoaPods 37 | 38 | SETabView is available through [CocoaPods](https://cocoapods.org). To install 39 | it, simply add the following line to your Podfile: 40 | 41 | ```ruby 42 | pod 'SETabView' 43 | ``` 44 | 45 | In case the latest version (2.0.0) is not the one being installed, update the pod. 46 | 47 | ``` 48 | pod update 'SETabView' 49 | ``` 50 | 51 | ### Swift Package Manager 52 | 53 | The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. 54 | 55 | Once you have your Swift package set up, adding SETabView as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. 56 | 57 | ```swift 58 | dependencies: [ 59 | .package(url: "https://github.com/eshwavin/SETabView.git", .upToNextMajor(from: "2.0.0")) 60 | ] 61 | ``` 62 | 63 | ### Directly include source files 64 | 65 | Download and add the files in the [Source](https://github.com/eshwavin/SETabView/tree/master/Source) folder directly into your Xcode Project. In this case you should **skip** 66 | 67 | ```swift 68 | import SETabView 69 | ``` 70 | 71 | in the usage instructions. 72 | 73 | ## Usage and Customization 74 | 75 | Import `SETabView` into the parent view controller and any child view controllers 76 | 77 | ```swift 78 | import SETabView 79 | ``` 80 | 81 | Inherit from the `SETabViewController` class in your tab view controller 82 | ```swift 83 | class MyCustomTabViewController: SETabViewController { 84 | 85 | override func viewDidLoad() { 86 | super.viewDidLoad() 87 | 88 | } 89 | } 90 | ``` 91 | 92 | ### Setting the view controllers and colors 93 | 94 | Set the view controllers using `setViewControllers(_:)` method or by directly setting the `viewControllers` property 95 | 96 | Customise the look by calling `setTabColors(backgroundColor:ballColor:tintColor:unselectedItemTintColor:barTintColor:)` method or simply setting the respective colors 97 | 98 | 99 | ```swift 100 | class ViewController: SEViewController { 101 | 102 | override func viewDidLoad() { 103 | super.viewDidLoad() 104 | 105 | // set tab bar look collectively 106 | setTabColors(backgroundColor: UIColor.white, ballColor: UIColor.white, tintColor: UIColor.black, unselectedItemTintColor: UIColor.red, barTintColor: .clear) 107 | 108 | // set animation type 109 | animationType = .holeball3 110 | 111 | // set the view controllers 112 | setViewControllers(getViewControllers()) 113 | 114 | } 115 | 116 | private func getViewControllers() -> [UIViewController] { 117 | let storyboard = UIStoryboard(name: "Main", bundle: nil) 118 | 119 | return [ 120 | storyboard.instantiateViewController(withIdentifier: "firstVC"), 121 | storyboard.instantiateViewController(withIdentifier: "secondVC"), 122 | storyboard.instantiateViewController(withIdentifier: "thirdVC"), 123 | storyboard.instantiateViewController(withIdentifier: "fourthVC"), 124 | storyboard.instantiateViewController(withIdentifier: "fifthVC") 125 | ] 126 | } 127 | } 128 | ``` 129 | 130 | ### Providing the image for the tab bar 131 | 132 | The child view controllers can conform to the `SETabItemProvider` protocol. Using `seTabImage` return a `UITabBarItem` for the view controller. 133 | 134 | 135 | Alternatively you can set the `tabBarItem` property for the view controllers as you would do when using `UITabBarController` 136 | 137 | ```swift 138 | class FirstViewController: UIViewController, SETabItemProvider { 139 | 140 | var seTabBarItem: UITabBarItem? { 141 | return UITabBarItem(title: "", image: UIImage(named: "first"), tag: 0) 142 | } 143 | 144 | override func viewDidLoad() { 145 | super.viewDidLoad() 146 | } 147 | } 148 | ``` 149 | 150 | ### Setting the selected index programmatically 151 | 152 | ```swift 153 | selectedTabIndex = 3 154 | ``` 155 | 156 | ## Restrictions 157 | 158 | - Max 5 Tabs 159 | 160 | ## Example 161 | 162 | To run the example project, clone the repo, and run `pod install` from the Example directory first. 163 | 164 | ## Planned Improvements 165 | 166 | - More `UITabBarController` behaviours 167 | - Increasing support for number of tabs by introducing a **More** tab 168 | - Badges 169 | - Performance improvements 170 | 171 | ## Author 172 | 173 | Srivinayak Chaitanya Eshwa, eshwavin@gmail.com 174 | 175 | ## License 176 | 177 | SETabView is available under the MIT license. See the LICENSE file for more info. 178 | SETabView uses the complete OrderedCollections code from [swift-collections](https://github.com/apple/swift-collections) 179 | 180 | ## Acknowledgement 181 | 182 | [Animation Inspiration](https://www.behance.net/gallery/79473185/25-Animated-Tab-Bar-Designs-for-Inspiration) 183 | 184 | [Icons](https://www.flaticon.com/authors/nikita-golubev) 185 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Partial RangeReplaceableCollection.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | // The parts of RangeReplaceableCollection that OrderedDictionary is able to implement. 13 | 14 | extension OrderedDictionary { 15 | /// Reserves enough space to store the specified number of elements. 16 | /// 17 | /// This method ensures that the dictionary has unique, mutable, contiguous 18 | /// storage, with space allocated for at least the requested number of 19 | /// elements. 20 | /// 21 | /// If you are adding a known number of elements to a dictionary, call this 22 | /// method once before the first insertion to avoid multiple reallocations. 23 | /// 24 | /// Do not call this method in a loop -- it does not use an exponential 25 | /// allocation strategy, so doing that can result in quadratic instead of 26 | /// linear performance. 27 | /// 28 | /// - Parameter minimumCapacity: The minimum number of elements that the 29 | /// dictionary should be able to store without reallocating its storage. 30 | /// 31 | /// - Complexity: O(`max(count, minimumCapacity)`) 32 | @inlinable 33 | public mutating func reserveCapacity(_ minimumCapacity: Int) { 34 | self._keys.reserveCapacity(minimumCapacity) 35 | self._values.reserveCapacity(minimumCapacity) 36 | } 37 | 38 | /// Removes all members from the dictionary. 39 | /// 40 | /// - Parameter keepingCapacity: If `true`, the dictionary's storage capacity 41 | /// is preserved; if `false`, the underlying storage is released. The 42 | /// default is `false`. 43 | /// 44 | /// - Complexity: O(`count`) 45 | @inlinable 46 | public mutating func removeAll(keepingCapacity keepCapacity: Bool = false) { 47 | _keys.removeAll(keepingCapacity: keepCapacity) 48 | _values.removeAll(keepingCapacity: keepCapacity) 49 | } 50 | 51 | /// Removes and returns the element at the specified position. 52 | /// 53 | /// All the elements following the specified position are moved to close the 54 | /// resulting gap. 55 | /// 56 | /// - Parameter index: The position of the element to remove. `index` must be 57 | /// a valid index of the collection that is not equal to the collection's 58 | /// end index. 59 | /// 60 | /// - Returns: The removed element. 61 | /// 62 | /// - Complexity: O(`count`) 63 | @inlinable 64 | @discardableResult 65 | public mutating func remove(at index: Int) -> Element { 66 | let key = _keys.remove(at: index) 67 | let value = _values.remove(at: index) 68 | return (key, value) 69 | } 70 | 71 | /// Removes the specified subrange of elements from the collection. 72 | /// 73 | /// All the elements following the specified subrange are moved to close the 74 | /// resulting gap. 75 | /// 76 | /// - Parameter bounds: The subrange of the collection to remove. The bounds 77 | /// of the range must be valid indices of the collection. 78 | /// 79 | /// - Complexity: O(`count`) 80 | @inlinable 81 | public mutating func removeSubrange(_ bounds: Range) { 82 | _keys.removeSubrange(bounds) 83 | _values.removeSubrange(bounds) 84 | } 85 | 86 | /// Removes the specified subrange of elements from the collection. 87 | /// 88 | /// All the elements following the specified subrange are moved to close the 89 | /// resulting gap. 90 | /// 91 | /// - Parameter bounds: The subrange of the collection to remove. The bounds 92 | /// of the range must be valid indices of the collection. 93 | /// 94 | /// - Complexity: O(`count`) 95 | @inlinable 96 | public mutating func removeSubrange( 97 | _ bounds: R 98 | ) where R.Bound == Int { 99 | removeSubrange(bounds.relative(to: elements)) 100 | } 101 | 102 | 103 | /// Removes the last element of a non-empty dictionary. 104 | /// 105 | /// - Complexity: Expected to be O(`1`) on average, if `Element` implements 106 | /// high-quality hashing. 107 | @inlinable 108 | @discardableResult 109 | public mutating func removeLast() -> Element { 110 | precondition(!isEmpty, "Cannot remove last element of an empty collection") 111 | return remove(at: count - 1) 112 | } 113 | 114 | /// Removes the last `n` element of the dictionary. 115 | /// 116 | /// - Parameter n: The number of elements to remove from the collection. 117 | /// `n` must be greater than or equal to zero and must not exceed the 118 | /// number of elements in the collection. 119 | /// 120 | /// - Complexity: Expected to be O(`n`) on average, if `Element` implements 121 | /// high-quality hashing. 122 | @inlinable 123 | public mutating func removeLast(_ n: Int) { 124 | precondition(n >= 0, "Can't remove a negative number of elements") 125 | precondition(n <= count, "Can't remove more elements than there are in the collection") 126 | _keys.removeLast(n) 127 | _values.removeLast(n) 128 | } 129 | 130 | /// Removes the first element of a non-empty dictionary. 131 | /// 132 | /// The members following the removed key-value pair need to be moved to close 133 | /// the resulting gaps in the storage arrays. 134 | /// 135 | /// - Complexity: O(`count`). 136 | @inlinable 137 | @discardableResult 138 | public mutating func removeFirst() -> Element { 139 | precondition(!isEmpty, "Cannot remove first element of an empty collection") 140 | return remove(at: 0) 141 | } 142 | 143 | /// Removes the first `n` elements of the dictionary. 144 | /// 145 | /// The members following the removed items need to be moved to close the 146 | /// resulting gaps in the storage arrays. 147 | /// 148 | /// - Parameter n: The number of elements to remove from the collection. 149 | /// `n` must be greater than or equal to zero and must not exceed the 150 | /// number of elements in the set. 151 | /// 152 | /// - Complexity: O(`count`). 153 | @inlinable 154 | public mutating func removeFirst(_ n: Int) { 155 | precondition(n >= 0, "Can't remove a negative number of elements") 156 | precondition(n <= count, "Can't remove more elements than there are in the collection") 157 | _keys.removeFirst(n) 158 | _values.removeFirst(n) 159 | } 160 | 161 | /// Removes all the elements that satisfy the given predicate. 162 | /// 163 | /// Use this method to remove every element in a collection that meets 164 | /// particular criteria. The order of the remaining elements is preserved. 165 | /// 166 | /// - Parameter shouldBeRemoved: A closure that takes an element of the 167 | /// dictionary as its argument and returns a Boolean value indicating 168 | /// whether the element should be removed from the collection. 169 | /// 170 | /// - Complexity: O(`count`) 171 | @inlinable 172 | public mutating func removeAll( 173 | where shouldBeRemoved: (Self.Element) throws -> Bool 174 | ) rethrows { 175 | let pivot = try _values.withUnsafeMutableBufferPointer { values in 176 | try _keys._halfStablePartition( 177 | values: values, 178 | by: shouldBeRemoved) 179 | } 180 | removeSubrange(pivot...) 181 | _checkInvariants() 182 | } 183 | } 184 | 185 | -------------------------------------------------------------------------------- /Source/OrderedCollections/HashTable/_HashTable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | @usableFromInline 13 | @frozen 14 | internal struct _HashTable { 15 | @usableFromInline 16 | internal var _storage: Storage 17 | 18 | @inlinable 19 | @inline(__always) 20 | internal init(_ storage: Storage) { 21 | _storage = storage 22 | } 23 | } 24 | 25 | extension _HashTable { 26 | /// A class holding hash table storage for a `OrderedSet` collection. 27 | /// Values in the hash table are offsets into separate element storage, so 28 | /// this class doesn't need to be generic over `OrderedSet`'s `Element` type. 29 | @usableFromInline 30 | internal final class Storage 31 | : ManagedBuffer 32 | {} 33 | } 34 | 35 | extension _HashTable { 36 | /// Allocate a new empty hash table buffer of the specified scale. 37 | @usableFromInline 38 | @_effects(releasenone) 39 | internal init(scale: Int, reservedScale: Int = 0) { 40 | assert(scale >= Self.minimumScale && scale <= Self.maximumScale) 41 | let wordCount = Self.wordCount(forScale: scale) 42 | let storage = Storage.create( 43 | minimumCapacity: wordCount, 44 | makingHeaderWith: { object in 45 | #if COLLECTIONS_DETERMINISTIC_HASHING 46 | let seed = scale << 6 47 | #else 48 | let seed = Int(bitPattern: Unmanaged.passUnretained(object).toOpaque()) 49 | #endif 50 | return Header(scale: scale, reservedScale: reservedScale, seed: seed) 51 | }) 52 | storage.withUnsafeMutablePointerToElements { elements in 53 | elements.initialize(repeating: 0, count: wordCount) 54 | } 55 | self.init(unsafeDowncast(storage, to: Storage.self)) 56 | } 57 | 58 | /// Populate a new hash table with data from `elements`. 59 | /// 60 | /// - Parameter scale: The desired hash table scale or nil to use the minimum scale that satisfies invariants. 61 | /// - Parameter reservedScale: The reserved scale to remember in the returned storage. 62 | /// - Parameter duplicates: The strategy to use to handle duplicate items. 63 | /// - Returns: `(storage, index)` where `storage` is a storage instance. The contents of `storage` reflects all elements in `contents[contents.startIndex ..< index]`. `index` is usually `contents.endIndex`, except when the function was asked to reject duplicates, in which case `index` addresses the first duplicate element in `contents` (if any). 64 | @inlinable 65 | @inline(never) 66 | @_effects(releasenone) 67 | static func create( 68 | uncheckedUniqueElements elements: C, 69 | scale: Int? = nil, 70 | reservedScale: Int = 0 71 | ) -> _HashTable? 72 | where C.Element: Hashable { 73 | let minScale = Self.scale(forCapacity: elements.count) 74 | let scale = Swift.max(Swift.max(scale ?? 0, minScale), 75 | reservedScale) 76 | if scale < Self.minimumScale { return nil } 77 | let hashTable = Self(scale: scale, reservedScale: reservedScale) 78 | hashTable.update { handle in 79 | handle.fill(uncheckedUniqueElements: elements) 80 | } 81 | return hashTable 82 | } 83 | 84 | /// Populate a new hash table with data from `elements`. 85 | /// 86 | /// - Parameter scale: The desired hash table scale or nil to use the minimum scale that satisfies invariants. 87 | /// - Parameter reservedScale: The reserved scale to remember in the returned storage. 88 | /// - Parameter duplicates: The strategy to use to handle duplicate items. 89 | /// - Returns: `(storage, index)` where `storage` is a storage instance. The contents of `storage` reflects all elements in `contents[contents.startIndex ..< index]`. `index` is usually `contents.endIndex`, except when the function was asked to reject duplicates, in which case `index` addresses the first duplicate element in `contents` (if any). 90 | @inlinable 91 | @inline(never) 92 | @_effects(releasenone) 93 | static func create( 94 | untilFirstDuplicateIn elements: C, 95 | scale: Int? = nil, 96 | reservedScale: Int = 0 97 | ) -> (hashTable: _HashTable?, end: C.Index) 98 | where C.Element: Hashable { 99 | let minScale = Self.scale(forCapacity: elements.count) 100 | let scale = Swift.max(Swift.max(scale ?? 0, minScale), 101 | reservedScale) 102 | if scale < Self.minimumScale { 103 | // Don't hash anything. 104 | if elements.count < 2 { return (nil, elements.endIndex) } 105 | var temp: [C.Element] = [] 106 | temp.reserveCapacity(elements.count) 107 | for i in elements.indices { 108 | let item = elements[i] 109 | guard !temp.contains(item) else { return (nil, i) } 110 | temp.append(item) 111 | } 112 | return (nil, elements.endIndex) 113 | } 114 | let hashTable = Self(scale: scale, reservedScale: reservedScale) 115 | let (_, index) = hashTable.update { handle in 116 | handle.fill(untilFirstDuplicateIn: elements) 117 | } 118 | return (hashTable, index) 119 | } 120 | 121 | /// Create and return a new copy of this instance. The result has the same 122 | /// scale and seed, and contains the exact same bucket data as the original instance. 123 | @usableFromInline 124 | @_effects(releasenone) 125 | internal func copy() -> _HashTable { 126 | self.read { handle in 127 | let wordCount = handle.wordCount 128 | let new = Storage.create( 129 | minimumCapacity: wordCount, 130 | makingHeaderWith: { _ in handle._header.pointee }) 131 | new.withUnsafeMutablePointerToElements { elements in 132 | elements.initialize(from: handle._buckets, count: wordCount) 133 | } 134 | return Self(unsafeDowncast(new, to: Storage.self)) 135 | } 136 | } 137 | } 138 | 139 | 140 | 141 | extension _HashTable { 142 | /// Call `body` with a hash table handle suitable for read-only use. 143 | /// 144 | /// - Warning: The handle supplied to `body` is only valid for the duration of 145 | /// the closure call. The closure must not escape it outside the call. 146 | @inlinable 147 | @inline(__always) 148 | internal func read(_ body: (_UnsafeHashTable) throws -> R) rethrows -> R { 149 | try _storage.withUnsafeMutablePointers { header, elements in 150 | let handle = _UnsafeHashTable(header: header, buckets: elements, readonly: true) 151 | return try body(handle) 152 | } 153 | } 154 | 155 | /// Call `body` with a hash table handle suitable for mutating use. 156 | /// 157 | /// - Warning: The handle supplied to `body` is only valid for the duration of 158 | /// the closure call. The closure must not escape it outside the call. 159 | @inlinable 160 | @inline(__always) 161 | internal func update(_ body: (_UnsafeHashTable) throws -> R) rethrows -> R { 162 | try _storage.withUnsafeMutablePointers { header, elements in 163 | let handle = _UnsafeHashTable(header: header, buckets: elements, readonly: false) 164 | return try body(handle) 165 | } 166 | } 167 | } 168 | 169 | extension _HashTable { 170 | @inlinable 171 | internal var header: Header { 172 | get { _storage.header } 173 | nonmutating _modify { yield &_storage.header } 174 | } 175 | 176 | @inlinable 177 | internal var capacity: Int { 178 | _storage.header.capacity 179 | } 180 | 181 | @inlinable 182 | internal var minimumCapacity: Int { 183 | if scale == reservedScale { return 0 } 184 | return Self.minimumCapacity(forScale: scale) 185 | } 186 | 187 | @inlinable 188 | internal var scale: Int { 189 | _storage.header.scale 190 | } 191 | 192 | @inlinable 193 | internal var reservedScale: Int { 194 | _storage.header.reservedScale 195 | } 196 | 197 | @inlinable 198 | internal var bias: Int { 199 | _storage.header.bias 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /Source/OrderedCollections/OrderedDictionary/OrderedDictionary+Partial MutableCollection.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the Swift Collections open source project 4 | // 5 | // Copyright (c) 2021 Apple Inc. and the Swift project authors 6 | // Licensed under Apache License v2.0 with Runtime Library Exception 7 | // 8 | // See https://swift.org/LICENSE.txt for license information 9 | // 10 | //===----------------------------------------------------------------------===// 11 | 12 | extension OrderedDictionary { 13 | /// Exchanges the key-value pairs at the specified indices of the dictionary. 14 | /// 15 | /// Both parameters must be valid indices below `endIndex`. Passing the same 16 | /// index as both `i` and `j` has no effect. 17 | /// 18 | /// - Parameters: 19 | /// - i: The index of the first value to swap. 20 | /// - j: The index of the second value to swap. 21 | /// 22 | /// - Complexity: O(1) when the dictionary's storage isn't shared with another 23 | /// value; O(`count`) otherwise. 24 | @inlinable 25 | public mutating func swapAt(_ i: Int, _ j: Int) { 26 | _keys.swapAt(i, j) 27 | _values.swapAt(i, j) 28 | } 29 | 30 | /// Reorders the elements of the dictionary such that all the elements that 31 | /// match the given predicate are after all the elements that don't match. 32 | /// 33 | /// After partitioning a collection, there is a pivot index `p` where 34 | /// no element before `p` satisfies the `belongsInSecondPartition` 35 | /// predicate and every element at or after `p` satisfies 36 | /// `belongsInSecondPartition`. 37 | /// 38 | /// - Parameter belongsInSecondPartition: A predicate used to partition 39 | /// the collection. All elements satisfying this predicate are ordered 40 | /// after all elements not satisfying it. 41 | /// - Returns: The index of the first element in the reordered collection 42 | /// that matches `belongsInSecondPartition`. If no elements in the 43 | /// collection match `belongsInSecondPartition`, the returned index is 44 | /// equal to the collection's `endIndex`. 45 | /// 46 | /// - Complexity: O(`count`) 47 | @inlinable 48 | public mutating func partition( 49 | by belongsInSecondPartition: (Element) throws -> Bool 50 | ) rethrows -> Int { 51 | let pivot = try _values.withUnsafeMutableBufferPointer { values in 52 | try _keys._partition(values: values, by: belongsInSecondPartition) 53 | } 54 | _checkInvariants() 55 | return pivot 56 | } 57 | } 58 | 59 | extension OrderedDictionary { 60 | /// Sorts the collection in place, using the given predicate as the 61 | /// comparison between elements. 62 | /// 63 | /// When you want to sort a collection of elements that don't conform to 64 | /// the `Comparable` protocol, pass a closure to this method that returns 65 | /// `true` when the first element should be ordered before the second. 66 | /// 67 | /// Alternatively, use this method to sort a collection of elements that do 68 | /// conform to `Comparable` when you want the sort to be descending instead 69 | /// of ascending. Pass the greater-than operator (`>`) operator as the 70 | /// predicate. 71 | /// 72 | /// `areInIncreasingOrder` must be a *strict weak ordering* over the 73 | /// elements. That is, for any elements `a`, `b`, and `c`, the following 74 | /// conditions must hold: 75 | /// 76 | /// - `areInIncreasingOrder(a, a)` is always `false`. (Irreflexivity) 77 | /// - If `areInIncreasingOrder(a, b)` and `areInIncreasingOrder(b, c)` are 78 | /// both `true`, then `areInIncreasingOrder(a, c)` is also `true`. 79 | /// (Transitive comparability) 80 | /// - Two elements are *incomparable* if neither is ordered before the other 81 | /// according to the predicate. If `a` and `b` are incomparable, and `b` 82 | /// and `c` are incomparable, then `a` and `c` are also incomparable. 83 | /// (Transitive incomparability) 84 | /// 85 | /// The sorting algorithm is not guaranteed to be stable. A stable sort 86 | /// preserves the relative order of elements for which 87 | /// `areInIncreasingOrder` does not establish an order. 88 | /// 89 | /// - Parameter areInIncreasingOrder: A predicate that returns `true` if its 90 | /// first argument should be ordered before its second argument; 91 | /// otherwise, `false`. If `areInIncreasingOrder` throws an error during 92 | /// the sort, the elements may be in a different order, but none will be 93 | /// lost. 94 | /// 95 | /// - Complexity: O(*n* log *n*), where *n* is the length of the collection. 96 | @inlinable 97 | public mutating func sort( 98 | by areInIncreasingOrder: (Element, Element) throws -> Bool 99 | ) rethrows { 100 | // FIXME: Implement in-place sorting. 101 | let temp = try self.sorted(by: areInIncreasingOrder) 102 | precondition(temp.count == self.count) 103 | temp.withUnsafeBufferPointer { source in 104 | _keys = OrderedSet(uncheckedUniqueElements: source.lazy.map { $0.key }) 105 | _values = ContiguousArray(source.lazy.map { $0.value }) 106 | } 107 | _checkInvariants() 108 | } 109 | } 110 | 111 | extension OrderedDictionary where Key: Comparable { 112 | /// Sorts the dictionary in place. 113 | /// 114 | /// You can sort an ordered dictionary of keys that conform to the 115 | /// `Comparable` protocol by calling this method. The key-value pairs are 116 | /// sorted in ascending order. (`Value` doesn't need to conform to 117 | /// `Comparable` because the keys are guaranteed to be unique.) 118 | /// 119 | /// The sorting algorithm is not guaranteed to be stable. A stable sort 120 | /// preserves the relative order of elements that compare equal. 121 | /// 122 | /// - Complexity: O(*n* log *n*), where *n* is the length of the collection. 123 | @inlinable 124 | public mutating func sort() { 125 | sort { $0.key < $1.key } 126 | } 127 | } 128 | 129 | extension OrderedDictionary { 130 | /// Shuffles the collection in place. 131 | /// 132 | /// Use the `shuffle()` method to randomly reorder the elements of an ordered 133 | /// dictionary. 134 | /// 135 | /// This method is equivalent to calling `shuffle(using:)`, passing in the 136 | /// system's default random generator. 137 | /// 138 | /// - Complexity: O(*n*), where *n* is the length of the collection. 139 | @inlinable 140 | public mutating func shuffle() { 141 | var generator = SystemRandomNumberGenerator() 142 | shuffle(using: &generator) 143 | } 144 | 145 | /// Shuffles the collection in place, using the given generator as a source 146 | /// for randomness. 147 | /// 148 | /// You use this method to randomize the elements of a collection when you 149 | /// are using a custom random number generator. For example, you can use the 150 | /// `shuffle(using:)` method to randomly reorder the elements of an array. 151 | /// 152 | /// - Parameter generator: The random number generator to use when shuffling 153 | /// the collection. 154 | /// 155 | /// - Complexity: O(*n*), where *n* is the length of the collection. 156 | /// 157 | /// - Note: The algorithm used to shuffle a collection may change in a future 158 | /// version of Swift. If you're passing a generator that results in the 159 | /// same shuffled order each time you run your program, that sequence may 160 | /// change when your program is compiled using a different version of 161 | /// Swift. 162 | @inlinable 163 | public mutating func shuffle( 164 | using generator: inout T 165 | ) { 166 | guard count > 1 else { return } 167 | var keys = self._keys.elements 168 | var values = self._values 169 | self = [:] 170 | var amount = keys.count 171 | var current = 0 172 | while amount > 1 { 173 | let random = Int.random(in: 0 ..< amount, using: &generator) 174 | amount -= 1 175 | keys.swapAt(current, current + random) 176 | values.swapAt(current, current + random) 177 | current += 1 178 | } 179 | self = OrderedDictionary(uncheckedUniqueKeys: keys, values: values) 180 | } 181 | } 182 | 183 | extension OrderedDictionary { 184 | /// Reverses the elements of the ordered dictionary in place. 185 | /// 186 | /// - Complexity: O(`count`) 187 | @inlinable 188 | public mutating func reverse() { 189 | _keys.reverse() 190 | _values.reverse() 191 | } 192 | } 193 | 194 | --------------------------------------------------------------------------------