├── TopTabBarView
├── Media
│ └── demo.mov
├── TopTabBarView.docc
│ └── TopTabBarView.md
├── Source
│ ├── CircleView.swift
│ ├── UIView+Extension.swift
│ ├── TabBarCollectionView.swift
│ └── TopTabbarView.swift
└── TopTabBarView.h
├── Example
├── Example
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── AccentColor.colorset
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Media
│ │ └── demo.mov
│ ├── ContentViewController.swift
│ ├── Info.plist
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── SceneDelegate.swift
│ └── ViewController.swift
├── Podfile
└── Example.xcodeproj
│ └── project.pbxproj
├── TopTabBarView.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── project.pbxproj
├── TopTabBarView.podspec
├── LICENSE
├── .gitignore
└── README.md
/TopTabBarView/Media/demo.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mindinventory/iOS-Top-Tab-Navigation/HEAD/TopTabBarView/Media/demo.mov
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/Example/Media/demo.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Mindinventory/iOS-Top-Tab-Navigation/HEAD/Example/Example/Media/demo.mov
--------------------------------------------------------------------------------
/TopTabBarView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "idiom" : "universal"
5 | }
6 | ],
7 | "info" : {
8 | "author" : "xcode",
9 | "version" : 1
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/TopTabBarView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/TopTabBarView/TopTabBarView.docc/TopTabBarView.md:
--------------------------------------------------------------------------------
1 | # ``TopTabBarView``
2 |
3 | Summary
4 |
5 | ## Overview
6 |
7 | Text
8 |
9 | ## Topics
10 |
11 | ### Group
12 |
13 | - ``Symbol``
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'Example' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for Example
9 | pod 'TopTabBarView', git: 'https://github.com/parthgohel2810/TopTabBarView-Framework.git', branch: 'main'
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/TopTabBarView/Source/CircleView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CircleView.swift
3 | // TopTabbarView
4 | //
5 | // Created by Parth Gohel on 06/05/22.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | final class CircleView: UIView {
12 |
13 | override func layoutSubviews() {
14 | super.layoutSubviews()
15 | self.layer.cornerRadius = self.frame.size.height/2
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/TopTabBarView/Source/UIView+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.swift
3 | // TopTabbarView
4 | //
5 | // Created by Parth Gohel on 06/05/22.
6 | //
7 |
8 | import UIKit
9 |
10 | extension UIView {
11 |
12 | func viewCenter(usePresentationLayerIfPossible: Bool) -> CGPoint {
13 | if usePresentationLayerIfPossible, let presentationLayer = layer.presentation() {
14 | return presentationLayer.position
15 | }
16 | return center
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/TopTabBarView/TopTabBarView.h:
--------------------------------------------------------------------------------
1 | //
2 | // TopTabBarView.h
3 | // TopTabBarView
4 | //
5 | // Created by mac-0009 on 09/05/22.
6 | //
7 |
8 | #import
9 |
10 | //! Project version number for TopTabBarView.
11 | FOUNDATION_EXPORT double TopTabBarViewVersionNumber;
12 |
13 | //! Project version string for TopTabBarView.
14 | FOUNDATION_EXPORT const unsigned char TopTabBarViewVersionString[];
15 |
16 | // In this header, you should import all the public headers of your framework using statements like #import
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Example/Example/ContentViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentViewController.swift
3 | // Example
4 | //
5 | // Created by Parth Gohel on 10/05/22.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | class ContentViewController: UIViewController {
12 |
13 | @IBOutlet private weak var titleLabel: UILabel!
14 |
15 | override func viewDidLoad() {
16 | super.viewDidLoad()
17 | // Do any additional setup after loading the view.
18 | }
19 |
20 | func update(with title: String) {
21 | titleLabel.text = title
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/Example/Example/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIApplicationSceneManifest
6 |
7 | UIApplicationSupportsMultipleScenes
8 |
9 | UISceneConfigurations
10 |
11 | UIWindowSceneSessionRoleApplication
12 |
13 |
14 | UISceneConfigurationName
15 | Default Configuration
16 | UISceneDelegateClassName
17 | $(PRODUCT_MODULE_NAME).SceneDelegate
18 | UISceneStoryboardFile
19 | Main
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/TopTabBarView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'TopTabBarView'
3 | s.version = '1.0.1'
4 | s.summary = 'Wave animation view for tabs only used for iOS'
5 | s.description = <<-DESC
6 | This CocoaPods library helps you to add wave animation tabs in app and makes your app look fantastic!
7 | DESC
8 |
9 | s.homepage = 'https://github.com/parthgohel2810/TopTabBarView-Framework.git'
10 | s.license = { :type => 'MIT', :file => 'LICENSE' }
11 | s.author = { "Parth Gohel" => "parth.gohel@mindinventory.com" }
12 | s.source = { :git => 'https://github.com/parthgohel2810/TopTabBarView-Framework.git', :tag => "#v{s.version}" }
13 | s.platform = :ios, "13.0"
14 | s.swift_version = '5.0'
15 | s.ios.deployment_target = '13.0'
16 | s.source_files = "TopTabBarView/Source/**/*.swift"
17 | end
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 parthgohel2810
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Example/Example/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Example
4 | //
5 | // Created by Parth Gohel on 10/05/22.
6 | //
7 |
8 | import UIKit
9 |
10 | @main
11 | class AppDelegate: UIResponder, UIApplicationDelegate {
12 |
13 |
14 |
15 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
16 | // Override point for customization after application launch.
17 | return true
18 | }
19 |
20 | // MARK: UISceneSession Lifecycle
21 |
22 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
23 | // Called when a new scene session is being created.
24 | // Use this method to select a configuration to create the new scene with.
25 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
26 | }
27 |
28 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
29 | // Called when the user discards a scene session.
30 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
31 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
32 | }
33 |
34 |
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "scale" : "1x",
46 | "size" : "20x20"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "scale" : "2x",
51 | "size" : "20x20"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "scale" : "1x",
56 | "size" : "29x29"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "scale" : "2x",
61 | "size" : "29x29"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "scale" : "1x",
66 | "size" : "40x40"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "scale" : "2x",
71 | "size" : "40x40"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "scale" : "1x",
76 | "size" : "76x76"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "scale" : "2x",
81 | "size" : "76x76"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "scale" : "2x",
86 | "size" : "83.5x83.5"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "scale" : "1x",
91 | "size" : "1024x1024"
92 | }
93 | ],
94 | "info" : {
95 | "author" : "xcode",
96 | "version" : 1
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Example/Example/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // Example
4 | //
5 | // Created by Parth Gohel on 10/05/22.
6 | //
7 |
8 | import UIKit
9 |
10 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
11 |
12 | var window: UIWindow?
13 |
14 |
15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
16 | // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
17 | // If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
18 | // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
19 | guard let _ = (scene as? UIWindowScene) else { return }
20 | }
21 |
22 | func sceneDidDisconnect(_ scene: UIScene) {
23 | // Called as the scene is being released by the system.
24 | // This occurs shortly after the scene enters the background, or when its session is discarded.
25 | // Release any resources associated with this scene that can be re-created the next time the scene connects.
26 | // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
27 | }
28 |
29 | func sceneDidBecomeActive(_ scene: UIScene) {
30 | // Called when the scene has moved from an inactive state to an active state.
31 | // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
32 | }
33 |
34 | func sceneWillResignActive(_ scene: UIScene) {
35 | // Called when the scene will move from an active state to an inactive state.
36 | // This may occur due to temporary interruptions (ex. an incoming phone call).
37 | }
38 |
39 | func sceneWillEnterForeground(_ scene: UIScene) {
40 | // Called as the scene transitions from the background to the foreground.
41 | // Use this method to undo the changes made on entering the background.
42 | }
43 |
44 | func sceneDidEnterBackground(_ scene: UIScene) {
45 | // Called as the scene transitions from the foreground to the background.
46 | // Use this method to save data, release shared resources, and store enough scene-specific state information
47 | // to restore the scene back to its current state.
48 | }
49 |
50 |
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## User settings
6 | xcuserdata/
7 |
8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
9 | *.xcscmblueprint
10 | *.xccheckout
11 |
12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
13 | build/
14 | DerivedData/
15 | *.moved-aside
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 |
28 | ## App packaging
29 | *.ipa
30 | *.dSYM.zip
31 | *.dSYM
32 |
33 | ## Playgrounds
34 | timeline.xctimeline
35 | playground.xcworkspace
36 |
37 | # Swift Package Manager
38 | #
39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
40 | # Packages/
41 | # Package.pins
42 | # Package.resolved
43 | # *.xcodeproj
44 | #
45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
46 | # hence it is not needed unless you have added a package configuration file to your project
47 | # .swiftpm
48 |
49 | .build/
50 |
51 | # CocoaPods
52 | #
53 | # We recommend against adding the Pods directory to your .gitignore. However
54 | # you should judge for yourself, the pros and cons are mentioned at:
55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
56 | #
57 | # Pods/
58 | #
59 | # Add this line if you want to avoid checking in source code from the Xcode workspace
60 | # *.xcworkspace
61 |
62 | # Carthage
63 | #
64 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
65 | # Carthage/Checkouts
66 |
67 | Carthage/Build/
68 |
69 | # Accio dependency management
70 | Dependencies/
71 | .accio/
72 |
73 | # fastlane
74 | #
75 | # It is recommended to not store the screenshots in the git repo.
76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed.
77 | # For more information about the recommended setup visit:
78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
79 |
80 | fastlane/report.xml
81 | fastlane/Preview.html
82 | fastlane/screenshots/**/*.png
83 | fastlane/test_output
84 |
85 | # Code Injection
86 | #
87 | # After new code Injection tools there's a generated folder /iOSInjectionProject
88 | # https://github.com/johnno1962/injectionforxcode
89 |
90 | iOSInjectionProject/
91 |
--------------------------------------------------------------------------------
/Example/Example/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Example
4 | //
5 | // Created by Parth Gohel on 10/05/22.
6 | //
7 |
8 | import UIKit
9 | import TopTabBarView
10 |
11 | class ViewController: UIViewController {
12 |
13 | @IBOutlet private weak var topTabBarView: TopTabbarView!
14 | @IBOutlet private weak var pageContainerView: UIView!
15 |
16 | private var pageViewController: UIPageViewController!
17 | private var viewControllers: [UIViewController] = []
18 | private var collectionDataSource: [String] = ["M", "I", "N", "D", "3", "0", "0"]
19 |
20 | var selectedIndex: Int = 0
21 |
22 | override func viewDidLoad() {
23 | super.viewDidLoad()
24 | configureTabBarItem()
25 | configurePageViewController()
26 | }
27 |
28 | private func configureTabBarItem() {
29 |
30 | topTabBarView.dataSource = collectionDataSource
31 | topTabBarView.dotColor = .white
32 | topTabBarView.waveHeight = 20
33 | topTabBarView.leftPadding = 60
34 | topTabBarView.rightPadding = 60
35 | topTabBarView.tabBarColor = .red
36 | view.backgroundColor = .red
37 | topTabBarView.onItemSelected = {[weak self] (index) in
38 | self?.selectedIndex = index
39 | self?.pageViewController.setViewControllers([(self?.viewControllers[index] ?? UIViewController())], direction: .forward, animated: false, completion: nil)
40 | }
41 | topTabBarView.isScaleItem = true
42 | topTabBarView.tabBarItemStyle = .setStyle(font: UIFont.boldSystemFont(ofSize: 18),
43 | foregroundColor: .white)
44 | topTabBarView.selectedTab = 1
45 | applyCorner()
46 | }
47 |
48 | func applyCorner() {
49 | DispatchQueue.main.async {
50 | let rectShape = CAShapeLayer()
51 | rectShape.bounds = self.topTabBarView.contentView.bounds
52 | rectShape.position = self.topTabBarView.contentView.center
53 | rectShape.path = UIBezierPath(roundedRect: self.topTabBarView.contentView.bounds, byRoundingCorners: [.bottomLeft , .bottomRight], cornerRadii: CGSize(width: 50, height: 50)).cgPath
54 |
55 | self.topTabBarView.contentView.layer.backgroundColor = UIColor.red.cgColor
56 | self.topTabBarView.contentView.layer.mask = rectShape
57 | }
58 | }
59 |
60 | private func configurePageViewController() {
61 |
62 | viewControllers = []
63 |
64 | _ = collectionDataSource.enumerated().map { (index, title) in
65 | let viewController = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(identifier: "ContentViewController") as! ContentViewController
66 | viewController.view.tag = index
67 | viewController.update(with: title)
68 | viewController.view.backgroundColor = .white
69 | viewControllers.append(viewController)
70 | }
71 |
72 | self.pageViewController = UIPageViewController.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
73 | self.pageViewController.view.frame = CGRect.init(x: 0, y: 0, width: self.pageContainerView.frame.width, height: self.pageContainerView.frame.height)
74 | addChild(self.pageViewController)
75 | self.pageViewController.setViewControllers([viewControllers[0]], direction: .forward, animated: true, completion: nil)
76 | self.pageContainerView.addSubview(pageViewController.view)
77 | self.pageViewController.didMove(toParent: self)
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS-Top-Tab-Navigation
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Good news for all our users out there! Now there are no boundaries to your convenience, you can pass as much words as you want and bind the same number of pages using page control, their is no limit of words and neither for your easiness.
16 |
17 | Checkout this super easy navigation integration and example.!!!
18 |
19 |
20 |
21 |
22 |
23 | ## Installation
24 | To install it, simply add the following line to your Podfile:
25 |
26 | ```ruby
27 | pod 'TopTabBarView', git: 'https://github.com/parthgohel2810/TopTabBarView-Framework.git', branch: 'main'
28 | ```
29 | Then run `pod install` from the Example directory.
30 |
31 | ## Usage
32 |
33 | 1. Change the class of a view from UIView to TopTabbarView
34 | ```swift
35 | @IBOutlet private weak var topTabBarView: TopTabbarView!
36 | ```
37 | 2. Programmatically:
38 |
39 | ```swift
40 | let topTabBarView = TopTabbarView(frame: myFrame)
41 |
42 | ```
43 |
44 | ## Customization
45 |
46 | ```swift
47 | private func configureTabBarItem() {
48 |
49 | topTabBarView.dataSource = ["M", "I", "N", "D", "I", "N", "V", "E", "N", "T", "O", "R", "Y"]
50 | topTabBarView.dotColor = .white
51 | topTabBarView.waveHeight = 16
52 | topTabBarView.leftPadding = 10
53 | topTabBarView.rightPadding = 10
54 | topTabBarView.tabBarColor = .red
55 | topTabBarView.onItemSelected = { (index) in
56 | debugPrint("tabIndex: \(index)")
57 | }
58 | topTabBarView.isScaleItem = true
59 | topTabBarView.tabBarItemStyle = .setStyle(font: UIFont.boldSystemFont(ofSize: 18),
60 | foregroundColor: .white)
61 | }
62 | ```
63 |
64 | #### dataSource
65 | The dataSource property accepts string array which is used to display title of tab and creates number of tab that you want to create.
66 |
67 | #### dotColor
68 | The dotColor property change the color of dot which is place at center of wave.
69 |
70 | #### waveHeight
71 | The waveHeight property change height of wave.
72 |
73 | #### leftPadding, rightPadding
74 | The left and right padding property will change the tabBar left and right padding to the view.
75 |
76 | #### tabBarColor
77 | The tabBarColor property used to change background color of tabbar color.
78 |
79 | #### isScaleItem
80 | The isScaleItem property enables you to off/on scaling of tab titles.
81 |
82 | #### tabBarItemStyle
83 | The tabBarItemStyle used to tabBarItem font and textColor.
84 |
85 | #### selectedTab
86 | The selectedTab used to set selected tab initially.
87 |
88 | #### setSelectedTab(with index: Int)
89 | This function used to set selected tab programmatically.
90 |
91 | #### onItemSelected
92 | You will receive selected tab index in onItemSelected clouser.
93 | ```swift
94 | topTabBarView.onItemSelected = { (index) in
95 | debugPrint("tabIndex: \(index)")
96 | }
97 | ```
98 |
99 | ## Requirements
100 | - iOS 13.0+
101 | - Xcode 13.0+
102 |
103 |
104 | ## 📱 Check out other lists of our Mobile UI libraries
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 | ## 💻 Check out other lists of Web libraries
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | ## Check out our Work
137 |
138 |
139 |
140 |
141 | ## 📄 License
142 | iOS-Top-Tab-Navigation is [MIT-licensed](/LICENSE).
143 |
144 |
145 | If you use our open-source libraries in your project, please make sure to credit us and Give a star to www.mindinventory.com
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/TopTabBarView/Source/TabBarCollectionView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TabBarCollectionView.swift
3 | // TopTabbarView
4 | //
5 | // Created by Parth Gohel on 06/05/22.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | public class TabBarCollectionView: UICollectionView {
12 |
13 | /// Fill color of back wave layer
14 | var layerFillColor: UIColor {
15 | get {
16 | return UIColor(cgColor: kLayerFillColor)
17 | }
18 | set{
19 | kLayerFillColor = newValue.cgColor
20 | backgroundColor = newValue
21 | }
22 | }
23 |
24 | var numberOfItem: Int = 0
25 |
26 | /// Wave Height
27 | var waveHeight: CGFloat {
28 | get{
29 | return self.minimalHeight
30 | }
31 | set{
32 | self.minimalHeight = newValue
33 | }
34 | }
35 |
36 | var numberOfTabItem: Int {
37 | get {
38 | return numberOfItem
39 | } set {
40 | numberOfItem = newValue
41 | }
42 | }
43 |
44 | var dotColor: UIColor = .red {
45 | didSet {
46 | circlePoint.backgroundColor = dotColor
47 | }
48 | }
49 | internal var minimalHeight: CGFloat = 18
50 | private var kLayerFillColor: CGColor = UIColor.red.cgColor
51 | private var displayLink: CADisplayLink!
52 | var count: Int = 0
53 | private let tabBarShapeLayer = CAShapeLayer()
54 | var animating = false {
55 | didSet {
56 | if animating {
57 | displayLink?.isPaused = false
58 | count = 0
59 | }
60 | }
61 | }
62 | var selectedTab: Int = 1
63 | /// Controll point of wave
64 |
65 | private var leftPoint4 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
66 | didSet {
67 | leftPoint4.backgroundColor = .clear
68 | }
69 | }
70 | private var leftPoint3 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
71 | didSet {
72 | leftPoint3.backgroundColor = .clear
73 | }
74 | }
75 | private var leftPoint2 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
76 | didSet {
77 | leftPoint2.backgroundColor = .clear
78 | }
79 | }
80 | private var leftPoint1 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
81 | didSet {
82 | leftPoint1.backgroundColor = .clear
83 | }
84 | }
85 | private var centerPoint1 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
86 | didSet {
87 | centerPoint1.backgroundColor = .clear
88 | }
89 | }
90 | private var centerPoint2 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
91 | didSet {
92 | centerPoint2.backgroundColor = .clear
93 | }
94 | }
95 | private var rightPoint1 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
96 | didSet {
97 | rightPoint1.backgroundColor = .clear
98 | }
99 | }
100 | private var rightPoint2 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
101 | didSet {
102 | rightPoint2.backgroundColor = .clear
103 | }
104 | }
105 | private var rightPoint4 = UIView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
106 | didSet {
107 | rightPoint4.backgroundColor = .clear
108 | }
109 | }
110 | private var circlePoint = CircleView(frame: CGRect(x: 0.0, y: 0.0, width: 8, height: 8)) {
111 | didSet {
112 | circlePoint.backgroundColor = .clear
113 | }
114 | }
115 |
116 | /// Draws the receiver’s image within the passed-in rectangle.
117 | ///
118 | /// - Parameter rect: rect of view
119 | override public func draw(_ rect: CGRect) {
120 | super.draw(rect)
121 | self.setupTabBar()
122 | }
123 | }
124 |
125 | // MARK: - Setup Tabbar
126 | extension TabBarCollectionView {
127 |
128 | func setupTabBar() {
129 |
130 | guard numberOfItem != 0 else { return }
131 | clipsToBounds = false
132 | addSubview(leftPoint4)
133 | addSubview(leftPoint3)
134 | addSubview(leftPoint2)
135 | addSubview(leftPoint1)
136 | addSubview(centerPoint1)
137 | addSubview(centerPoint2)
138 | addSubview(rightPoint1)
139 | addSubview(rightPoint2)
140 | addSubview(rightPoint4)
141 | addSubview(circlePoint)
142 | displayLink = CADisplayLink(target: self, selector: #selector(updateShapeLayer))
143 | displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
144 | displayLink?.isPaused = true
145 | tabBarShapeLayer.fillColor = kLayerFillColor
146 | layer.insertSublayer(tabBarShapeLayer, at: 0)
147 | update(with: selectedTab)
148 | updateShapeLayer()
149 | }
150 |
151 | func update(with index: Int) {
152 | guard numberOfItem != 0
153 | else { return }
154 | let width = (self.bounds.width)/CGFloat(numberOfItem)
155 | let changeValue = (width*(CGFloat(index)))-(width/2)
156 | setDefaultlayoutControlPoints(waveHeight: minimalHeight, locationX: changeValue)
157 | }
158 | }
159 |
160 | // MARK: - Set layer path
161 | extension TabBarCollectionView {
162 |
163 | func setDefaultlayoutControlPoints(waveHeight: CGFloat, locationX: CGFloat) {
164 |
165 | let width = (bounds.width/CGFloat(numberOfItem))
166 | leftPoint4.center = CGPoint(x: 0, y: bounds.maxY)
167 | rightPoint4.center = CGPoint(x: bounds.width, y: bounds.maxY)
168 |
169 | let imaganaeryFram = CGRect(x: locationX-(width/2), y: self.bounds.maxY + minimalHeight , width: width, height: minimalHeight)
170 |
171 | leftPoint3.center = CGPoint(x: imaganaeryFram.minX - width/2, y: self.bounds.maxY)
172 |
173 | let topOffset: CGFloat = imaganaeryFram.width / 4.3
174 | let bottomOffset: CGFloat = imaganaeryFram.width / 4.5
175 |
176 | leftPoint2.center = CGPoint(x: imaganaeryFram.midX, y: imaganaeryFram.minY)
177 | leftPoint1.center = CGPoint(x: imaganaeryFram.minX + bottomOffset, y: self.bounds.maxY)
178 | centerPoint1.center = CGPoint(x: imaganaeryFram.midX - topOffset - 8, y: imaganaeryFram.minY)
179 | centerPoint2.center = CGPoint(x: imaganaeryFram.maxX + width/2, y: self.bounds.maxY)
180 | rightPoint1.center = CGPoint(x: imaganaeryFram.midX + topOffset + 8, y: imaganaeryFram.minY)
181 | rightPoint2.center = CGPoint(x: imaganaeryFram.maxX - bottomOffset, y: self.bounds.maxY)
182 | circlePoint.center = CGPoint(x: leftPoint2.center.x, y: self.bounds.maxY+4)
183 | }
184 |
185 | /// updateShapeLayer
186 | @objc func updateShapeLayer() {
187 | count += 1
188 | if count == 50 {
189 | displayLink?.isPaused = true
190 | }
191 | tabBarShapeLayer.path = getCurrentPath()
192 | }
193 |
194 | /// Get path
195 | ///
196 | /// - Returns: get current index path
197 | func getCurrentPath() -> CGPath {
198 |
199 | let bezierPath = UIBezierPath()
200 | bezierPath.move(to: CGPoint(x: 0.0, y: self.bounds.height))
201 | bezierPath.addLine(to: CGPoint(x: 0.0, y: leftPoint4.viewCenter(usePresentationLayerIfPossible: animating).y))
202 | bezierPath.addLine(to: leftPoint3.viewCenter(usePresentationLayerIfPossible: animating))
203 | bezierPath.addCurve(
204 | to: leftPoint2.viewCenter(usePresentationLayerIfPossible: animating),
205 | controlPoint1: leftPoint1.viewCenter(usePresentationLayerIfPossible: animating),
206 | controlPoint2: centerPoint1.viewCenter(usePresentationLayerIfPossible: animating)
207 | )
208 | bezierPath.addCurve(
209 | to: centerPoint2.viewCenter(usePresentationLayerIfPossible: animating),
210 | controlPoint1: rightPoint1.viewCenter(usePresentationLayerIfPossible: animating),
211 | controlPoint2: rightPoint2.viewCenter(usePresentationLayerIfPossible: animating)
212 | )
213 | bezierPath.addLine(to: leftPoint3.viewCenter(usePresentationLayerIfPossible: animating))
214 | bezierPath.addLine(to: rightPoint4.viewCenter(usePresentationLayerIfPossible: animating))
215 | bezierPath.addLine(to: CGPoint(x: self.bounds.width, y: self.bounds.height))
216 | bezierPath.close()
217 | return bezierPath.cgPath
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/Example/Example/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/TopTabBarView/Source/TopTabbarView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TopTabbarView.swift
3 | // TopTabbarView
4 | //
5 | // Created by Parth Gohel on 09/05/22.
6 | //
7 |
8 | import Foundation
9 | import UIKit
10 |
11 | final class ItemCollectionViewCell: UICollectionViewCell {
12 |
13 | var tabbarTitleLabel: UILabel = UILabel(frame: .zero)
14 |
15 | override init(frame : CGRect) {
16 | super.init(frame : frame)
17 | loadTitleLabel()
18 | configureLabel()
19 | }
20 |
21 | required init?(coder: NSCoder) {
22 | super.init(coder: coder)
23 | }
24 |
25 | override func awakeFromNib() {
26 | super.awakeFromNib()
27 | backgroundColor = .clear
28 | }
29 |
30 | private func loadTitleLabel() {
31 |
32 | tabbarTitleLabel.translatesAutoresizingMaskIntoConstraints = false
33 | contentView.addSubview(tabbarTitleLabel)
34 | NSLayoutConstraint.activate([
35 | tabbarTitleLabel.topAnchor.constraint(equalTo: contentView.topAnchor),
36 | tabbarTitleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
37 | tabbarTitleLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
38 | tabbarTitleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
39 | ])
40 | }
41 |
42 | private func configureLabel() {
43 | tabbarTitleLabel.textAlignment = .center
44 | }
45 |
46 | func configure(with title: String) {
47 | tabbarTitleLabel.text = title
48 | }
49 |
50 | func configureStyle(
51 | font: UIFont = UIFont.boldSystemFont(ofSize: 18),
52 | foregroundColor: UIColor = .white
53 | ){
54 | tabbarTitleLabel.font = font
55 | tabbarTitleLabel.textColor = foregroundColor
56 | }
57 | }
58 |
59 | public enum TabBarItemStyle {
60 | case setStyle(font:UIFont, foregroundColor: UIColor)
61 | case none
62 | }
63 |
64 | public class TopTabbarView: UIView {
65 |
66 | public var collectionView: TabBarCollectionView = TabBarCollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout.init())
67 |
68 | public var dataSource: [String] = [] {
69 | didSet {
70 | collectionView.numberOfTabItem = dataSource.count
71 | }
72 | }
73 |
74 | public var dotColor: UIColor = .red {
75 | didSet {
76 | collectionView.dotColor = dotColor
77 | }
78 | }
79 |
80 | /// Wave Height
81 | public var waveHeight: CGFloat = 20 {
82 | didSet {
83 | collectionView.waveHeight = waveHeight
84 | }
85 | }
86 |
87 | public var leftPadding: CGFloat = 50 {
88 | didSet {
89 | leadingConstraint?.constant = leftPadding
90 | }
91 | }
92 |
93 | public var tabBarColor: UIColor = .systemBlue {
94 | didSet {
95 | collectionView.layerFillColor = tabBarColor
96 | contentView.backgroundColor = tabBarColor
97 | backgroundColor = .clear
98 | }
99 | }
100 |
101 | public var rightPadding: CGFloat = 50 {
102 | didSet {
103 | trailingConstraint?.constant = -rightPadding
104 | }
105 | }
106 | public var tabBarItemStyle: TabBarItemStyle = .none {
107 | didSet {
108 | collectionView.reloadData()
109 | }
110 | }
111 | public var selectedTab: Int = 1 {
112 | didSet {
113 | collectionView.selectedTab = selectedTab
114 | }
115 | }
116 |
117 | public var isScaleItem: Bool = true
118 | public var onItemSelected: ((Int) -> Void)?
119 | public var contentView: UIView = UIView(frame: .zero)
120 |
121 | var leadingConstraint: NSLayoutConstraint?
122 | var trailingConstraint: NSLayoutConstraint?
123 | private var priviousSelectedIndex: Int = -1
124 |
125 | public override func awakeFromNib() {
126 | super.awakeFromNib()
127 | loadCollectionView()
128 | loadContentView()
129 | configureCollectionView()
130 | }
131 | }
132 |
133 | extension TopTabbarView {
134 |
135 | private func loadContentView() {
136 |
137 | contentView.translatesAutoresizingMaskIntoConstraints = false
138 | addSubview(contentView)
139 | NSLayoutConstraint.activate([
140 | contentView.topAnchor.constraint(equalTo: topAnchor, constant: 0),
141 | contentView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -collectionView.minimalHeight),
142 | contentView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0),
143 | contentView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0),
144 | ])
145 |
146 | contentView.backgroundColor = .orange
147 | contentView.superview?.sendSubviewToBack(contentView)
148 | }
149 |
150 | private func loadCollectionView() {
151 |
152 | collectionView.translatesAutoresizingMaskIntoConstraints = false
153 | addSubview(collectionView)
154 | leadingConstraint = collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: leftPadding)
155 | trailingConstraint = collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -rightPadding)
156 | NSLayoutConstraint.activate([
157 | collectionView.topAnchor.constraint(equalTo: topAnchor, constant: 0),
158 | collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -collectionView.minimalHeight),
159 | leadingConstraint!,
160 | trailingConstraint!,
161 | ])
162 |
163 | collectionView.register(ItemCollectionViewCell.self, forCellWithReuseIdentifier: "ItemCollectionViewCell")
164 | }
165 |
166 | private func configureCollectionView() {
167 |
168 | let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
169 | layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
170 | layout.minimumInteritemSpacing = 0
171 | layout.minimumLineSpacing = 0
172 | collectionView.setCollectionViewLayout(layout, animated: true)
173 | collectionView.delegate = self
174 | collectionView.dataSource = self
175 | collectionView.layerFillColor = tabBarColor
176 | contentView.backgroundColor = tabBarColor
177 | collectionView.numberOfTabItem = dataSource.count
178 | }
179 |
180 | private func performSpringAnimation(for cell: ItemCollectionViewCell, index: Int) {
181 | UIView.animate(withDuration: 0.75, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: [], animations: { () -> Void in
182 | self.collectionView.update(with: index)
183 |
184 | }, completion: { _ in
185 | self.collectionView.animating = false
186 | })
187 | UIView.animate(withDuration: 0.75, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: .curveEaseInOut, animations: {
188 | if self.isScaleItem {
189 | cell.tabbarTitleLabel.transform = CGAffineTransform.init(scaleX: 1.5, y: 1.5)
190 | }
191 | }, completion: nil)
192 | }
193 |
194 | public func setSelectedTab(with index: Int) {
195 |
196 | if index != self.priviousSelectedIndex {
197 |
198 | collectionView.animating = true
199 |
200 | let orderedTabBarItemViews: [UIView] = {
201 | let interactionViews = collectionView.subviews.filter({ $0 is ItemCollectionViewCell })
202 | return interactionViews.sorted(by: { $0.frame.minX < $1.frame.minX })
203 | }()
204 |
205 | orderedTabBarItemViews.forEach({ (objectView) in
206 | let objectIndex = orderedTabBarItemViews.firstIndex(of: objectView)
207 | if index == objectIndex {}
208 | else if objectIndex == priviousSelectedIndex {
209 | guard let cell = collectionView.cellForItem(at: [0, priviousSelectedIndex]) as? ItemCollectionViewCell
210 | else { return }
211 | UIView.animate(withDuration: 0.75, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.0, options: .curveEaseInOut, animations: {
212 | if self.isScaleItem {
213 | cell.tabbarTitleLabel.transform = CGAffineTransform.init(scaleX: 1, y: 1)
214 | }
215 | }, completion: nil)
216 | }
217 | })
218 | priviousSelectedIndex = index
219 | guard let cell = collectionView.cellForItem(at: [0,index]) as? ItemCollectionViewCell
220 | else { return }
221 | performSpringAnimation(for: cell, index: index+1)
222 | }
223 | }
224 | }
225 |
226 | extension TopTabbarView: UICollectionViewDelegate,
227 | UICollectionViewDataSource,
228 | UICollectionViewDelegateFlowLayout {
229 | public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
230 | dataSource.count
231 | }
232 |
233 | public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
234 | guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ItemCollectionViewCell", for: indexPath) as? ItemCollectionViewCell
235 | else { return UICollectionViewCell() }
236 | cell.configure(with: dataSource[indexPath.row])
237 | switch tabBarItemStyle {
238 | case .setStyle(let font, let foreground):
239 | cell.configureStyle(font: font, foregroundColor: foreground)
240 | case .none: break
241 | }
242 | return cell
243 | }
244 |
245 | public func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
246 | return CGSize(width: (collectionView.frame.size.width)/CGFloat(dataSource.count), height: collectionView.bounds.size.height)
247 | }
248 |
249 | public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
250 | onItemSelected?(indexPath.row)
251 | setSelectedTab(with: indexPath.row)
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/TopTabBarView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 63703BEA2829366E008F4ABC /* TopTabBarView.docc in Sources */ = {isa = PBXBuildFile; fileRef = 63703BE92829366E008F4ABC /* TopTabBarView.docc */; };
11 | 63703BEB2829366E008F4ABC /* TopTabBarView.h in Headers */ = {isa = PBXBuildFile; fileRef = 63703BE82829366E008F4ABC /* TopTabBarView.h */; settings = {ATTRIBUTES = (Public, ); }; };
12 | 63703C32282940C6008F4ABC /* UIView+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63703C2E282940C6008F4ABC /* UIView+Extension.swift */; };
13 | 63703C33282940C6008F4ABC /* TopTabbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63703C2F282940C6008F4ABC /* TopTabbarView.swift */; };
14 | 63703C34282940C6008F4ABC /* CircleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63703C30282940C6008F4ABC /* CircleView.swift */; };
15 | 63703C35282940C6008F4ABC /* TabBarCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 63703C31282940C6008F4ABC /* TabBarCollectionView.swift */; };
16 | 63703C38282940CE008F4ABC /* demo.mov in Resources */ = {isa = PBXBuildFile; fileRef = 63703C37282940CE008F4ABC /* demo.mov */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 63703BE52829366E008F4ABC /* TopTabBarView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TopTabBarView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
21 | 63703BE82829366E008F4ABC /* TopTabBarView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TopTabBarView.h; sourceTree = ""; };
22 | 63703BE92829366E008F4ABC /* TopTabBarView.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = TopTabBarView.docc; sourceTree = ""; };
23 | 63703C2E282940C6008F4ABC /* UIView+Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extension.swift"; sourceTree = ""; };
24 | 63703C2F282940C6008F4ABC /* TopTabbarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TopTabbarView.swift; sourceTree = ""; };
25 | 63703C30282940C6008F4ABC /* CircleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CircleView.swift; sourceTree = ""; };
26 | 63703C31282940C6008F4ABC /* TabBarCollectionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarCollectionView.swift; sourceTree = ""; };
27 | 63703C37282940CE008F4ABC /* demo.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = demo.mov; sourceTree = ""; };
28 | /* End PBXFileReference section */
29 |
30 | /* Begin PBXFrameworksBuildPhase section */
31 | 63703BE22829366E008F4ABC /* Frameworks */ = {
32 | isa = PBXFrameworksBuildPhase;
33 | buildActionMask = 2147483647;
34 | files = (
35 | );
36 | runOnlyForDeploymentPostprocessing = 0;
37 | };
38 | /* End PBXFrameworksBuildPhase section */
39 |
40 | /* Begin PBXGroup section */
41 | 63703BDB2829366E008F4ABC = {
42 | isa = PBXGroup;
43 | children = (
44 | 63703BE72829366E008F4ABC /* TopTabBarView */,
45 | 63703BE62829366E008F4ABC /* Products */,
46 | );
47 | sourceTree = "";
48 | };
49 | 63703BE62829366E008F4ABC /* Products */ = {
50 | isa = PBXGroup;
51 | children = (
52 | 63703BE52829366E008F4ABC /* TopTabBarView.framework */,
53 | );
54 | name = Products;
55 | sourceTree = "";
56 | };
57 | 63703BE72829366E008F4ABC /* TopTabBarView */ = {
58 | isa = PBXGroup;
59 | children = (
60 | 63703C36282940CE008F4ABC /* Media */,
61 | 63703BE82829366E008F4ABC /* TopTabBarView.h */,
62 | 63703BE92829366E008F4ABC /* TopTabBarView.docc */,
63 | 63703C2D282940C6008F4ABC /* Source */,
64 | );
65 | path = TopTabBarView;
66 | sourceTree = "";
67 | };
68 | 63703C2D282940C6008F4ABC /* Source */ = {
69 | isa = PBXGroup;
70 | children = (
71 | 63703C2E282940C6008F4ABC /* UIView+Extension.swift */,
72 | 63703C2F282940C6008F4ABC /* TopTabbarView.swift */,
73 | 63703C30282940C6008F4ABC /* CircleView.swift */,
74 | 63703C31282940C6008F4ABC /* TabBarCollectionView.swift */,
75 | );
76 | path = Source;
77 | sourceTree = "";
78 | };
79 | 63703C36282940CE008F4ABC /* Media */ = {
80 | isa = PBXGroup;
81 | children = (
82 | 63703C37282940CE008F4ABC /* demo.mov */,
83 | );
84 | path = Media;
85 | sourceTree = "";
86 | };
87 | /* End PBXGroup section */
88 |
89 | /* Begin PBXHeadersBuildPhase section */
90 | 63703BE02829366E008F4ABC /* Headers */ = {
91 | isa = PBXHeadersBuildPhase;
92 | buildActionMask = 2147483647;
93 | files = (
94 | 63703BEB2829366E008F4ABC /* TopTabBarView.h in Headers */,
95 | );
96 | runOnlyForDeploymentPostprocessing = 0;
97 | };
98 | /* End PBXHeadersBuildPhase section */
99 |
100 | /* Begin PBXNativeTarget section */
101 | 63703BE42829366E008F4ABC /* TopTabBarView */ = {
102 | isa = PBXNativeTarget;
103 | buildConfigurationList = 63703BEE2829366E008F4ABC /* Build configuration list for PBXNativeTarget "TopTabBarView" */;
104 | buildPhases = (
105 | 63703BE02829366E008F4ABC /* Headers */,
106 | 63703BE12829366E008F4ABC /* Sources */,
107 | 63703BE22829366E008F4ABC /* Frameworks */,
108 | 63703BE32829366E008F4ABC /* Resources */,
109 | );
110 | buildRules = (
111 | );
112 | dependencies = (
113 | );
114 | name = TopTabBarView;
115 | productName = TopTabBarView;
116 | productReference = 63703BE52829366E008F4ABC /* TopTabBarView.framework */;
117 | productType = "com.apple.product-type.framework";
118 | };
119 | /* End PBXNativeTarget section */
120 |
121 | /* Begin PBXProject section */
122 | 63703BDC2829366E008F4ABC /* Project object */ = {
123 | isa = PBXProject;
124 | attributes = {
125 | BuildIndependentTargetsInParallel = 1;
126 | LastUpgradeCheck = 1320;
127 | TargetAttributes = {
128 | 63703BE42829366E008F4ABC = {
129 | CreatedOnToolsVersion = 13.2.1;
130 | };
131 | };
132 | };
133 | buildConfigurationList = 63703BDF2829366E008F4ABC /* Build configuration list for PBXProject "TopTabBarView" */;
134 | compatibilityVersion = "Xcode 13.0";
135 | developmentRegion = en;
136 | hasScannedForEncodings = 0;
137 | knownRegions = (
138 | en,
139 | Base,
140 | );
141 | mainGroup = 63703BDB2829366E008F4ABC;
142 | productRefGroup = 63703BE62829366E008F4ABC /* Products */;
143 | projectDirPath = "";
144 | projectRoot = "";
145 | targets = (
146 | 63703BE42829366E008F4ABC /* TopTabBarView */,
147 | );
148 | };
149 | /* End PBXProject section */
150 |
151 | /* Begin PBXResourcesBuildPhase section */
152 | 63703BE32829366E008F4ABC /* Resources */ = {
153 | isa = PBXResourcesBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | 63703C38282940CE008F4ABC /* demo.mov in Resources */,
157 | );
158 | runOnlyForDeploymentPostprocessing = 0;
159 | };
160 | /* End PBXResourcesBuildPhase section */
161 |
162 | /* Begin PBXSourcesBuildPhase section */
163 | 63703BE12829366E008F4ABC /* Sources */ = {
164 | isa = PBXSourcesBuildPhase;
165 | buildActionMask = 2147483647;
166 | files = (
167 | 63703C35282940C6008F4ABC /* TabBarCollectionView.swift in Sources */,
168 | 63703C33282940C6008F4ABC /* TopTabbarView.swift in Sources */,
169 | 63703C34282940C6008F4ABC /* CircleView.swift in Sources */,
170 | 63703C32282940C6008F4ABC /* UIView+Extension.swift in Sources */,
171 | 63703BEA2829366E008F4ABC /* TopTabBarView.docc in Sources */,
172 | );
173 | runOnlyForDeploymentPostprocessing = 0;
174 | };
175 | /* End PBXSourcesBuildPhase section */
176 |
177 | /* Begin XCBuildConfiguration section */
178 | 63703BEC2829366E008F4ABC /* Debug */ = {
179 | isa = XCBuildConfiguration;
180 | buildSettings = {
181 | ALWAYS_SEARCH_USER_PATHS = NO;
182 | CLANG_ANALYZER_NONNULL = YES;
183 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
184 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
185 | CLANG_CXX_LIBRARY = "libc++";
186 | CLANG_ENABLE_MODULES = YES;
187 | CLANG_ENABLE_OBJC_ARC = YES;
188 | CLANG_ENABLE_OBJC_WEAK = YES;
189 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
190 | CLANG_WARN_BOOL_CONVERSION = YES;
191 | CLANG_WARN_COMMA = YES;
192 | CLANG_WARN_CONSTANT_CONVERSION = YES;
193 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
194 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
195 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
196 | CLANG_WARN_EMPTY_BODY = YES;
197 | CLANG_WARN_ENUM_CONVERSION = YES;
198 | CLANG_WARN_INFINITE_RECURSION = YES;
199 | CLANG_WARN_INT_CONVERSION = YES;
200 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
201 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
202 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
203 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
204 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
205 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
206 | CLANG_WARN_STRICT_PROTOTYPES = YES;
207 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
208 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
209 | CLANG_WARN_UNREACHABLE_CODE = YES;
210 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
211 | COPY_PHASE_STRIP = NO;
212 | CURRENT_PROJECT_VERSION = 1;
213 | DEBUG_INFORMATION_FORMAT = dwarf;
214 | ENABLE_STRICT_OBJC_MSGSEND = YES;
215 | ENABLE_TESTABILITY = YES;
216 | GCC_C_LANGUAGE_STANDARD = gnu11;
217 | GCC_DYNAMIC_NO_PIC = NO;
218 | GCC_NO_COMMON_BLOCKS = YES;
219 | GCC_OPTIMIZATION_LEVEL = 0;
220 | GCC_PREPROCESSOR_DEFINITIONS = (
221 | "DEBUG=1",
222 | "$(inherited)",
223 | );
224 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
225 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
226 | GCC_WARN_UNDECLARED_SELECTOR = YES;
227 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
228 | GCC_WARN_UNUSED_FUNCTION = YES;
229 | GCC_WARN_UNUSED_VARIABLE = YES;
230 | IPHONEOS_DEPLOYMENT_TARGET = 15.2;
231 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
232 | MTL_FAST_MATH = YES;
233 | ONLY_ACTIVE_ARCH = YES;
234 | SDKROOT = iphoneos;
235 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
236 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
237 | VERSIONING_SYSTEM = "apple-generic";
238 | VERSION_INFO_PREFIX = "";
239 | };
240 | name = Debug;
241 | };
242 | 63703BED2829366E008F4ABC /* Release */ = {
243 | isa = XCBuildConfiguration;
244 | buildSettings = {
245 | ALWAYS_SEARCH_USER_PATHS = NO;
246 | CLANG_ANALYZER_NONNULL = YES;
247 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
249 | CLANG_CXX_LIBRARY = "libc++";
250 | CLANG_ENABLE_MODULES = YES;
251 | CLANG_ENABLE_OBJC_ARC = YES;
252 | CLANG_ENABLE_OBJC_WEAK = YES;
253 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
254 | CLANG_WARN_BOOL_CONVERSION = YES;
255 | CLANG_WARN_COMMA = YES;
256 | CLANG_WARN_CONSTANT_CONVERSION = YES;
257 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
258 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
259 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
260 | CLANG_WARN_EMPTY_BODY = YES;
261 | CLANG_WARN_ENUM_CONVERSION = YES;
262 | CLANG_WARN_INFINITE_RECURSION = YES;
263 | CLANG_WARN_INT_CONVERSION = YES;
264 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
265 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
266 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
267 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
268 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
269 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
270 | CLANG_WARN_STRICT_PROTOTYPES = YES;
271 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
272 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
273 | CLANG_WARN_UNREACHABLE_CODE = YES;
274 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
275 | COPY_PHASE_STRIP = NO;
276 | CURRENT_PROJECT_VERSION = 1;
277 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
278 | ENABLE_NS_ASSERTIONS = NO;
279 | ENABLE_STRICT_OBJC_MSGSEND = YES;
280 | GCC_C_LANGUAGE_STANDARD = gnu11;
281 | GCC_NO_COMMON_BLOCKS = YES;
282 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
283 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
284 | GCC_WARN_UNDECLARED_SELECTOR = YES;
285 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
286 | GCC_WARN_UNUSED_FUNCTION = YES;
287 | GCC_WARN_UNUSED_VARIABLE = YES;
288 | IPHONEOS_DEPLOYMENT_TARGET = 15.2;
289 | MTL_ENABLE_DEBUG_INFO = NO;
290 | MTL_FAST_MATH = YES;
291 | SDKROOT = iphoneos;
292 | SWIFT_COMPILATION_MODE = wholemodule;
293 | SWIFT_OPTIMIZATION_LEVEL = "-O";
294 | VALIDATE_PRODUCT = YES;
295 | VERSIONING_SYSTEM = "apple-generic";
296 | VERSION_INFO_PREFIX = "";
297 | };
298 | name = Release;
299 | };
300 | 63703BEF2829366E008F4ABC /* Debug */ = {
301 | isa = XCBuildConfiguration;
302 | buildSettings = {
303 | CODE_SIGN_STYLE = Automatic;
304 | CURRENT_PROJECT_VERSION = 1;
305 | DEFINES_MODULE = YES;
306 | DYLIB_COMPATIBILITY_VERSION = 1;
307 | DYLIB_CURRENT_VERSION = 1;
308 | DYLIB_INSTALL_NAME_BASE = "@rpath";
309 | GENERATE_INFOPLIST_FILE = YES;
310 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
311 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
312 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
313 | LD_RUNPATH_SEARCH_PATHS = (
314 | "$(inherited)",
315 | "@executable_path/Frameworks",
316 | "@loader_path/Frameworks",
317 | );
318 | MARKETING_VERSION = 1.0;
319 | PRODUCT_BUNDLE_IDENTIFIER = Mindinventory.TopTabBarView;
320 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
321 | SKIP_INSTALL = YES;
322 | SUPPORTS_MACCATALYST = NO;
323 | SWIFT_EMIT_LOC_STRINGS = YES;
324 | SWIFT_VERSION = 5.0;
325 | TARGETED_DEVICE_FAMILY = 1;
326 | };
327 | name = Debug;
328 | };
329 | 63703BF02829366E008F4ABC /* Release */ = {
330 | isa = XCBuildConfiguration;
331 | buildSettings = {
332 | CODE_SIGN_STYLE = Automatic;
333 | CURRENT_PROJECT_VERSION = 1;
334 | DEFINES_MODULE = YES;
335 | DYLIB_COMPATIBILITY_VERSION = 1;
336 | DYLIB_CURRENT_VERSION = 1;
337 | DYLIB_INSTALL_NAME_BASE = "@rpath";
338 | GENERATE_INFOPLIST_FILE = YES;
339 | INFOPLIST_KEY_NSHumanReadableCopyright = "";
340 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
341 | IPHONEOS_DEPLOYMENT_TARGET = 14.0;
342 | LD_RUNPATH_SEARCH_PATHS = (
343 | "$(inherited)",
344 | "@executable_path/Frameworks",
345 | "@loader_path/Frameworks",
346 | );
347 | MARKETING_VERSION = 1.0;
348 | PRODUCT_BUNDLE_IDENTIFIER = Mindinventory.TopTabBarView;
349 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
350 | SKIP_INSTALL = YES;
351 | SUPPORTS_MACCATALYST = NO;
352 | SWIFT_EMIT_LOC_STRINGS = YES;
353 | SWIFT_VERSION = 5.0;
354 | TARGETED_DEVICE_FAMILY = 1;
355 | };
356 | name = Release;
357 | };
358 | /* End XCBuildConfiguration section */
359 |
360 | /* Begin XCConfigurationList section */
361 | 63703BDF2829366E008F4ABC /* Build configuration list for PBXProject "TopTabBarView" */ = {
362 | isa = XCConfigurationList;
363 | buildConfigurations = (
364 | 63703BEC2829366E008F4ABC /* Debug */,
365 | 63703BED2829366E008F4ABC /* Release */,
366 | );
367 | defaultConfigurationIsVisible = 0;
368 | defaultConfigurationName = Release;
369 | };
370 | 63703BEE2829366E008F4ABC /* Build configuration list for PBXNativeTarget "TopTabBarView" */ = {
371 | isa = XCConfigurationList;
372 | buildConfigurations = (
373 | 63703BEF2829366E008F4ABC /* Debug */,
374 | 63703BF02829366E008F4ABC /* Release */,
375 | );
376 | defaultConfigurationIsVisible = 0;
377 | defaultConfigurationName = Release;
378 | };
379 | /* End XCConfigurationList section */
380 | };
381 | rootObject = 63703BDC2829366E008F4ABC /* Project object */;
382 | }
383 |
--------------------------------------------------------------------------------
/Example/Example.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 55;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 630F8CBE282A7349007E467D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 630F8CBD282A7349007E467D /* AppDelegate.swift */; };
11 | 630F8CC0282A7349007E467D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 630F8CBF282A7349007E467D /* SceneDelegate.swift */; };
12 | 630F8CC2282A7349007E467D /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 630F8CC1282A7349007E467D /* ViewController.swift */; };
13 | 630F8CC5282A7349007E467D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 630F8CC3282A7349007E467D /* Main.storyboard */; };
14 | 630F8CC7282A734C007E467D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 630F8CC6282A734C007E467D /* Assets.xcassets */; };
15 | 630F8CCA282A734C007E467D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 630F8CC8282A734C007E467D /* LaunchScreen.storyboard */; };
16 | 6394708D282A827500366C49 /* ContentViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6394708C282A827500366C49 /* ContentViewController.swift */; };
17 | 63947090282A8EA200366C49 /* demo.mov in Resources */ = {isa = PBXBuildFile; fileRef = 6394708F282A8EA200366C49 /* demo.mov */; };
18 | F5F032BC7350E30775486469 /* Pods_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1643FD87C39B7391B4688CC3 /* Pods_Example.framework */; };
19 | /* End PBXBuildFile section */
20 |
21 | /* Begin PBXFileReference section */
22 | 1643FD87C39B7391B4688CC3 /* Pods_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 630F8CBA282A7349007E467D /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
24 | 630F8CBD282A7349007E467D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
25 | 630F8CBF282A7349007E467D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
26 | 630F8CC1282A7349007E467D /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
27 | 630F8CC4282A7349007E467D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
28 | 630F8CC6282A734C007E467D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
29 | 630F8CC9282A734C007E467D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
30 | 630F8CCB282A734C007E467D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 6394708C282A827500366C49 /* ContentViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentViewController.swift; sourceTree = ""; };
32 | 6394708F282A8EA200366C49 /* demo.mov */ = {isa = PBXFileReference; lastKnownFileType = video.quicktime; path = demo.mov; sourceTree = ""; };
33 | 70DD0695FC161CF3FEBAE375 /* Pods-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.release.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.release.xcconfig"; sourceTree = ""; };
34 | 8A6CFF22EFE0000231E55F18 /* Pods-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example.debug.xcconfig"; path = "Target Support Files/Pods-Example/Pods-Example.debug.xcconfig"; sourceTree = ""; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | 630F8CB7282A7349007E467D /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | F5F032BC7350E30775486469 /* Pods_Example.framework in Frameworks */,
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | /* End PBXFrameworksBuildPhase section */
47 |
48 | /* Begin PBXGroup section */
49 | 630F8CB1282A7349007E467D = {
50 | isa = PBXGroup;
51 | children = (
52 | 630F8CBC282A7349007E467D /* Example */,
53 | 630F8CBB282A7349007E467D /* Products */,
54 | A8AC6F8E11404E5996336DF1 /* Pods */,
55 | 7E019F3FE93E233910EFE137 /* Frameworks */,
56 | );
57 | sourceTree = "";
58 | };
59 | 630F8CBB282A7349007E467D /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | 630F8CBA282A7349007E467D /* Example.app */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | 630F8CBC282A7349007E467D /* Example */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 6394708E282A8E9400366C49 /* Media */,
71 | 630F8CBD282A7349007E467D /* AppDelegate.swift */,
72 | 630F8CBF282A7349007E467D /* SceneDelegate.swift */,
73 | 630F8CC1282A7349007E467D /* ViewController.swift */,
74 | 630F8CC3282A7349007E467D /* Main.storyboard */,
75 | 630F8CC6282A734C007E467D /* Assets.xcassets */,
76 | 630F8CC8282A734C007E467D /* LaunchScreen.storyboard */,
77 | 630F8CCB282A734C007E467D /* Info.plist */,
78 | 6394708C282A827500366C49 /* ContentViewController.swift */,
79 | );
80 | path = Example;
81 | sourceTree = "";
82 | };
83 | 6394708E282A8E9400366C49 /* Media */ = {
84 | isa = PBXGroup;
85 | children = (
86 | 6394708F282A8EA200366C49 /* demo.mov */,
87 | );
88 | path = Media;
89 | sourceTree = "";
90 | };
91 | 7E019F3FE93E233910EFE137 /* Frameworks */ = {
92 | isa = PBXGroup;
93 | children = (
94 | 1643FD87C39B7391B4688CC3 /* Pods_Example.framework */,
95 | );
96 | name = Frameworks;
97 | sourceTree = "";
98 | };
99 | A8AC6F8E11404E5996336DF1 /* Pods */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 8A6CFF22EFE0000231E55F18 /* Pods-Example.debug.xcconfig */,
103 | 70DD0695FC161CF3FEBAE375 /* Pods-Example.release.xcconfig */,
104 | );
105 | path = Pods;
106 | sourceTree = "";
107 | };
108 | /* End PBXGroup section */
109 |
110 | /* Begin PBXNativeTarget section */
111 | 630F8CB9282A7349007E467D /* Example */ = {
112 | isa = PBXNativeTarget;
113 | buildConfigurationList = 630F8CCE282A734C007E467D /* Build configuration list for PBXNativeTarget "Example" */;
114 | buildPhases = (
115 | 9A4A6458A4E2BB0E42F60257 /* [CP] Check Pods Manifest.lock */,
116 | 630F8CB6282A7349007E467D /* Sources */,
117 | 630F8CB7282A7349007E467D /* Frameworks */,
118 | 630F8CB8282A7349007E467D /* Resources */,
119 | 1FFF88E1D4279AD486D580B6 /* [CP] Embed Pods Frameworks */,
120 | );
121 | buildRules = (
122 | );
123 | dependencies = (
124 | );
125 | name = Example;
126 | productName = Example;
127 | productReference = 630F8CBA282A7349007E467D /* Example.app */;
128 | productType = "com.apple.product-type.application";
129 | };
130 | /* End PBXNativeTarget section */
131 |
132 | /* Begin PBXProject section */
133 | 630F8CB2282A7349007E467D /* Project object */ = {
134 | isa = PBXProject;
135 | attributes = {
136 | BuildIndependentTargetsInParallel = 1;
137 | LastSwiftUpdateCheck = 1320;
138 | LastUpgradeCheck = 1320;
139 | TargetAttributes = {
140 | 630F8CB9282A7349007E467D = {
141 | CreatedOnToolsVersion = 13.2.1;
142 | };
143 | };
144 | };
145 | buildConfigurationList = 630F8CB5282A7349007E467D /* Build configuration list for PBXProject "Example" */;
146 | compatibilityVersion = "Xcode 13.0";
147 | developmentRegion = en;
148 | hasScannedForEncodings = 0;
149 | knownRegions = (
150 | en,
151 | Base,
152 | );
153 | mainGroup = 630F8CB1282A7349007E467D;
154 | productRefGroup = 630F8CBB282A7349007E467D /* Products */;
155 | projectDirPath = "";
156 | projectRoot = "";
157 | targets = (
158 | 630F8CB9282A7349007E467D /* Example */,
159 | );
160 | };
161 | /* End PBXProject section */
162 |
163 | /* Begin PBXResourcesBuildPhase section */
164 | 630F8CB8282A7349007E467D /* Resources */ = {
165 | isa = PBXResourcesBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | 630F8CCA282A734C007E467D /* LaunchScreen.storyboard in Resources */,
169 | 63947090282A8EA200366C49 /* demo.mov in Resources */,
170 | 630F8CC7282A734C007E467D /* Assets.xcassets in Resources */,
171 | 630F8CC5282A7349007E467D /* Main.storyboard in Resources */,
172 | );
173 | runOnlyForDeploymentPostprocessing = 0;
174 | };
175 | /* End PBXResourcesBuildPhase section */
176 |
177 | /* Begin PBXShellScriptBuildPhase section */
178 | 1FFF88E1D4279AD486D580B6 /* [CP] Embed Pods Frameworks */ = {
179 | isa = PBXShellScriptBuildPhase;
180 | buildActionMask = 2147483647;
181 | files = (
182 | );
183 | inputFileListPaths = (
184 | "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-input-files.xcfilelist",
185 | );
186 | name = "[CP] Embed Pods Frameworks";
187 | outputFileListPaths = (
188 | "${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks-${CONFIGURATION}-output-files.xcfilelist",
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | shellPath = /bin/sh;
192 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Example/Pods-Example-frameworks.sh\"\n";
193 | showEnvVarsInLog = 0;
194 | };
195 | 9A4A6458A4E2BB0E42F60257 /* [CP] Check Pods Manifest.lock */ = {
196 | isa = PBXShellScriptBuildPhase;
197 | buildActionMask = 2147483647;
198 | files = (
199 | );
200 | inputFileListPaths = (
201 | );
202 | inputPaths = (
203 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
204 | "${PODS_ROOT}/Manifest.lock",
205 | );
206 | name = "[CP] Check Pods Manifest.lock";
207 | outputFileListPaths = (
208 | );
209 | outputPaths = (
210 | "$(DERIVED_FILE_DIR)/Pods-Example-checkManifestLockResult.txt",
211 | );
212 | runOnlyForDeploymentPostprocessing = 0;
213 | shellPath = /bin/sh;
214 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
215 | showEnvVarsInLog = 0;
216 | };
217 | /* End PBXShellScriptBuildPhase section */
218 |
219 | /* Begin PBXSourcesBuildPhase section */
220 | 630F8CB6282A7349007E467D /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | 6394708D282A827500366C49 /* ContentViewController.swift in Sources */,
225 | 630F8CC2282A7349007E467D /* ViewController.swift in Sources */,
226 | 630F8CBE282A7349007E467D /* AppDelegate.swift in Sources */,
227 | 630F8CC0282A7349007E467D /* SceneDelegate.swift in Sources */,
228 | );
229 | runOnlyForDeploymentPostprocessing = 0;
230 | };
231 | /* End PBXSourcesBuildPhase section */
232 |
233 | /* Begin PBXVariantGroup section */
234 | 630F8CC3282A7349007E467D /* Main.storyboard */ = {
235 | isa = PBXVariantGroup;
236 | children = (
237 | 630F8CC4282A7349007E467D /* Base */,
238 | );
239 | name = Main.storyboard;
240 | sourceTree = "";
241 | };
242 | 630F8CC8282A734C007E467D /* LaunchScreen.storyboard */ = {
243 | isa = PBXVariantGroup;
244 | children = (
245 | 630F8CC9282A734C007E467D /* Base */,
246 | );
247 | name = LaunchScreen.storyboard;
248 | sourceTree = "";
249 | };
250 | /* End PBXVariantGroup section */
251 |
252 | /* Begin XCBuildConfiguration section */
253 | 630F8CCC282A734C007E467D /* Debug */ = {
254 | isa = XCBuildConfiguration;
255 | buildSettings = {
256 | ALWAYS_SEARCH_USER_PATHS = NO;
257 | CLANG_ANALYZER_NONNULL = YES;
258 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
260 | CLANG_CXX_LIBRARY = "libc++";
261 | CLANG_ENABLE_MODULES = YES;
262 | CLANG_ENABLE_OBJC_ARC = YES;
263 | CLANG_ENABLE_OBJC_WEAK = YES;
264 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
265 | CLANG_WARN_BOOL_CONVERSION = YES;
266 | CLANG_WARN_COMMA = YES;
267 | CLANG_WARN_CONSTANT_CONVERSION = YES;
268 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
269 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
270 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
271 | CLANG_WARN_EMPTY_BODY = YES;
272 | CLANG_WARN_ENUM_CONVERSION = YES;
273 | CLANG_WARN_INFINITE_RECURSION = YES;
274 | CLANG_WARN_INT_CONVERSION = YES;
275 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
276 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
277 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
278 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
279 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
280 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
281 | CLANG_WARN_STRICT_PROTOTYPES = YES;
282 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
283 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
284 | CLANG_WARN_UNREACHABLE_CODE = YES;
285 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
286 | COPY_PHASE_STRIP = NO;
287 | DEBUG_INFORMATION_FORMAT = dwarf;
288 | ENABLE_STRICT_OBJC_MSGSEND = YES;
289 | ENABLE_TESTABILITY = YES;
290 | GCC_C_LANGUAGE_STANDARD = gnu11;
291 | GCC_DYNAMIC_NO_PIC = NO;
292 | GCC_NO_COMMON_BLOCKS = YES;
293 | GCC_OPTIMIZATION_LEVEL = 0;
294 | GCC_PREPROCESSOR_DEFINITIONS = (
295 | "DEBUG=1",
296 | "$(inherited)",
297 | );
298 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
299 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
300 | GCC_WARN_UNDECLARED_SELECTOR = YES;
301 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
302 | GCC_WARN_UNUSED_FUNCTION = YES;
303 | GCC_WARN_UNUSED_VARIABLE = YES;
304 | IPHONEOS_DEPLOYMENT_TARGET = 15.2;
305 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
306 | MTL_FAST_MATH = YES;
307 | ONLY_ACTIVE_ARCH = YES;
308 | SDKROOT = iphoneos;
309 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
310 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
311 | };
312 | name = Debug;
313 | };
314 | 630F8CCD282A734C007E467D /* Release */ = {
315 | isa = XCBuildConfiguration;
316 | buildSettings = {
317 | ALWAYS_SEARCH_USER_PATHS = NO;
318 | CLANG_ANALYZER_NONNULL = YES;
319 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
321 | CLANG_CXX_LIBRARY = "libc++";
322 | CLANG_ENABLE_MODULES = YES;
323 | CLANG_ENABLE_OBJC_ARC = YES;
324 | CLANG_ENABLE_OBJC_WEAK = YES;
325 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
326 | CLANG_WARN_BOOL_CONVERSION = YES;
327 | CLANG_WARN_COMMA = YES;
328 | CLANG_WARN_CONSTANT_CONVERSION = YES;
329 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
330 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
331 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
332 | CLANG_WARN_EMPTY_BODY = YES;
333 | CLANG_WARN_ENUM_CONVERSION = YES;
334 | CLANG_WARN_INFINITE_RECURSION = YES;
335 | CLANG_WARN_INT_CONVERSION = YES;
336 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
337 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
338 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
339 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
340 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
341 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
342 | CLANG_WARN_STRICT_PROTOTYPES = YES;
343 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
344 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
345 | CLANG_WARN_UNREACHABLE_CODE = YES;
346 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
347 | COPY_PHASE_STRIP = NO;
348 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
349 | ENABLE_NS_ASSERTIONS = NO;
350 | ENABLE_STRICT_OBJC_MSGSEND = YES;
351 | GCC_C_LANGUAGE_STANDARD = gnu11;
352 | GCC_NO_COMMON_BLOCKS = YES;
353 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
354 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
355 | GCC_WARN_UNDECLARED_SELECTOR = YES;
356 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
357 | GCC_WARN_UNUSED_FUNCTION = YES;
358 | GCC_WARN_UNUSED_VARIABLE = YES;
359 | IPHONEOS_DEPLOYMENT_TARGET = 15.2;
360 | MTL_ENABLE_DEBUG_INFO = NO;
361 | MTL_FAST_MATH = YES;
362 | SDKROOT = iphoneos;
363 | SWIFT_COMPILATION_MODE = wholemodule;
364 | SWIFT_OPTIMIZATION_LEVEL = "-O";
365 | VALIDATE_PRODUCT = YES;
366 | };
367 | name = Release;
368 | };
369 | 630F8CCF282A734C007E467D /* Debug */ = {
370 | isa = XCBuildConfiguration;
371 | baseConfigurationReference = 8A6CFF22EFE0000231E55F18 /* Pods-Example.debug.xcconfig */;
372 | buildSettings = {
373 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
374 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
375 | CODE_SIGN_IDENTITY = "iPhone Developer";
376 | CODE_SIGN_STYLE = Manual;
377 | CURRENT_PROJECT_VERSION = 1;
378 | DEVELOPMENT_TEAM = 7224G6JACN;
379 | GENERATE_INFOPLIST_FILE = YES;
380 | INFOPLIST_FILE = Example/Info.plist;
381 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
382 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
383 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
384 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
385 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
386 | LD_RUNPATH_SEARCH_PATHS = (
387 | "$(inherited)",
388 | "@executable_path/Frameworks",
389 | );
390 | MARKETING_VERSION = 1.0;
391 | PRODUCT_BUNDLE_IDENTIFIER = Mindinventory.Example;
392 | PRODUCT_NAME = "$(TARGET_NAME)";
393 | PROVISIONING_PROFILE_SPECIFIER = MI_WildCard_Dev;
394 | SWIFT_EMIT_LOC_STRINGS = YES;
395 | SWIFT_VERSION = 5.0;
396 | TARGETED_DEVICE_FAMILY = 1;
397 | };
398 | name = Debug;
399 | };
400 | 630F8CD0282A734C007E467D /* Release */ = {
401 | isa = XCBuildConfiguration;
402 | baseConfigurationReference = 70DD0695FC161CF3FEBAE375 /* Pods-Example.release.xcconfig */;
403 | buildSettings = {
404 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
405 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
406 | CODE_SIGN_IDENTITY = "iPhone Developer";
407 | CODE_SIGN_STYLE = Manual;
408 | CURRENT_PROJECT_VERSION = 1;
409 | DEVELOPMENT_TEAM = 7224G6JACN;
410 | GENERATE_INFOPLIST_FILE = YES;
411 | INFOPLIST_FILE = Example/Info.plist;
412 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
413 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
414 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
415 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
416 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
417 | LD_RUNPATH_SEARCH_PATHS = (
418 | "$(inherited)",
419 | "@executable_path/Frameworks",
420 | );
421 | MARKETING_VERSION = 1.0;
422 | PRODUCT_BUNDLE_IDENTIFIER = Mindinventory.Example;
423 | PRODUCT_NAME = "$(TARGET_NAME)";
424 | PROVISIONING_PROFILE_SPECIFIER = MI_WildCard_Dev;
425 | SWIFT_EMIT_LOC_STRINGS = YES;
426 | SWIFT_VERSION = 5.0;
427 | TARGETED_DEVICE_FAMILY = 1;
428 | };
429 | name = Release;
430 | };
431 | /* End XCBuildConfiguration section */
432 |
433 | /* Begin XCConfigurationList section */
434 | 630F8CB5282A7349007E467D /* Build configuration list for PBXProject "Example" */ = {
435 | isa = XCConfigurationList;
436 | buildConfigurations = (
437 | 630F8CCC282A734C007E467D /* Debug */,
438 | 630F8CCD282A734C007E467D /* Release */,
439 | );
440 | defaultConfigurationIsVisible = 0;
441 | defaultConfigurationName = Release;
442 | };
443 | 630F8CCE282A734C007E467D /* Build configuration list for PBXNativeTarget "Example" */ = {
444 | isa = XCConfigurationList;
445 | buildConfigurations = (
446 | 630F8CCF282A734C007E467D /* Debug */,
447 | 630F8CD0282A734C007E467D /* Release */,
448 | );
449 | defaultConfigurationIsVisible = 0;
450 | defaultConfigurationName = Release;
451 | };
452 | /* End XCConfigurationList section */
453 | };
454 | rootObject = 630F8CB2282A7349007E467D /* Project object */;
455 | }
456 |
--------------------------------------------------------------------------------