├── DemoContainerView
├── DemoContainerView
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ ├── IMG_33.imageset
│ │ │ ├── IMG_33.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_34.imageset
│ │ │ ├── IMG_34.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_37.imageset
│ │ │ ├── IMG_37.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_38.imageset
│ │ │ ├── IMG_38.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_39.imageset
│ │ │ ├── IMG_39.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_40.imageset
│ │ │ ├── IMG_40.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_43.imageset
│ │ │ ├── IMG_43.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_0.imageset
│ │ │ ├── IMG_0@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_1.imageset
│ │ │ ├── IMG_1@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_2.imageset
│ │ │ ├── IMG_2@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_3.imageset
│ │ │ ├── IMG_3@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_4.imageset
│ │ │ ├── IMG_4@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_5.imageset
│ │ │ ├── IMG_5@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_6.imageset
│ │ │ ├── IMG_6@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_7.imageset
│ │ │ ├── IMG_7@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_8.imageset
│ │ │ ├── IMG_8@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_9.imageset
│ │ │ ├── IMG_9@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_10.imageset
│ │ │ ├── IMG_10@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_11.imageset
│ │ │ ├── IMG_11@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_12.imageset
│ │ │ ├── IMG_12@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_13.imageset
│ │ │ ├── IMG_13@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_14.imageset
│ │ │ ├── IMG_14@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_15.imageset
│ │ │ ├── IMG_15@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_16.imageset
│ │ │ ├── IMG_16@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_17.imageset
│ │ │ ├── IMG_17@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_18.imageset
│ │ │ ├── IMG_18@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_19.imageset
│ │ │ ├── IMG_19@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_20.imageset
│ │ │ ├── IMG_20@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_21.imageset
│ │ │ ├── IMG_21@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_22.imageset
│ │ │ ├── IMG_22@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_23.imageset
│ │ │ ├── IMG_23@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_24.imageset
│ │ │ ├── IMG_24@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_25.imageset
│ │ │ ├── IMG_25@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_26.imageset
│ │ │ ├── IMG_26@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_27.imageset
│ │ │ ├── IMG_27@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_28.imageset
│ │ │ ├── IMG_28@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_29.imageset
│ │ │ ├── IMG_29@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_30.imageset
│ │ │ ├── IMG_30@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_31.imageset
│ │ │ ├── IMG_31@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_32.imageset
│ │ │ ├── IMG_32@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_35.imageset
│ │ │ ├── IMG_35@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_36.imageset
│ │ │ ├── IMG_36@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_41.imageset
│ │ │ ├── IMG_41@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_42.imageset
│ │ │ ├── IMG_42@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_44.imageset
│ │ │ ├── IMG_44@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_45.imageset
│ │ │ ├── IMG_45@3x.jpg
│ │ │ └── Contents.json
│ │ ├── IMG_46.imageset
│ │ │ ├── IMG_46@3x.jpg
│ │ │ └── Contents.json
│ │ ├── header_shadow.imageset
│ │ │ ├── header_shadow.png
│ │ │ └── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Resources
│ │ ├── ProximaNova-Extrabld.otf
│ │ └── ProximaNova-Regular.otf
│ ├── AppDelegate.h
│ ├── Demo
│ │ ├── DemoViewController.h
│ │ ├── DemoScrollViews
│ │ │ ├── DemoCells
│ │ │ │ ├── DemoCollectionCell.m
│ │ │ │ ├── DemoCollectionCell.h
│ │ │ │ ├── DemoTableCell.m
│ │ │ │ └── DemoTableCell.h
│ │ │ ├── DemoProtocolsTableView
│ │ │ │ ├── DemoTableDelegate.h
│ │ │ │ ├── DemoTableDataSource.h
│ │ │ │ ├── DemoTableDelegate.m
│ │ │ │ └── DemoTableDataSource.m
│ │ │ ├── DemoProtocolsCollectionView
│ │ │ │ ├── DemoCollectionDelegate.h
│ │ │ │ ├── DemoCollectionDataSource.h
│ │ │ │ ├── DemoCollectionDelegate.m
│ │ │ │ └── DemoCollectionDataSource.m
│ │ │ ├── DemoScrollViews.h
│ │ │ └── DemoScrollViews.m
│ │ ├── DemoModalViewController.h
│ │ ├── DemoModalViewController.m
│ │ ├── DemoHeaderViews
│ │ │ ├── DemoHeaderViews.h
│ │ │ └── DemoHeaderViews.m
│ │ └── DemoViewController.m
│ ├── main.m
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── AppDelegate.m
│ └── Info.plist
└── DemoContainerView.xcodeproj
│ ├── project.xcworkspace
│ ├── xcuserdata
│ │ └── mrusta.xcuserdatad
│ │ │ └── IDEFindNavigatorScopes.plist
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ ├── xcuserdata
│ └── rustam.xcuserdatad
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
│ └── project.pbxproj
├── .gitignore
├── ContainerView
├── ContainerScrollDelegate.h
├── ContainerTypes.h
├── ContainerViewController.h
├── ContainerView.h
├── ContainerDefines.h
├── ContainerScrollDelegate.m
├── ContainerViewController.m
└── ContainerView.m
├── LICENSE
└── README.md
/DemoContainerView/DemoContainerView/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Resources/ProximaNova-Extrabld.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Resources/ProximaNova-Extrabld.otf
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Resources/ProximaNova-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Resources/ProximaNova-Regular.otf
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_33.imageset/IMG_33.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_33.imageset/IMG_33.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_34.imageset/IMG_34.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_34.imageset/IMG_34.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_37.imageset/IMG_37.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_37.imageset/IMG_37.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_38.imageset/IMG_38.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_38.imageset/IMG_38.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_39.imageset/IMG_39.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_39.imageset/IMG_39.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_40.imageset/IMG_40.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_40.imageset/IMG_40.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_43.imageset/IMG_43.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_43.imageset/IMG_43.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_0.imageset/IMG_0@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_0.imageset/IMG_0@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_1.imageset/IMG_1@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_1.imageset/IMG_1@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_2.imageset/IMG_2@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_2.imageset/IMG_2@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_3.imageset/IMG_3@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_3.imageset/IMG_3@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_4.imageset/IMG_4@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_4.imageset/IMG_4@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_5.imageset/IMG_5@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_5.imageset/IMG_5@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_6.imageset/IMG_6@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_6.imageset/IMG_6@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_7.imageset/IMG_7@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_7.imageset/IMG_7@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_8.imageset/IMG_8@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_8.imageset/IMG_8@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_9.imageset/IMG_9@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_9.imageset/IMG_9@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_10.imageset/IMG_10@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_10.imageset/IMG_10@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_11.imageset/IMG_11@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_11.imageset/IMG_11@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_12.imageset/IMG_12@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_12.imageset/IMG_12@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_13.imageset/IMG_13@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_13.imageset/IMG_13@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_14.imageset/IMG_14@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_14.imageset/IMG_14@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_15.imageset/IMG_15@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_15.imageset/IMG_15@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_16.imageset/IMG_16@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_16.imageset/IMG_16@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_17.imageset/IMG_17@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_17.imageset/IMG_17@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_18.imageset/IMG_18@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_18.imageset/IMG_18@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_19.imageset/IMG_19@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_19.imageset/IMG_19@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_20.imageset/IMG_20@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_20.imageset/IMG_20@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_21.imageset/IMG_21@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_21.imageset/IMG_21@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_22.imageset/IMG_22@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_22.imageset/IMG_22@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_23.imageset/IMG_23@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_23.imageset/IMG_23@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_24.imageset/IMG_24@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_24.imageset/IMG_24@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_25.imageset/IMG_25@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_25.imageset/IMG_25@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_26.imageset/IMG_26@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_26.imageset/IMG_26@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_27.imageset/IMG_27@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_27.imageset/IMG_27@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_28.imageset/IMG_28@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_28.imageset/IMG_28@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_29.imageset/IMG_29@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_29.imageset/IMG_29@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_30.imageset/IMG_30@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_30.imageset/IMG_30@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_31.imageset/IMG_31@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_31.imageset/IMG_31@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_32.imageset/IMG_32@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_32.imageset/IMG_32@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_35.imageset/IMG_35@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_35.imageset/IMG_35@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_36.imageset/IMG_36@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_36.imageset/IMG_36@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_41.imageset/IMG_41@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_41.imageset/IMG_41@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_42.imageset/IMG_42@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_42.imageset/IMG_42@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_44.imageset/IMG_44@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_44.imageset/IMG_44@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_45.imageset/IMG_45@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_45.imageset/IMG_45@3x.jpg
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_46.imageset/IMG_46@3x.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_46.imageset/IMG_46@3x.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | DemoContainerView/DemoContainerView.xcodeproj/xcuserdata/mrusta.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
2 | DemoContainerView/DemoContainerView.xcodeproj/xcuserdata/mrusta.xcuserdatad/xcschemes/xcschememanagement.plist
3 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/header_shadow.imageset/header_shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mrustaa/ContainerView/HEAD/DemoContainerView/DemoContainerView/Assets.xcassets/header_shadow.imageset/header_shadow.png
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView.xcodeproj/project.xcworkspace/xcuserdata/mrusta.xcuserdatad/IDEFindNavigatorScopes.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/AppDelegate.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 03.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 |
7 | @interface AppDelegate : UIResponder
8 |
9 | @property (strong, nonatomic) UIWindow *window;
10 |
11 | @end
12 |
13 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoViewController.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 03.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 |
7 | #import
8 | #import "ContainerViewController.h"
9 |
10 | @interface DemoViewController : ContainerViewController
11 |
12 | @end
13 |
14 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoCells/DemoCollectionCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCollectionCell.m
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 21/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import "DemoCollectionCell.h"
10 |
11 | @implementation DemoCollectionCell
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/main.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 03.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import "AppDelegate.h"
7 |
8 | int main(int argc, char * argv[]) {
9 | @autoreleasepool {
10 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoModalViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoModalViewController.h
3 | // DemoContainerView
4 | //
5 | // Created by Rustam Motygullin on 26/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "ContainerViewController.h"
11 |
12 | @interface DemoModalViewController : ContainerViewController
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsTableView/DemoTableDelegate.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 29.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "ContainerScrollDelegate.h"
6 |
7 | @interface DemoTableDelegate : ContainerScrollDelegate
8 | @property (strong, nonatomic) void(^blockSelectIndex)(NSInteger);
9 | @end
10 |
--------------------------------------------------------------------------------
/ContainerView/ContainerScrollDelegate.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import "ContainerTypes.h"
7 | #import "ContainerView.h"
8 |
9 | @interface ContainerScrollDelegate : NSObject
10 |
11 | @property (strong, nonatomic) ContainerView *containerView;
12 | @property (strong, nonatomic) void(^blockTransform)(CGFloat);
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_0.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_0@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_1.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_1@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_10.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_10@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_11.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_11@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_12.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_12@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_13.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_13@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_14.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_14@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_15.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_15@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_16.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_16@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_17.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_17@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_18.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_18@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_19.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_19@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_2.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_2@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_20.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_20@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_21.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_21@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_22.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_22@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_23.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_23@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_24.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_24@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_25.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_25@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_26.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_26@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_27.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_27@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_28.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_28@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_29.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_29@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_3.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_3@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_30.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_30@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_31.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_31@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_32.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_32@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_33.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_33.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_34.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_34.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_35.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_35@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_36.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_36@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_37.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_37.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_38.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_38.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_39.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_39.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_4.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_4@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_40.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_40.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_41.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_41@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_42.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_42@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_43.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_43.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_44.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_44@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_45.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_45@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_46.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_46@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_5.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_5@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_6.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_6@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_7.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_7@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_8.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_8@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/IMG_9.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "IMG_9@3x.jpg",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsCollectionView/DemoCollectionDelegate.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 29.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "ContainerScrollDelegate.h"
6 |
7 | @interface DemoCollectionDelegate : ContainerScrollDelegate
8 | @property (strong, nonatomic) void(^blockSelectIndex)(NSInteger);
9 | @end
10 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsTableView/DemoTableDataSource.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import "ContainerTypes.h"
7 |
8 | @interface DemoTableDataSource : NSObject
9 |
10 | @property (strong, nonatomic) NSMutableArray *photos;
11 | @property ContainerStyle containerStyle;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/header_shadow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "header_shadow.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 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsCollectionView/DemoCollectionDataSource.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import "ContainerTypes.h"
7 |
8 |
9 |
10 | @interface DemoCollectionDataSource : NSObject
11 |
12 | @property (strong, nonatomic) NSMutableArray *photos;
13 | @property ContainerStyle containerStyle;
14 |
15 | @end
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoCells/DemoCollectionCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoCollectionCell.h
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 21/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoCollectionCell : UICollectionViewCell
12 |
13 | @property (strong, nonatomic) UIImageView *imageView;
14 | @property (strong, nonatomic) UIView *view;
15 | @property (strong, nonatomic) UILabel *label;
16 |
17 | @property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView.xcodeproj/xcuserdata/rustam.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | DemoContainerView.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | containerView.xcscheme
13 |
14 | orderHint
15 | 0
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoScrollViews.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoScrollViews.h
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 26/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "ContainerTypes.h"
12 |
13 | @interface DemoScrollViews : NSObject
14 |
15 | + (UITableView *)createTableViewWithProtocols:(id)protocols;
16 | + (UICollectionView *)createCollectionViewWithProtocols:(id)protocols;
17 | + (UITextView *)createTextViewWithProtocols:(id)protocols;
18 |
19 | @end
20 |
21 |
22 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoCells/DemoTableCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTableCell.m
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 21/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import "DemoTableCell.h"
10 |
11 | @implementation DemoTableCell
12 |
13 | - (void)awakeFromNib {
14 | [super awakeFromNib];
15 | // Initialization code
16 | }
17 |
18 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated {
19 | [super setSelected:selected animated:animated];
20 |
21 | // Configure the view for the selected state
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoCells/DemoTableCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoTableCell.h
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 21/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface DemoTableCell : UITableViewCell
12 |
13 | @property (strong, nonatomic) UILabel *labelTitle;
14 | @property (strong, nonatomic) UILabel *labelSubTitle;
15 | @property (strong, nonatomic) UIView *separatorLine;
16 | @property (strong, nonatomic) UIImageView *imageAvatar;
17 |
18 | @property (strong, nonatomic) UITapGestureRecognizer *tapGesture;
19 |
20 | @end
21 |
22 |
--------------------------------------------------------------------------------
/ContainerView/ContainerTypes.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 |
7 | typedef NS_ENUM(NSUInteger, ContainerStyle) {
8 | ContainerStyleDefault = 0,
9 | ContainerStyleLight,
10 | ContainerStyleExtraLight,
11 | ContainerStyleDark,
12 | };
13 |
14 | typedef NS_ENUM(NSUInteger, ContainerMoveType) {
15 | ContainerMoveTypeTop = 0,
16 | ContainerMoveTypeMiddle,
17 | ContainerMoveTypeBottom,
18 | ContainerMoveTypeHide,
19 | };
20 |
21 | typedef NS_ENUM(NSUInteger, SelectType) {
22 | SelectTypeSettings = 0,
23 | SelectTypeMap,
24 | SelectTypePhotos,
25 | };
26 |
27 |
28 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsTableView/DemoTableDelegate.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 29.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "DemoTableDelegate.h"
6 |
7 | @implementation DemoTableDelegate
8 |
9 | #pragma mark - TableView Delegate
10 |
11 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
12 | {
13 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
14 | if(self.blockSelectIndex) self.blockSelectIndex(indexPath.row);
15 | }
16 |
17 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
18 | {
19 | return 88;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoModalViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoModalViewController.m
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 26/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import "DemoModalViewController.h"
10 | #import "DemoScrollViews.h"
11 |
12 | @interface DemoModalViewController ()
13 |
14 | @end
15 |
16 | @implementation DemoModalViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | UITextView *textView = [DemoScrollViews createTextViewWithProtocols:self];
22 | [self.containerView addSubview:textView];
23 |
24 | }
25 | - (IBAction)closeController:(UIButton *)sender {
26 | [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Rustam Motygullin
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.
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoHeaderViews/DemoHeaderViews.h:
--------------------------------------------------------------------------------
1 | //
2 | // DemoHeaders.h
3 | // DemoContainerView
4 | //
5 | // Created by Rustam Motygullin on 17/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import "ContainerTypes.h"
12 |
13 | @interface HeaderLabel : UIView
14 | @property (nonatomic, strong) UILabel *label;
15 | @property (nonatomic, strong) UIView *separatorLine;
16 | @property (nonatomic, strong) UIView *grip;
17 | @end
18 |
19 |
20 | @interface HeaderSearch : UIView
21 | @property (nonatomic, strong) UISearchBar *searchBar;
22 | @property (nonatomic, strong) UIView *separatorLine;
23 | @end
24 |
25 |
26 | @interface HeaderGrib : UIView
27 | @property (nonatomic, strong) UIView *separatorLine;
28 | @property (nonatomic, strong) UIImageView *separatorShadow;
29 | @property (nonatomic, strong) UIView *grip;
30 | @end
31 |
32 |
33 | @interface DemoHeaderViews : NSObject
34 |
35 | + (HeaderLabel *)createHeaderLabel;
36 | + (HeaderSearch *)createHeaderSearch;
37 | + (HeaderGrib *)createHeaderGrip;
38 |
39 | + (void)changeColorsHeaderView:(UIView *)headerView forStyle:(ContainerStyle)style;
40 |
41 | @end
42 |
43 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsCollectionView/DemoCollectionDelegate.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 29.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "DemoCollectionDelegate.h"
6 |
7 | #import "ContainerDefines.h"
8 |
9 | @implementation DemoCollectionDelegate
10 |
11 | #pragma mark - CollectionView Delegate
12 |
13 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
14 | if(self.blockSelectIndex) self.blockSelectIndex(indexPath.row);
15 | }
16 |
17 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
18 |
19 | CGFloat indent = (((SCREEN_WIDTH - ((SCREEN_WIDTH * .437333) * 2)) / 3) / 2);
20 | CGFloat imageSize = (SCREEN_WIDTH * .437333);
21 |
22 | CGSize size = (CGSize) {
23 | ((imageSize + (indent * 2)) -1),
24 | (imageSize + indent + 36)
25 | };
26 |
27 | return size;
28 | }
29 |
30 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
31 |
32 | CGFloat indent = (((SCREEN_WIDTH - ((SCREEN_WIDTH * .437333) * 2)) / 3) / 2);
33 | return UIEdgeInsetsMake(indent,indent,0,indent);
34 | }
35 |
36 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
37 | return .0;
38 | }
39 |
40 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
41 | return .0;
42 | }
43 |
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/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 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/AppDelegate.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 03.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "AppDelegate.h"
6 |
7 | @interface AppDelegate ()
8 |
9 | @end
10 |
11 | @implementation AppDelegate
12 |
13 |
14 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
15 | // Override point for customization after application launch.
16 |
17 | return YES;
18 | }
19 |
20 |
21 | - (void)applicationWillResignActive:(UIApplication *)application {
22 | // 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.
23 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
24 | }
25 |
26 |
27 | - (void)applicationDidEnterBackground:(UIApplication *)application {
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 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 |
38 | - (void)applicationDidBecomeActive:(UIApplication *)application {
39 | // 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.
40 | }
41 |
42 |
43 | - (void)applicationWillTerminate:(UIApplication *)application {
44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
45 | }
46 |
47 |
48 | @end
49 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsCollectionView/DemoCollectionDataSource.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "DemoCollectionDataSource.h"
6 | #import "DemoCollectionCell.h"
7 |
8 | #import "ContainerDefines.h"
9 |
10 | @implementation DemoCollectionDataSource
11 |
12 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
13 | return self.photos.count ;
14 | }
15 |
16 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
17 |
18 | DemoCollectionCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier: @"collectionCell" forIndexPath: indexPath];
19 | cell.backgroundColor = CLR_COLOR;
20 | cell.clipsToBounds = YES;
21 |
22 | CGFloat indent = (((SCREEN_WIDTH - ((SCREEN_WIDTH * .437333) * 2)) / 3) / 2);
23 | CGFloat imageSize = (SCREEN_WIDTH * .437333);
24 |
25 | CGSize cellSize = (CGSize)
26 | {
27 | ((imageSize + (indent * 2)) -1) ,
28 | (imageSize + indent + 36)
29 | };
30 |
31 | if(!cell.imageView )
32 | {
33 | cell.imageView = [UIImageView new];
34 | cell.imageView.clipsToBounds = 1;
35 | cell.imageView.backgroundColor = CLR_COLOR;
36 | cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
37 | cell.imageView.layer.cornerRadius = 6;
38 | [cell addSubview: cell.imageView];
39 | }
40 |
41 | if(!cell.label)
42 | {
43 | cell.label = [[UILabel alloc]initWithFrame:CGRectMake(8, cellSize.height -26, cellSize.width -16, 18)];
44 | cell.label.font = [UIFont fontWithName:@"ProximaNova-Extrabld" size:14];
45 | cell.label.textColor = BLACK_COLOR;
46 | [cell addSubview:cell.label];
47 | }
48 |
49 | cell.imageView.frame = CGRectMake( indent, indent, imageSize, imageSize);
50 | cell.imageView.image = self.photos[indexPath.row][@"small"];
51 |
52 | cell.label.text = (indexPath.row) ? (indexPath.row == 1) ? @"mapView" : SFMT(@"photo %d",(int)indexPath.row) : @"settings" ;
53 | cell.label.textColor = (self.containerStyle == ContainerStyleDark) ? WHITE_COLOR : BLACK_COLOR;
54 |
55 | return cell;
56 | }
57 |
58 | @end
59 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | NSAppTransportSecurity
24 |
25 | NSAllowsArbitraryLoads
26 |
27 | NSExceptionDomains
28 |
29 | example.com
30 |
31 | NSExceptionAllowsInsecureHTTPLoads
32 |
33 | NSIncludesSubdomains
34 |
35 |
36 |
37 |
38 | NSLocationAlwaysAndWhenInUseUsageDescription
39 | Privacy - Location Always and When In Use Usage Description
40 | NSLocationAlwaysUsageDescription
41 | Privacy - Location Always Usage Description
42 | NSLocationWhenInUseUsageDescription
43 | Privacy - Location When In Use Usage Description
44 | UIAppFonts
45 |
46 | ProximaNova-Regular.otf
47 | ProximaNova-Extrabld.otf
48 |
49 | UILaunchStoryboardName
50 | LaunchScreen
51 | UIMainStoryboardFile
52 | Main
53 | UIRequiredDeviceCapabilities
54 |
55 | armv7
56 |
57 | UISupportedInterfaceOrientations
58 |
59 | UIInterfaceOrientationPortrait
60 | UIInterfaceOrientationLandscapeRight
61 | UIInterfaceOrientationLandscapeLeft
62 |
63 | UISupportedInterfaceOrientations~ipad
64 |
65 | UIInterfaceOrientationPortrait
66 | UIInterfaceOrientationPortraitUpsideDown
67 | UIInterfaceOrientationLandscapeLeft
68 | UIInterfaceOrientationLandscapeRight
69 |
70 | UIViewControllerBasedStatusBarAppearance
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoProtocolsTableView/DemoTableDataSource.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "DemoTableDataSource.h"
6 | #import "DemoTableCell.h"
7 |
8 | #import "ContainerDefines.h"
9 |
10 | @implementation DemoTableDataSource
11 |
12 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex {
13 | return self.photos.count ;
14 | }
15 |
16 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
17 |
18 | DemoTableCell * cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell"];
19 | if(!cell) {
20 | cell = [[DemoTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @"TableCell" ];
21 | cell.backgroundColor = CLR_COLOR;
22 | }
23 |
24 | if(!cell.separatorLine) {
25 | cell.separatorLine = [[UIView alloc]initWithFrame:CGRectMake( 16 , 87.5, SCREEN_WIDTH -32 , 0.5)];
26 | cell.separatorLine.backgroundColor = RGB(222, 222, 222);
27 | [cell addSubview: cell.separatorLine];
28 | }
29 |
30 | if(!cell.labelTitle) {
31 | cell.labelTitle = [[UILabel alloc]initWithFrame:CGRectMake( 18 , 20, SCREEN_WIDTH -67 , 30)];
32 | cell.labelTitle.font = [UIFont fontWithName:@"ProximaNova-Extrabld" size:22];
33 | cell.labelTitle.textColor = BLACK_COLOR;
34 | [cell addSubview:cell.labelTitle];
35 | }
36 |
37 | if(!cell.labelSubTitle) {
38 | cell.labelSubTitle = [[UILabel alloc]initWithFrame:CGRectMake( 18 , 50, SCREEN_WIDTH -67, 16)];
39 | cell.labelSubTitle.font = [UIFont fontWithName:@"ProximaNova-Regular" size:15];
40 | cell.labelSubTitle.textColor = RGB(124,132,148);
41 | [cell addSubview:cell.labelSubTitle];
42 | }
43 |
44 | cell.labelTitle .text = (indexPath.row) ? (indexPath.row == 1) ? @"mapView" : SFMT(@"photo %d", (int)indexPath.row) : @"settings" ;
45 | cell.labelSubTitle.text = @"Subtitle";
46 | cell.labelTitle.textColor = (self.containerStyle == ContainerStyleDark) ? WHITE_COLOR : BLACK_COLOR;
47 |
48 | switch (self.containerStyle) {
49 | case ContainerStyleDefault: {
50 | cell.separatorLine.backgroundColor = GRAYLEVEL(222);
51 | cell.separatorLine.alpha = 1;
52 | } break;
53 | case ContainerStyleLight:{
54 | cell.separatorLine.backgroundColor = GRAYLEVEL(180);
55 | cell.separatorLine.alpha = 0.5;
56 | } break;
57 | case ContainerStyleDark:{
58 | cell.separatorLine.backgroundColor = GRAYLEVEL(222);
59 | cell.separatorLine.alpha = 0.2;
60 | } break;
61 | case ContainerStyleExtraLight:{
62 | cell.separatorLine.backgroundColor = GRAYLEVEL(180);
63 | cell.separatorLine.alpha = 0.5;
64 | } break;
65 | default:
66 | break;
67 | }
68 |
69 | return cell;
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/ContainerView/ContainerViewController.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Рустам Мотыгуллин on 17.08.2018.
3 | // Copyright © 2018 GetTransfer. All rights reserved.
4 |
5 | #import
6 | #import "ContainerView.h"
7 |
8 |
9 |
10 | @interface ContainerViewController : UIViewController
11 |
12 |
13 | @property (strong, nonatomic) UIView *bottomView;
14 | @property (strong, nonatomic) UIButton *shadowButton;
15 | @property (strong, nonatomic) ContainerView *containerView;
16 |
17 | @property (nonatomic, weak) id delegate;
18 |
19 |
20 | /**
21 | @brief This view sets a custom header for the container.
22 | */
23 | @property (strong, nonatomic) UIView *headerView;
24 |
25 |
26 |
27 | /**
28 | @brief This parameter indicates which type of move was last.
29 | */
30 | @property (nonatomic, readonly) ContainerMoveType containerPosition;
31 |
32 | /**
33 | @brief This parameter to add a blur to the background of the container.
34 |
35 | There are 3 types of blur. Blur with hues of
36 | 1) black,
37 | 2) white,
38 | 3) white with low blur concentrations.
39 | 4) The last attribute turns off the blur, for a normal change of the background color.
40 | */
41 | @property (nonatomic) ContainerStyle containerStyle;
42 |
43 | /**
44 | @brief This parameter for changing the rounding radius
45 | */
46 | @property (nonatomic) CGFloat containerCornerRadius;
47 |
48 | /**
49 | @brief When moving the container, by default there are 2 positions (this is moving up and down). This parameter adds 3 position (move to the middle)
50 | */
51 | @property (nonatomic) BOOL containerAllowMiddlePosition;
52 |
53 |
54 |
55 | /**
56 | @brief This parameter indicates whether to add a button when the container is at the bottom to animate the container upwards.
57 | */
58 | @property (nonatomic) BOOL containerBottomButtonToMoveTop;
59 |
60 |
61 | /**
62 | @brief This parameter sets the shadow under container
63 | */
64 | @property (nonatomic) BOOL containerShadowView;
65 |
66 | /**
67 | @brief This parameter sets the shadow in container
68 | */
69 | @property (nonatomic) BOOL containerShadow;
70 |
71 |
72 | /**
73 | @brief This parameter allows you to zoom in on the screen under ContainerView.
74 | */
75 | @property (nonatomic) BOOL containerZoom;
76 |
77 | /**
78 | @brief This parameter sets the new position value for the up move type.
79 | */
80 | @property (nonatomic) CGFloat containerTop;
81 |
82 | /**
83 | @brief This parameter sets the new position value for the type of movement to the middle position.
84 | */
85 | @property (nonatomic) CGFloat containerMiddle;
86 |
87 | /**
88 | @brief This parameter sets the new position value for the type of movement to the middle position.
89 | */
90 | @property (nonatomic) CGFloat containerBottom;
91 |
92 |
93 | /**
94 | @brief This method for animated container movement, at fixed positions
95 |
96 | @param moveType There are 4 types of movement. Moving 1) up, 2) middle, 3) down, 4) hiding in the most down beyond the limits of visibility
97 | */
98 | - (void)containerMove:(ContainerMoveType)moveType;
99 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated;
100 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion;
101 |
102 | /**
103 | @brief This method for animated container movement, by user position.
104 |
105 | @param position Custom position
106 | */
107 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType;
108 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated;
109 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion;
110 |
111 | @end
112 |
--------------------------------------------------------------------------------
/ContainerView/ContainerView.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 08.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import "ContainerTypes.h"
7 | #import "ContainerDefines.h"
8 |
9 |
10 | @protocol ContainerViewDelegate
11 | @optional
12 | - (void)changeContainerMove:(ContainerMoveType)containerMove containerY:(CGFloat)containerY animated:(BOOL)animated;
13 | @end
14 |
15 |
16 |
17 | @interface ContainerView : UIView
18 |
19 | @property (nonatomic, weak) id delegate;
20 |
21 |
22 |
23 | @property (nonatomic) BOOL portrait;
24 |
25 | @property (nonatomic) BOOL firstAddedTop;
26 | @property (nonatomic) BOOL firstAddedMiddle;
27 | @property (nonatomic) BOOL firstAddedBottom;
28 |
29 | - (CGFloat)getContainerBottom;
30 | - (CGFloat)getContainerMiddle;
31 |
32 | /**
33 | @brief This view sets a custom header for the container.
34 | */
35 | @property (strong, nonatomic) UIView *headerView;
36 |
37 | /**
38 | @brief This option indicates whether to add a button when the container is at the bottom to animate the container upwards.
39 | */
40 | @property (nonatomic) BOOL containerBottomButtonToMoveTop;
41 |
42 | /**
43 | @brief When moving the container, by default there are 2 positions (this is moving up and down). This parameter adds 3 position (move to the middle)
44 | */
45 | @property (nonatomic) BOOL containerAllowMiddlePosition;
46 |
47 | /**
48 | @brief This parameter sets the shadow for the container.
49 | */
50 | @property (nonatomic) BOOL containerShadow;
51 |
52 |
53 | /**
54 | @brief This parameter sets the new position value for the up move type.
55 | */
56 | @property (nonatomic) CGFloat containerTop;
57 |
58 | /**
59 | @brief This parameter sets the new position value for the type of movement to the middle position.
60 | */
61 | @property (nonatomic) CGFloat containerMiddle;
62 |
63 | /**
64 | @brief This parameter sets the new position value for the type of movement to the middle position.
65 | */
66 | @property (nonatomic) CGFloat containerBottom;
67 |
68 | /**
69 | @brief This method for changing the rounding radius
70 | */
71 | @property (nonatomic) CGFloat containerCornerRadius;
72 |
73 |
74 |
75 | /**
76 | @brief This parameter indicates which type of move was last.
77 | */
78 | @property (nonatomic) ContainerMoveType containerPosition;
79 |
80 | /**
81 | @brief This parameter indicates which container style
82 | */
83 | @property (nonatomic) ContainerStyle containerStyle;
84 |
85 |
86 | /**
87 | @brief This method to add a blur to the background of the container.
88 |
89 | @param styleType There are 3 types of blur. Blur with hues of
90 | 1) black,
91 | 2) white,
92 | 3) white with low blur concentrations.
93 | 4) The last attribute turns off the blur, for a normal change of the background color.
94 | */
95 | - (void)changeBlurStyle:(ContainerStyle)styleType;
96 |
97 | - (void)transitionToSizeTop:(CGFloat)top middle:(CGFloat)middle bottom:(CGFloat)bottom size:(CGSize)size;
98 |
99 | - (void)containerMoveForVelocityInView:(CGFloat)velocityInViewY;
100 |
101 | /**
102 | @brief This method for animated container movement, at fixed positions
103 |
104 | @param moveType There are 4 types of movement. Moving 1) up, 2) middle, 3) down, 4) hiding in the most down beyond the limits of visibility
105 | */
106 | - (void)containerMove:(ContainerMoveType)moveType;
107 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated;
108 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion;
109 |
110 | /**
111 | @brief This method for animated container movement, by user position.
112 |
113 | @param position Custom position
114 | */
115 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType;
116 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated;
117 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion;
118 |
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/ContainerView/ContainerDefines.h:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 12.08.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import
6 | #import
7 |
8 |
9 |
10 | /// APP
11 | #define APP ([UIApplication sharedApplication])
12 | #define WINDOW ((UIWindow *)APP.delegate.window)
13 |
14 | /// ROOT
15 | #define ROOT_VC (APP.keyWindow.rootViewController)
16 |
17 | /// NAV
18 | #define NAV_ADDED ([ROOT_VC isKindOfClass:[UINavigationController class]])
19 |
20 | #define NETWORK_INDICATOR_ON(a) (APP.networkActivityIndicatorVisible = a)
21 |
22 | /// STATUS BAR
23 | #define STATUSBAR_STYLE(a) ([APP setStatusBarStyle:(UIStatusBarStyle)a animated:YES])
24 |
25 |
26 | /// SIZE
27 | #define FRAME ((CGRect)WINDOW.frame)
28 |
29 | #define SCREEN_STATUS_HEIGHT [UIApplication sharedApplication].statusBarFrame.size.height
30 |
31 | #define SCREEN_WIDTH ([[UIScreen mainScreen] bounds].size.width)
32 | #define SCREEN_HEIGHT ([[UIScreen mainScreen] bounds].size.height)
33 | #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT))
34 | #define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT))
35 |
36 | #define SCREEN_PORTRAIT (SCREEN_WIDTH < SCREEN_HEIGHT)
37 |
38 | /// DEVICE
39 | #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
40 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
41 | #define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0)
42 |
43 | #define IS_IPHONE_4 (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0)
44 | #define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0)
45 | #define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0)
46 | #define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0)
47 | #define IS_IPHONE_X (IS_IPHONE && SCREEN_MAX_LENGTH == 812.0)
48 | #define IS_BIG_IPHONE (IS_IPHONE && SCREEN_MAX_LENGTH > 568.0)
49 |
50 | #define IPHONE_X_PADDING_TOP (IS_IPHONE_X ? 24 :0)
51 | #define IPHONE_X_PADDING_BOTTOM (IS_IPHONE_X ? 34 :0)
52 |
53 | /// COLOR
54 | #define RGBA(r,g,b,a) ([UIColor colorWithRed:(CGFloat)r / 255.0 green:(CGFloat)g / 255.0 blue:(CGFloat)b / 255.0 alpha:(CGFloat)a])
55 | #define RGB(r,g,b) RGBA(r,g,b, 1.0)
56 | #define HTMLRGBA(rgb,a) RGBA( ((rgb >> 16) & 0xff),((rgb >> 8) & 0xff),((rgb) & 0xff),a)
57 | #define HTMLRGB(rgb) HTMLRGBA(rgb, 1.0)
58 |
59 | #define GRAYLEVEL(l) RGB(l,l,l)
60 |
61 | #define BLACK_COLOR [UIColor blackColor]
62 | #define WHITE_COLOR [UIColor whiteColor]
63 | #define RED_COLOR [UIColor redColor]
64 | #define CLR_COLOR [UIColor clearColor]
65 |
66 | /// FONTS
67 | #define FONT_S(s) [UIFont systemFontOfSize:s]
68 | #define FONT_BS(s) [UIFont boldSystemFontOfSize:s]
69 |
70 | /// ANIMATION
71 | #define ANIMATION(d,a) [UIView animateWithDuration:d animations:a completion:nil]
72 | #define ANIMATIONCOMP(d,a,c) [UIView animateWithDuration:d animations:a completion:c]
73 | #define ANIMATION_SPRING(d,a) [UIView animateWithDuration:d delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:6.0 options:UIViewAnimationOptionAllowUserInteraction animations:a completion:nil]
74 | #define ANIMATION_SPRINGCOMP(d,a,c) [UIView animateWithDuration:d delay:0 usingSpringWithDamping:0.8 initialSpringVelocity:6.0 options:UIViewAnimationOptionAllowUserInteraction animations:a completion:c]
75 |
76 |
77 | /// STRING
78 | #define SFMT(str, ...) [NSString stringWithFormat:str, ##__VA_ARGS__]
79 | #define PRINT(str, ...) printf("%s\n",[NSString stringWithFormat:str, ##__VA_ARGS__].UTF8String)
80 |
81 | /// IMAGE
82 | #define IMG(name) [UIImage imageNamed:name]
83 |
84 |
85 | /// GCD
86 | #define GCD_SYNC_MAIN_BEGIN dispatch_sync(dispatch_get_main_queue(), ^
87 | #define GCD_ASYNC_MAIN_BEGIN dispatch_async(dispatch_get_main_queue(), ^
88 | #define GCD_MAIN_END });
89 |
90 | #define GCD_SYNC_GLOBAL_BEGIN(PRIORITY) dispatch_sync(dispatch_get_global_queue(PRIORITY, 0), ^
91 | #define GCD_ASYNC_GLOBAL_BEGIN(PRIORITY) dispatch_async(dispatch_get_global_queue(PRIORITY, 0), ^
92 | #define GCD_GLOBAL_END });
93 |
94 |
95 | /// CUSTOM
96 | #define COORDINATE_SAN_FRANCISCO (MKCoordinateRegionMakeWithDistance( (CLLocationCoordinate2D) { 37.773972, -122.431297 }, 25000, 25000))
97 |
98 | #define CUSTOM_TOP 60.0
99 | #define CUSTOM_BOTTOM (92)
100 | #define CUSTOM_MIDDLE (0.5)
101 |
102 | #define CUSTOM_HEADER_HEIGHT 64.0
103 |
104 | #define FRAME_SCROLLVIEW CGRectMake ( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT -CUSTOM_TOP -IPHONE_X_PADDING_TOP )
105 |
106 |
107 |
--------------------------------------------------------------------------------
/ContainerView/ContainerScrollDelegate.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 11.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "ContainerScrollDelegate.h"
6 | #import "ContainerDefines.h"
7 |
8 | @implementation ContainerScrollDelegate {
9 | BOOL bordersRunContainer;
10 | BOOL onceEnded;
11 | BOOL bottomDeceleratingDisable;
12 | BOOL onceScrollingBeginDragging;
13 | BOOL scrollBegin;
14 | CGFloat startScrollPosition;
15 | CGAffineTransform selfTransform;
16 | }
17 |
18 |
19 |
20 | #pragma mark - Scroll Delegate
21 |
22 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView
23 | {
24 | CGFloat velocityInViewY = [scrollView.panGestureRecognizer velocityInView: WINDOW].y;
25 | CGFloat translationInViewY = [scrollView.panGestureRecognizer translationInView:WINDOW].y;
26 |
27 | if((scrollView.panGestureRecognizer.state) && (scrollView.contentOffset.y <= 0)) {
28 | scrollView.showsVerticalScrollIndicator = NO;
29 | scrollView.contentOffset = CGPointMake( scrollView.contentOffset.x, 0 );
30 | } else {
31 | scrollView.showsVerticalScrollIndicator = YES;
32 | }
33 |
34 | bordersRunContainer = ( (scrollView.contentOffset.y == 0) && (0 < velocityInViewY));
35 |
36 | selfTransform = self.containerView.transform;
37 |
38 |
39 | // if(NAV_ADDED) {
40 | // UINavigationController *nvc = (UINavigationController *)ROOT_VC;
41 | // if(!nvc.navigationBarHidden) {
42 | // top = (top + nvc.navigationBar.height);
43 | // }
44 | // }
45 |
46 |
47 | CGFloat top = self.containerView.containerTop;
48 |
49 | if(scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded)
50 | onceScrollingBeginDragging = NO;
51 |
52 | if(bordersRunContainer) {
53 |
54 | onceEnded = NO;
55 | onceScrollingBeginDragging = NO;
56 |
57 | selfTransform.ty = ((top - startScrollPosition) + translationInViewY );
58 | if(selfTransform.ty < top) selfTransform.ty = top;
59 |
60 | if(scrollBegin)
61 | {
62 | ANIMATION_SPRING(.325, ^(void) {
63 | self.containerView.transform = self->selfTransform;
64 | });
65 |
66 | scrollBegin = NO;
67 |
68 | } else {
69 | self.containerView.transform = selfTransform;
70 | }
71 | }
72 | else
73 | {
74 | if((top == selfTransform.ty) && !onceScrollingBeginDragging) {
75 | onceScrollingBeginDragging = YES;
76 |
77 | CGFloat headerHeight = (self.containerView.headerView) ?self.containerView.headerView.frame.size.height :0;
78 | CGFloat top = (self.containerView.containerTop == 0) ? CUSTOM_TOP : self.containerView.containerTop;
79 | CGFloat iphnX = IPHONE_X_PADDING_TOP;
80 |
81 | CGFloat height = (SCREEN_HEIGHT - (top + headerHeight + iphnX ));
82 |
83 | if(scrollView.frame.size.height != height) {
84 |
85 | ANIMATION_SPRING( .45, ^(void) {
86 | scrollView.frame = CGRectMake(
87 | scrollView.frame.origin.x, headerHeight ,
88 | scrollView.frame.size.width, height
89 | );
90 | });
91 | }
92 | }
93 |
94 | if(top < selfTransform.ty)
95 | {
96 | if (velocityInViewY < 0. )
97 | {
98 | if(self.containerView.containerPosition == ContainerMoveTypeTop) {
99 | scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, 0 );
100 | }
101 |
102 | selfTransform = self.containerView.transform;
103 | selfTransform.ty = ((top - startScrollPosition) + translationInViewY );
104 |
105 | if(selfTransform.ty < top) selfTransform.ty = top;
106 |
107 | self.containerView.transform = selfTransform;
108 | }
109 | }
110 | }
111 |
112 | if(self.blockTransform) self.blockTransform(selfTransform.ty);
113 | }
114 |
115 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
116 | {
117 | startScrollPosition = scrollView.contentOffset.y;
118 |
119 | if(bottomDeceleratingDisable) return;
120 |
121 | scrollBegin = YES;
122 | if(startScrollPosition < 0) startScrollPosition = 0;
123 | }
124 |
125 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
126 | {
127 | if(bottomDeceleratingDisable) return;
128 | CGFloat velocityInViewY = [scrollView.panGestureRecognizer velocityInView:WINDOW].y;
129 |
130 | if(!self.containerView) return;
131 |
132 | if(!onceEnded)
133 | {
134 | onceEnded = YES;
135 | [self.containerView containerMoveForVelocityInView:velocityInViewY];
136 | }
137 | }
138 |
139 | @end
140 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoScrollViews/DemoScrollViews.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoScrollViews.m
3 | // DemoContainerView
4 | //
5 | // Created by Рустам Мотыгуллин on 26/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import "DemoScrollViews.h"
10 | #import "ContainerDefines.h"
11 | #import "DemoCollectionCell.h"
12 |
13 | @implementation DemoScrollViews
14 |
15 | + (UITableView *)createTableViewWithProtocols:(id)protocols {
16 | UITableView *
17 | table = [[UITableView alloc] initWithFrame:FRAME_SCROLLVIEW style:UITableViewStylePlain];
18 | table.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
19 | table.showsVerticalScrollIndicator = NO;
20 | table.backgroundColor = CLR_COLOR;
21 | table.delegate = protocols;
22 | table.dataSource = protocols;
23 | return table;
24 | }
25 |
26 |
27 | + (UICollectionView *)createCollectionViewWithProtocols:(id)protocols {
28 | UICollectionView *
29 | collection = [[UICollectionView alloc]initWithFrame:FRAME_SCROLLVIEW collectionViewLayout:[[UICollectionViewFlowLayout alloc]init]];
30 | [collection registerClass:[DemoCollectionCell class] forCellWithReuseIdentifier:@"collectionCell"];
31 | collection.backgroundColor = CLR_COLOR;
32 | collection.delegate = protocols;
33 | collection.dataSource = protocols;
34 | return collection;
35 | }
36 |
37 | + (UITextView *)createTextViewWithProtocols:(id)protocols {
38 |
39 | UITextView * textView = [[UITextView alloc]initWithFrame:FRAME_SCROLLVIEW];
40 | textView.delegate = protocols;
41 | textView.returnKeyType = UIReturnKeyDone;
42 | textView.backgroundColor = CLR_COLOR;
43 | //textView.textColor = (self.containerStyle == ContainerStyleDark) ?WHITE_COLOR :BLACK_COLOR;
44 | textView.font = FONT_S(15);
45 | textView.text = @"This example demonstrates a block quote. Because some introductory phrases will lead\
46 | naturally into the block quote,\
47 | you might choose to begin the block quote with a lowercase letter. In this and the later\
48 | examples we use “Lorem ipsum” text to ensure that each block quotation contains 40 words or\
49 | more. Lorem ipsum dolor sit amet, consectetur adipiscing elit. (Organa, 2013, p. 234)\
50 | Example 2\
51 | This example also demonstrates a block quote. Some introductory sentences end abruptly in a\
52 | colon or a period:\
53 | In those cases, you are more likely to capitalize the beginning word of the block quotation.\
54 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nisi mi, pharetra sit amet mi vitae,\
55 | commodo accumsan dui. Donec non scelerisque quam. Pellentesque ut est sed neque.\
56 | (Calrissian, 2013, para. 3)\
57 | Example 3\
58 | This is another example of a block quotation. Sometimes, the author(s) being cited will be\
59 | included in the introduction. In that case, according to Skywalker and Solo,\
60 | because the author names are in the introduction of this quote, the parentheses that follow it\
61 | will include only the year and the page number. Lorem ipsum dolor sit amet, consectetur\
62 | adipiscing elit. Sed nisi mi, pharetra sit amet mi vitae, commodo accumsan dui. Donec non\
63 | scelerisque quam. Pellentesque ut est sed neque. (2013, p. 103)\
64 | Copyright © 2013 by the American Psychological Association. This content may be reproduced for classroom or teaching purposes\
65 | provided that credit is given to the American Psychological Association. For any other use, please contact the APA Permissions Office.\
66 | Example 4\
67 | In this example, we have added our own emphasis. This needs to be indicated parenthetically,\
68 | so the reader knows that the italics were not in the original text. Amidala (2009) dabbled in hyperbole,\
69 | saying,\
70 | Random Explosions 2: Revenge of the Dialogue is the worst movie in the history of time\
71 | [emphasis added]. . . . it’s [sic] promise of dialogue is a misnomer of explosive proportions. Lorem ipsum\
72 | dolor sit amet, consectetur adipiscing elit. Sed nisi mi, pharetra sit amet mi vitae. (p. 13)\
73 | This paragraph appears flush left because it is a continuation of the paragraph we began above the block\
74 | quote. Note that we also added “[sic]” within the block quotation to indicate that a misspelling was in\
75 | the original text, and we’ve included ellipses (with four periods) because we have omitted a sentence\
76 | from the quotation (see pp. 172–173 of the Publication Manual of the American Psychological\
77 | Association).\
78 | Example 5\
79 | This example is similar to the previous one, except that we have continued the quotation to\
80 | include text from a second paragraph. Amidala (2009) dabbled in hyperbole, saying,\
81 | Random Explosions 2: Revenge of the Dialogue is the worst movie in the history of time\
82 | [emphasis added]. . . . it’s [sic] promise of dialogue is a misnomer of explosive proportions.\
83 | On the other hand, Delightful Banter on Windswept Mountainside is a film to be\
84 | cherished for all time. Filmmakers hoping to top this film should abandon hope. (p. 13)\
85 | This paragraph begins with an indent because we do not intend it to continue the paragraph\
86 | that we started above the block quote. Note that we also added “[sic]” within the block quotation to\
87 | indicate that a misspelling was in the original text, and we’ve included ellipses (with four periods)\
88 | because we have omitted a sentence from this quotation (see pp. 172–173 of the Manual).";
89 |
90 | return textView;
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoHeaderViews/DemoHeaderViews.m:
--------------------------------------------------------------------------------
1 | //
2 | // DemoHeaders.m
3 | // DemoContainerView
4 | //
5 | // Created by Rustam Motygullin on 17/11/2018.
6 | // Copyright © 2018 mrusta. All rights reserved.
7 | //
8 |
9 | #import "DemoHeaderViews.h"
10 | #import "ContainerDefines.h"
11 |
12 | @implementation HeaderLabel
13 | @end
14 |
15 | @implementation HeaderSearch
16 | @end
17 |
18 | @implementation HeaderGrib
19 | @end
20 |
21 |
22 | @implementation DemoHeaderViews
23 |
24 |
25 | + (void)changeColorsHeaderView:(UIView *)headerView forStyle:(ContainerStyle)style {
26 |
27 | if(!headerView) return;
28 |
29 | CGFloat alpha = 0.5;
30 | UIColor *separatorColor = GRAYLEVEL(180);
31 | UIColor *graberColor = [separatorColor copy];
32 | if((style == ContainerStyleDark) ||
33 | (style == ContainerStyleDefault)) {
34 | if (style == ContainerStyleDark) alpha = 0.2;
35 | else if (style == ContainerStyleDefault) alpha = 1.0;
36 | separatorColor = GRAYLEVEL(222);
37 | graberColor = RGB(235, 239, 245);
38 | }
39 |
40 | if ([headerView isKindOfClass:[HeaderLabel class]]) {
41 | HeaderLabel *headerLabel = (HeaderLabel *)headerView;
42 | headerLabel.label.textColor = (style == ContainerStyleDark) ? WHITE_COLOR : BLACK_COLOR;
43 | headerLabel.separatorLine.backgroundColor = separatorColor;
44 | headerLabel.separatorLine.alpha = alpha;
45 | headerLabel.grip.backgroundColor = graberColor;
46 | headerLabel.grip.alpha = alpha;
47 | }
48 | else if([headerView isKindOfClass:[HeaderSearch class]]) {
49 | HeaderSearch *headerSearch = (HeaderSearch *)headerView;
50 | headerSearch.searchBar.keyboardAppearance = (style == ContainerStyleDark) ? UIKeyboardAppearanceDark : UIKeyboardAppearanceDefault;
51 | headerSearch.separatorLine.backgroundColor = separatorColor;
52 | headerSearch.separatorLine.alpha = alpha;
53 | }
54 | else if([headerView isKindOfClass:[HeaderGrib class]]) {
55 | HeaderGrib *headerGrip = (HeaderGrib *)headerView;
56 | headerGrip.separatorLine.backgroundColor = separatorColor;
57 | headerGrip.separatorLine.alpha = alpha;
58 | headerGrip.grip.backgroundColor = graberColor;
59 | headerGrip.grip.alpha = alpha;
60 | }
61 |
62 | }
63 |
64 | + (CGFloat)headerSize {
65 | CGFloat paddingWidht = SCREEN_PORTRAIT ?0. :20.;
66 | CGFloat widht = (SCREEN_PORTRAIT ?SCREEN_WIDTH :SCREEN_HEIGHT - paddingWidht);
67 | return widht;
68 | }
69 |
70 | + (HeaderLabel *)createHeaderLabel {
71 |
72 | HeaderLabel *view = [[HeaderLabel alloc] initWithFrame:CGRectMake(0, 0, [self headerSize], CUSTOM_HEADER_HEIGHT)];
73 | view.clipsToBounds = YES;
74 |
75 | UILabel *
76 | label = [[UILabel alloc]initWithFrame:CGRectMake( 18, 16, 161, 30)];
77 | label.font = [UIFont fontWithName:@"ProximaNova-Extrabld" size:24];
78 |
79 | label.text = @"Heading";
80 | view.label = label;
81 | [view addSubview:label];
82 |
83 | view.grip = [self createGrip];
84 | [view addSubview:view.grip];
85 |
86 | view.separatorLine = [self createSeparatorLine];
87 | [view addSubview:view.separatorLine];
88 |
89 |
90 | return view;
91 | }
92 |
93 | + (HeaderSearch *)createHeaderSearch {
94 |
95 | HeaderSearch *view = [[HeaderSearch alloc] initWithFrame:CGRectMake(0, 0, [self headerSize], CUSTOM_HEADER_HEIGHT)];
96 | view.clipsToBounds = YES;
97 |
98 | UISearchBar *
99 | searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 4, [self headerSize], CUSTOM_HEADER_HEIGHT -4)];
100 | searchBar.barStyle = UIBarStyleDefault;
101 | searchBar.searchBarStyle = UISearchBarStyleMinimal;
102 | searchBar.placeholder = @"Search";
103 | searchBar.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth );
104 | view.searchBar = searchBar;
105 | [view addSubview:searchBar];
106 |
107 | view.separatorLine = [self createSeparatorLine];
108 | [view addSubview:view.separatorLine];
109 | return view;
110 | }
111 |
112 | + (HeaderGrib *)createHeaderGrip {
113 | HeaderGrib *view = [[HeaderGrib alloc] initWithFrame:CGRectMake(0, 0, [self headerSize], 20)];
114 |
115 | view.grip = [self createGrip];
116 | [view addSubview:view.grip];
117 |
118 | view.separatorLine = [self createSeparatorLine];
119 | view.separatorLine.frame = CGRectMake(
120 | view.separatorLine.frame.origin.x, 19.5 ,
121 | view.separatorLine.frame.size.width, view.separatorLine.frame.size.height
122 | );
123 |
124 | view.separatorShadow = [[UIImageView alloc]initWithFrame:CGRectMake(0, 19.5, [self headerSize], 20)];
125 | view.separatorShadow.image = IMG(@"header_shadow.png");
126 | view.separatorShadow.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth);
127 | // view.separatorShadow.alpha = 0.4;
128 | [view addSubview:view.separatorShadow];
129 |
130 | [view addSubview:view.separatorLine];
131 | return view;
132 | }
133 |
134 | + (UIView *)createSeparatorLine {
135 | CGFloat height = 0.5;
136 | UIView *
137 | line = [[UIView alloc]initWithFrame: CGRectMake( 0, CUSTOM_HEADER_HEIGHT -height, [self headerSize], height )];
138 | line.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth );
139 | return line;
140 | }
141 |
142 | + (UIView *)createGrip {
143 | UIView *
144 | grip = [[UIView alloc] initWithFrame: CGRectMake( (([self headerSize] / 2) -18) , 8 , 36, 4 )];
145 | grip.autoresizingMask = (UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin );
146 | grip.layer.cornerRadius = grip.frame.size.height / 2;
147 | return grip;
148 | }
149 |
150 |
151 | @end
152 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ContainerView
2 |
3 | ContainerView is designed to add a cool swim from the bottom to the animation with the effect of scale, controlled by the help of a gesture, scrollView also takes control.
4 |
5 | The idea is taken from the application [Apple Maps](https://www.apple.com/ios/maps/)
6 |
7 | ______________________________
8 | Also, ☝️ See the new version `Swift` [ContainerController](https://github.com/mrustaa/ContainerController/)
9 |
10 | ## Preview
11 | 
12 | 
13 | 
14 |
15 |
16 |
17 | - [Installation](#installation)
18 | - [CocoaPods](#cocoapods)
19 | - [Getting Started](#getting-started)
20 | - [Setting](#setting)
21 | - [Change position Top Middle Bottom](#change-position-top-middle-bottom)
22 | - [Adding Custom View](#adding-custom)
23 | - [`View` under ContainerView](#view-under-containerview)
24 | - [`ScrollView` in ContainerView](#scrollview-in-containerview)
25 | - [`HeaderView` in ContainerView](#headerview-in-containerview)
26 | - [Protocol](#protocol)
27 | - [Reports the changes current position of the container, after its use](#reports-the-changes-current-position-of-the-container-after-its-use)
28 | - [License](#license)
29 |
30 |
31 |
32 | ## Installation
33 |
34 | ### CocoaPods
35 |
36 | ContainerView is available through [CocoaPods](https://cocoapods.org). To install
37 | it, simply add the following line to your Podfile:
38 |
39 | ```ruby
40 | pod 'ContainerView'
41 | ```
42 |
43 | ## Getting Started
44 |
45 | ```objc
46 | #import
47 | #import "ContainerViewController.h"
48 |
49 | @interface ViewController : ContainerViewController
50 | @end
51 | ```
52 |
53 | ## Setting
54 |
55 | ```objc
56 | - (void)viewDidLoad {
57 | [super viewDidLoad];
58 |
59 | // This parameter for changing the rounding corner radius of the Container
60 | self.containerCornerRadius = 15;
61 |
62 | // This parameter to add a blur to the background of the Container
63 | self.containerStyle = ContainerStyleLight;
64 |
65 | // This parameter adds 3 position (move to the middle). Default there are 2 positions
66 | self.containerAllowMiddlePosition = YES;
67 |
68 | // This parameter allows you to zoom in on the screen under Container
69 | self.containerZoom = YES;
70 |
71 | // This parameter sets the shadow under Container
72 | self.containerShadowView = YES;
73 |
74 | // This parameter sets the shadow in Container
75 | self.containerShadow = YES;
76 |
77 | // This parameter indicates whether to add a button when the container is at the bottom to move the container to the top
78 | self.containerBottomButtonToMoveTop = YES;
79 | }
80 | ```
81 |
82 | ### Change position Top Middle Bottom
83 |
84 | ```objc
85 | - (void)viewDidLoad {
86 | [super viewDidLoad];
87 |
88 | // These parameters set the new position value.
89 | self.containerTop = 50;
90 | self.containerMiddle = 200;
91 | self.containerBottom = 400;
92 | }
93 | ```
94 |
95 | ### Move position with an animation
96 |
97 | ```objc
98 | - (void)moveTop {
99 | [self containerMove:ContainerMoveTypeTop];
100 | }
101 |
102 | - (void)moveMiddle {
103 | [self containerMove:ContainerMoveTypeMiddle];
104 | }
105 |
106 | - (void)moveBottom {
107 | [self containerMove:ContainerMoveTypeBottom];
108 | }
109 | ```
110 |
111 | ## Adding Custom
112 |
113 | ### `View` under ContainerView
114 |
115 | #### ☝️ Adding all views under the ContainerView necessarily via the `self.bottomView`
116 |
117 | ```objc
118 | - (void)viewDidLoad {
119 | [super viewDidLoad];
120 |
121 | UILabel *label = [[UILabel alloc]initWithFrame: CGRectMake(18, 26, 60, 30 )];
122 | label.font = [UIFont boldSystemFontOfSize:24];
123 | label.textColor = [UIColor redColor];
124 | label.text = @"Label";
125 |
126 | [self.bottomView addSubview:label];
127 | }
128 | ```
129 |
130 | ### `ScrollView` in ContainerView
131 |
132 | #### ☝️ For all `ScrollView`, add the `self` delegate. Otherwise, moving the container through scrolling will not work.
133 |
134 | ```objc
135 | @interface ViewController ()
136 | @end
137 |
138 | @implementation ViewController
139 |
140 | - (void)viewDidLoad {
141 | [super viewDidLoad];
142 |
143 | UITextView *textView = [[UITextView alloc]initWithFrame:self.view.bounds];
144 | textView.delegate = self;
145 | textView.returnKeyType = UIReturnKeyDone;
146 | textView.backgroundColor = [UIColor clearColor];
147 | textView.font = [UIFont systemFontOfSize:46];
148 | textView.text = @"This \n example \n more \n text \n\n\n\n\n\n\n\n ....";
149 |
150 | [self.containerView addSubview:textView];
151 | }
152 |
153 | @end
154 | ```
155 |
156 | ### `HeaderView` in ContainerView
157 |
158 | ```objc
159 | - (void)addHeader {
160 |
161 | CGFloat height = 60;
162 |
163 | UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, height)];
164 |
165 | UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 4, self.view.frame.size.width, height -4)];
166 | searchBar.barStyle = UIBarStyleDefault;
167 | searchBar.searchBarStyle = UISearchBarStyleMinimal;
168 | searchBar.placeholder = @"Search";
169 | [headerView addSubview:searchBar];
170 |
171 | self.containerView.headerView = headerView;
172 | }
173 | ```
174 |
175 | ## Protocol
176 |
177 | ### Reports the changes current position of the container, after its use
178 |
179 | ```objc
180 | @interface ViewController ()
181 | @end
182 |
183 | @implementation ViewController
184 |
185 | - (void)changeContainerMove:(ContainerMoveType)containerMove containerY:(CGFloat)containerY animated:(BOOL)animated {
186 | [super changeContainerMove:containerMove containerY:containerY animated:animated];
187 | ...
188 | }
189 |
190 | @end
191 | ```
192 |
193 | ## Author
194 |
195 | 📩| [mrustaa](https://github.com/mrustaa/) NOVEMBER 2018
196 |
197 | ## License
198 |
199 | ContainerView is available under the MIT license. See the LICENSE file for more info.
200 |
--------------------------------------------------------------------------------
/ContainerView/ContainerViewController.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Рустам Мотыгуллин on 17.08.2018.
3 | // Copyright © 2018 GetTransfer. All rights reserved.
4 |
5 | #import "ContainerViewController.h"
6 |
7 |
8 | @interface ContainerViewController () {
9 | BOOL bordersRunContainer;
10 | BOOL onceEnded;
11 | BOOL bottomDeceleratingDisable;
12 | BOOL onceScrollingBeginDragging;
13 | BOOL scrollBegin;
14 | CGFloat startScrollPosition;
15 | CGAffineTransform selfTransform;
16 | BOOL _containerShadowView;
17 | BOOL _containerZoom;
18 | }
19 |
20 | @end
21 |
22 | @implementation ContainerViewController
23 |
24 |
25 | - (void)viewDidLoad {
26 | [super viewDidLoad];
27 |
28 | self.automaticallyAdjustsScrollViewInsets = NO;
29 |
30 | [self.view insertSubview:self.bottomView atIndex:0];
31 | [self.view addSubview:self.shadowButton];
32 |
33 |
34 | self.containerShadowView = YES;
35 | self.containerZoom = YES;
36 |
37 | [self.view addSubview:self.containerView];
38 | }
39 |
40 | - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
41 | [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
42 |
43 | BOOL addedTop = self.containerView.firstAddedTop;
44 | BOOL addedMiddle = self.containerView.firstAddedMiddle;
45 | BOOL addedBottom = self.containerView.firstAddedBottom;
46 |
47 | CGFloat top = addedTop ? self.containerTop : CUSTOM_TOP;
48 | CGFloat middle = addedMiddle ? [self.containerView getContainerMiddle] : CUSTOM_MIDDLE;
49 | CGFloat bottom = addedBottom ? [self.containerView getContainerBottom] : CUSTOM_BOTTOM;
50 |
51 | [self.containerView transitionToSizeTop:top middle:middle bottom:bottom size:size];
52 | }
53 |
54 | #pragma mark - Create
55 |
56 |
57 | - (ContainerView *)containerView {
58 |
59 | if(!_containerView) {
60 | ContainerView *
61 | container = [[ContainerView alloc] initWithFrame: CGRectMake( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT +50 )];
62 | container.delegate = self;
63 | _containerView = container;
64 | }
65 | return _containerView;
66 | }
67 |
68 | - (UIView *)bottomView {
69 | if(!_bottomView) {
70 |
71 | UIView *
72 | view = [[UIView alloc]initWithFrame:self.view.bounds];
73 | view.backgroundColor = [UIColor clearColor];
74 | view.clipsToBounds = YES;
75 | view.autoresizingMask =
76 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |
77 | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin);
78 | _bottomView = view;
79 | for( UIView * v in self.view.subviews ) {
80 | [_bottomView addSubview:v];
81 | }
82 | }
83 | return _bottomView;
84 | }
85 |
86 | - (UIButton *)shadowButton {
87 |
88 | if(!_shadowButton) {
89 | UIButton *
90 | shadow = [UIButton buttonWithType:UIButtonTypeCustom];
91 | [shadow addTarget:self action:@selector(shadowButtonAction) forControlEvents:UIControlEventTouchUpInside];
92 | shadow.frame = FRAME;
93 | shadow.backgroundColor = [UIColor blackColor];
94 | shadow.alpha = 0;
95 | shadow.autoresizingMask =
96 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin);
97 | _shadowButton = shadow;
98 |
99 | [self.view addSubview:_shadowButton];
100 | }
101 | return _shadowButton;
102 | }
103 |
104 | #pragma mark - ContainerView Delegate
105 |
106 | - (void)changeContainerMove:(ContainerMoveType)containerMove containerY:(CGFloat)containerY animated:(BOOL)animated {
107 |
108 | if(containerMove == ContainerMoveTypeBottom) {
109 | [self.view endEditing:YES];
110 | }
111 |
112 | if(animated) {
113 | ANIMATION_SPRING(.45,^(void){
114 | [self changeScalesImageAndShadowLevel:containerY];
115 | });
116 | } else {
117 | [self changeScalesImageAndShadowLevel:containerY];
118 | }
119 | }
120 |
121 |
122 |
123 | #pragma mark - Getter Setter
124 |
125 | - (void)setDelegate:(id)delegate {
126 | self.containerView.delegate = delegate;
127 | }
128 |
129 | - (id)delegate {
130 | return self.containerView.delegate;
131 | }
132 |
133 | - (void)setHeaderView:(UIView *)headerView {
134 | self.containerView.headerView = headerView;
135 | }
136 |
137 | - (UIView *)headerView {
138 | return self.containerView.headerView;
139 | }
140 |
141 |
142 | - (void)setContainerShadow:(BOOL)containerShadow {
143 | self.containerView.containerShadow =containerShadow;
144 | }
145 | - (BOOL)containerShadow {
146 | return self.containerView.containerShadow;
147 | }
148 |
149 |
150 |
151 | - (void)setContainerBottomButtonToMoveTop:(BOOL)containerBottomButtonToMoveTop {
152 | self.containerView.containerBottomButtonToMoveTop = containerBottomButtonToMoveTop;
153 | }
154 |
155 | - (BOOL)containerBottomButtonToMoveTop {
156 | return self.containerView.containerBottomButtonToMoveTop;
157 | }
158 |
159 |
160 | - (void)setContainerShadowView:(BOOL)value {
161 | _shadowButton.hidden = (!value);
162 | _containerShadowView = value;
163 | }
164 |
165 | - (BOOL)containerShadowView {
166 | return _shadowButton != nil;
167 | }
168 |
169 | - (void)shadowButtonAction {
170 | [self containerMove:ContainerMoveTypeBottom];
171 | }
172 |
173 |
174 | - (void)setContainerZoom:(BOOL)containerZoom {
175 | _containerZoom = containerZoom;
176 | }
177 |
178 | - (BOOL)containerZoom {
179 | return _containerZoom;
180 | }
181 |
182 | - (void)setContainerAllowMiddlePosition:(BOOL)containerAllowMiddlePosition {
183 | self.containerView.containerAllowMiddlePosition = containerAllowMiddlePosition;
184 | }
185 |
186 | - (BOOL)containerAllowMiddlePosition {
187 | return self.containerView.containerAllowMiddlePosition;
188 | }
189 |
190 | - (void)setContainerStyle:(ContainerStyle)containerStyle {
191 | [self.containerView changeBlurStyle:containerStyle];
192 | }
193 |
194 | - (ContainerStyle)containerStyle {
195 | return self.containerView.containerStyle;
196 | }
197 |
198 |
199 | - (void)setContainerCornerRadius:(CGFloat)containerCornerRadius {
200 | self.containerView.containerCornerRadius = containerCornerRadius;
201 | }
202 |
203 | - (CGFloat)containerCornerRadius {
204 | return self.containerView.containerCornerRadius;
205 | }
206 |
207 |
208 |
209 | #pragma mark - Container Set/Get Top/Middle/Bottom position
210 |
211 |
212 |
213 | - (void)setContainerTop:(CGFloat)containerTop {
214 | self.containerView.containerTop = containerTop;
215 | }
216 |
217 | - (CGFloat)containerTop {
218 | return self.containerView.containerTop;
219 | }
220 |
221 |
222 | - (void)setContainerMiddle:(CGFloat)containerMiddle {
223 | self.containerView.containerMiddle = containerMiddle;
224 | }
225 |
226 | - (CGFloat)containerMiddle {
227 | return self.containerView.containerMiddle;
228 | }
229 |
230 | - (void)setContainerBottom:(CGFloat)containerBottom {
231 | self.containerView.containerBottom = containerBottom;
232 | }
233 |
234 | - (CGFloat)containerBottom {
235 | return self.containerView.containerBottom;
236 | }
237 |
238 |
239 |
240 | #pragma mark - Container Move
241 |
242 | - (ContainerMoveType)containerPosition {
243 | return self.containerView.containerPosition;
244 | }
245 |
246 | - (void)containerMove:(ContainerMoveType)moveType {
247 | [self.containerView containerMove:moveType];
248 | }
249 |
250 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated {
251 | [self.containerView containerMove:moveType animated:animated];
252 | }
253 |
254 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion {
255 | [self.containerView containerMove:moveType animated:animated completion:completion];
256 | }
257 |
258 |
259 |
260 |
261 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType {
262 | [self.containerView containerMoveCustomPosition:position moveType:moveType];
263 | }
264 |
265 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated {
266 | [self.containerView containerMoveCustomPosition:position moveType:moveType animated:animated];
267 | }
268 |
269 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion {
270 | [self.containerView containerMoveCustomPosition:position moveType:moveType animated:animated completion:completion];
271 | }
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 | #pragma mark - Change ShadowLevel
282 |
283 | - (void)changeScalesImageAndShadowLevel:(CGFloat)containerFrameY {
284 |
285 | CGFloat selfCenter = self.containerView.containerMiddle;
286 |
287 |
288 | if(containerFrameY < selfCenter) {
289 |
290 | CGFloat procent = (((selfCenter - containerFrameY) / selfCenter) / 2);
291 |
292 | CGAffineTransform transform = CGAffineTransformMakeScale( 1. - (procent / 5), 1. - (procent / 5));
293 |
294 | if(self.containerZoom) {
295 | self.bottomView.transform = transform;
296 | self.bottomView.layer.cornerRadius = (procent * 24);
297 | } else {
298 | self.bottomView.transform = CGAffineTransformIdentity;
299 | self.bottomView.layer.cornerRadius = 0;
300 | }
301 |
302 | self.shadowButton.alpha = procent;
303 |
304 | CGFloat height;
305 | if(self.containerView.portrait)
306 | height = (containerFrameY + self.containerView.containerCornerRadius +5);
307 | else height = SCREEN_HEIGHT;
308 |
309 | self.shadowButton.frame = CGRectMake( self.shadowButton.frame.origin.x,self.shadowButton.frame.origin.y, self.shadowButton.frame.size.width, height);
310 | } else {
311 | self.bottomView.transform = CGAffineTransformIdentity;
312 | self.bottomView.layer.cornerRadius = 0;
313 |
314 | self.shadowButton.alpha = 0.;
315 | self.shadowButton.frame = CGRectMake( self.shadowButton.frame.origin.x, self.shadowButton.frame.origin.y, self.shadowButton.frame.size.width, SCREEN_HEIGHT);
316 | }
317 | }
318 |
319 |
320 |
321 |
322 | #pragma mark - Scroll Delegate
323 |
324 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView
325 | {
326 | CGFloat velocityInViewY = [scrollView.panGestureRecognizer velocityInView: self.view].y;
327 | CGFloat translationInViewY = [scrollView.panGestureRecognizer translationInView:self.view].y;
328 |
329 | if(scrollView.panGestureRecognizer.state == UIGestureRecognizerStateChanged) {
330 | [self.view endEditing:YES];
331 | }
332 |
333 | if((scrollView.panGestureRecognizer.state) && (scrollView.contentOffset.y <= 0)) {
334 | scrollView.showsVerticalScrollIndicator = NO;
335 | scrollView.contentOffset = CGPointMake( scrollView.contentOffset.x, 0 );
336 | } else {
337 | scrollView.showsVerticalScrollIndicator = YES;
338 | }
339 |
340 | bordersRunContainer = ( (scrollView.contentOffset.y == 0) && (0 < velocityInViewY));
341 |
342 | selfTransform = self.containerView.transform;
343 |
344 |
345 | // TODO: Implement these.
346 | // if (NAV_ADDED) {
347 | // UINavigationController * nav = (UINavigationController *)ROOT_VC;
348 | // if(!nav.navigationBarHidden) {
349 | // if(!nav.navigationBar.translucent) {
350 | //
351 | // }
352 | // if (@available(iOS 11.0, *)) {
353 | // if(!nav.navigationBar.prefersLargeTitles) {
354 | //
355 | // }
356 | // }
357 | // }
358 | // }
359 |
360 |
361 | CGFloat top = self.containerView.containerTop;
362 | top += IPHONE_X_PADDING_TOP;
363 |
364 |
365 | if(scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded)
366 | onceScrollingBeginDragging = NO;
367 |
368 | if(bordersRunContainer) {
369 |
370 | onceEnded = NO;
371 | onceScrollingBeginDragging = NO;
372 |
373 | selfTransform.ty = ((top - startScrollPosition) + translationInViewY );
374 | if(selfTransform.ty < top) selfTransform.ty = top;
375 |
376 | if(scrollBegin)
377 | {
378 | ANIMATION_SPRING(.325, ^(void) {
379 | self.containerView.transform = self->selfTransform;
380 | });
381 |
382 | scrollBegin = NO;
383 |
384 | } else {
385 | self.containerView.transform = selfTransform;
386 | }
387 | }
388 | else
389 | {
390 | if((top == selfTransform.ty) && !onceScrollingBeginDragging) {
391 | onceScrollingBeginDragging = YES;
392 |
393 | CGFloat headerHeight = (self.containerView.headerView) ?self.containerView.headerView.frame.size.height :0;
394 | CGFloat top = (self.containerView.containerTop == 0) ? CUSTOM_TOP : self.containerView.containerTop;
395 | CGFloat iphnX = IPHONE_X_PADDING_TOP;
396 |
397 | CGFloat height = (SCREEN_HEIGHT - (top + headerHeight + iphnX ));
398 |
399 | if(scrollView.frame.size.height != height) {
400 |
401 | ANIMATION_SPRING( .45, ^(void) {
402 | scrollView.frame = CGRectMake(
403 | scrollView.frame.origin.x, headerHeight ,
404 | scrollView.frame.size.width, height
405 | );
406 | });
407 | }
408 | }
409 |
410 |
411 | if(top < selfTransform.ty)
412 | {
413 | if (velocityInViewY < 0. )
414 | {
415 | if(self.containerView.containerPosition == ContainerMoveTypeTop) {
416 | scrollView.contentOffset = CGPointMake(scrollView.contentOffset.x, 0 );
417 | }
418 |
419 | selfTransform = self.containerView.transform;
420 | selfTransform.ty = ((top - startScrollPosition) + translationInViewY );
421 |
422 | if(selfTransform.ty < top) selfTransform.ty = top;
423 |
424 | self.containerView.transform = selfTransform;
425 | }
426 | }
427 | }
428 |
429 |
430 | [self changeScalesImageAndShadowLevel:selfTransform.ty];
431 |
432 | }
433 |
434 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
435 | {
436 | startScrollPosition = scrollView.contentOffset.y;
437 |
438 | if(bottomDeceleratingDisable) return;
439 |
440 | scrollBegin = YES;
441 | if(startScrollPosition < 0) startScrollPosition = 0;
442 | }
443 |
444 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
445 | {
446 | if(bottomDeceleratingDisable) return;
447 | CGFloat velocityInViewY = [scrollView.panGestureRecognizer velocityInView:WINDOW].y;
448 |
449 | if(!self.containerView) return;
450 |
451 | if(!onceEnded)
452 | {
453 | onceEnded = YES;
454 | [self.containerView containerMoveForVelocityInView:velocityInViewY];
455 | }
456 | }
457 |
458 |
459 | @end
460 |
--------------------------------------------------------------------------------
/ContainerView/ContainerView.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 08.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 | #import "ContainerView.h"
6 |
7 | @interface ContainerView () {
8 | CGFloat _containerTop;
9 | CGFloat _containerMiddle;
10 | CGFloat _containerBottom;
11 | CGFloat _savePositionContainer;
12 | CGFloat _containerCornerRadius;
13 | BOOL _containerAllowMiddlePosition;
14 | BOOL _containerBottomButtonToMoveTop;
15 | BOOL _containerShadow;
16 | UIView * _headerView;
17 | }
18 |
19 |
20 |
21 | @property (strong, nonatomic) UIButton *bottomButtonToMoveTop;
22 |
23 | @property (strong, nonatomic) UIScrollView *scrollView;
24 |
25 |
26 | @property (strong, nonatomic) UIVisualEffectView *visualEffectViewOrigin;
27 | @property (strong, nonatomic) UIView *visualEffectView;
28 |
29 | @end
30 |
31 |
32 | @implementation ContainerView
33 |
34 | - (id)initWithFrame:(CGRect)rect
35 | {
36 | self = [super initWithFrame:rect];
37 | if(self) [self initContainer];
38 | return self;
39 | }
40 |
41 | - (void)initContainer
42 | {
43 | [self initContainerSize:CGSizeMake(SCREEN_WIDTH,SCREEN_HEIGHT)];
44 |
45 | self.backgroundColor = CLR_COLOR;
46 | self.clipsToBounds = NO;
47 | //self.layer.masksToBounds = NO;
48 |
49 | self.layer.shadowOffset = CGSizeMake(0, 5);
50 | self.layer.shadowOpacity = 0.75;
51 | self.layer.shadowRadius = 5;
52 | self.layer.shadowColor = RGB(44, 62, 80).CGColor;
53 |
54 |
55 |
56 | _containerAllowMiddlePosition = NO;
57 | _containerShadow = YES;
58 |
59 | UIPanGestureRecognizer *
60 | containerPan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureRecognized:)];
61 | containerPan.delegate = self;
62 | [self addGestureRecognizer:containerPan];
63 |
64 |
65 | // TODO: Implement these.
66 | // if (NAV_ADDED) {
67 | // UINavigationController * nav = (UINavigationController *)ROOT_VC;
68 | // if(!nav.navigationBarHidden) {
69 | // if(!nav.navigationBar.translucent) {
70 | //
71 | // }
72 | // if (@available(iOS 11.0, *)) {
73 | // if(!nav.navigationBar.prefersLargeTitles) {
74 | //
75 | // }
76 | // }
77 | // }
78 | // }
79 |
80 |
81 | self.transform = CGAffineTransformMakeTranslation( 0, self.containerBottom - IPHONE_X_PADDING_BOTTOM);
82 | self.containerPosition = ContainerMoveTypeBottom;
83 |
84 | if(!_visualEffectView) {
85 | _visualEffectView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
86 | _visualEffectView.clipsToBounds = YES;
87 | _visualEffectView.autoresizingMask =
88 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |
89 | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin);
90 | [self addSubview:_visualEffectView];
91 |
92 | if(!_visualEffectViewOrigin)
93 | {
94 | UIVisualEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleExtraLight];
95 | _visualEffectViewOrigin = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
96 | _visualEffectViewOrigin.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
97 | _visualEffectViewOrigin.autoresizingMask =
98 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |
99 | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin);
100 | [_visualEffectView addSubview: _visualEffectViewOrigin];
101 | }
102 | _visualEffectView.backgroundColor = WHITE_COLOR;
103 | _visualEffectViewOrigin.hidden = YES;
104 | }
105 | }
106 |
107 | /// Add Subview - Search ScrollView
108 | - (void)addSubview:(UIView *)subview {
109 | if(subview == self.visualEffectView) {
110 | [super addSubview:subview];
111 | } else {
112 | if(self.headerView) [self.visualEffectView insertSubview:subview belowSubview:self.headerView];
113 | else [self.visualEffectView addSubview:subview];
114 | }
115 |
116 | if([subview isKindOfClass:[UIScrollView class]]) {
117 |
118 | if(_bottomButtonToMoveTop) {
119 | [_bottomButtonToMoveTop removeFromSuperview];
120 | _bottomButtonToMoveTop = nil;
121 | }
122 |
123 | if(_containerBottomButtonToMoveTop) {
124 | [self addSubview:self.bottomButtonToMoveTop];
125 | }
126 |
127 | self.scrollView = (UIScrollView *)subview;
128 | if (@available(iOS 11.0, *)) {
129 | self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
130 | }
131 |
132 | self.scrollView.scrollEnabled = (self.containerPosition == ContainerMoveTypeTop);
133 |
134 | self.scrollView.indicatorStyle =
135 | (self.containerStyle == ContainerStyleDark) ? UIScrollViewIndicatorStyleWhite :UIScrollViewIndicatorStyleDefault;
136 |
137 | [self changeCornerRadius:_containerCornerRadius];
138 | }
139 | }
140 |
141 | - (void)setContainerBottomButtonToMoveTop:(BOOL)newValue {
142 | _containerBottomButtonToMoveTop = newValue;
143 | if(newValue) {
144 | [self addSubview: self.bottomButtonToMoveTop];
145 | } else if (!newValue && _bottomButtonToMoveTop) {
146 | [_bottomButtonToMoveTop removeFromSuperview];
147 | _bottomButtonToMoveTop = nil;
148 | }
149 | }
150 |
151 | - (BOOL)containerBottomButtonToMoveTop {
152 | return _containerBottomButtonToMoveTop;
153 | }
154 |
155 | - (void)setContainerCornerRadius:(CGFloat)containerCornerRadius {
156 | [self changeCornerRadius:containerCornerRadius];
157 | }
158 |
159 | - (CGFloat)containerCornerRadius {
160 | return _containerCornerRadius;
161 | }
162 |
163 | - (void)changeCornerRadius:(CGFloat)newValue {
164 | _containerCornerRadius = newValue;
165 |
166 | self.layer.cornerRadius = _containerCornerRadius;
167 |
168 | if (self.visualEffectView)
169 | self.visualEffectView.layer.cornerRadius = _containerCornerRadius;
170 |
171 | [self calculationScrollViewHeight:0];
172 | }
173 |
174 |
175 |
176 |
177 |
178 | - (UIButton *)bottomButtonToMoveTop {
179 |
180 | if(!_bottomButtonToMoveTop)
181 | {
182 | UIButton *
183 | btn = [UIButton buttonWithType:UIButtonTypeCustom];
184 | [btn addTarget:self action:@selector(containerBottomButtonAction) forControlEvents:UIControlEventTouchUpInside];
185 |
186 | //[btn addGestureRecognizer: [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(containerBottomButtonAction)]];
187 | //[btn addGestureRecognizer: [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(containerBottomButtonAction)]];
188 |
189 | btn.frame = CGRectMake( 0, 0, SCREEN_WIDTH, (SCREEN_HEIGHT - self.containerBottom + IPHONE_X_PADDING_BOTTOM) );
190 | btn.backgroundColor = CLR_COLOR;
191 | _bottomButtonToMoveTop = btn;
192 | }
193 |
194 | return _bottomButtonToMoveTop;
195 | }
196 | - (void)containerBottomButtonAction {
197 | if(self.containerPosition == ContainerMoveTypeBottom) {
198 | [self containerMove:ContainerMoveTypeTop];
199 | }
200 | }
201 |
202 |
203 | - (void)initContainerSize:(CGSize)size {
204 |
205 | if(size.width < size.height) {
206 | self.portrait = YES;
207 | self.frame = CGRectMake( 0 , self.frame.origin.y, size.width, size.height + 50);
208 | } else {
209 | self.portrait = NO;
210 | self.frame = CGRectMake( (IS_IPHONE_X ? 44 :15), self.frame.origin.y, (size.height - 20), size.height + 50);
211 | }
212 | }
213 |
214 | - (void)transitionToSizeTop:(CGFloat)top middle:(CGFloat)middle bottom:(CGFloat)bottom size:(CGSize)size {
215 |
216 | _containerTop = top;
217 | _containerMiddle = middle;
218 | _containerBottom = bottom;
219 |
220 | [self initContainerSize:size];
221 |
222 | [self calculationScrollViewHeight:0];
223 |
224 | [self containerMove:self.containerPosition];
225 | }
226 |
227 | /// Top
228 | - (void)setContainerTop:(CGFloat)containerTop {
229 | if(!_firstAddedTop) _firstAddedTop = YES;
230 | _containerTop = containerTop;
231 | }
232 |
233 | - (CGFloat)containerTop {
234 | if(!_containerTop) _containerTop = CUSTOM_TOP;
235 | return _containerTop;
236 | }
237 |
238 | /// Middle
239 | - (void)setContainerMiddle:(CGFloat)containerMiddle {
240 | if(!_firstAddedMiddle) _firstAddedMiddle = YES;
241 | _containerMiddle = containerMiddle;
242 | }
243 |
244 | - (CGFloat)getContainerMiddle {
245 | return (_containerMiddle);
246 | }
247 |
248 | - (CGFloat)containerMiddle {
249 | if(!_containerMiddle) _containerMiddle = CUSTOM_MIDDLE;
250 |
251 | CGFloat bottom = SCREEN_HEIGHT - _containerBottom;
252 | CGFloat middle = (((bottom - _containerTop) * _containerMiddle) + _containerTop);
253 |
254 | return middle;// ((self.frame.size.height - 50) *_containerMiddle);
255 | }
256 |
257 | /// Bottom
258 | - (void)setContainerBottom:(CGFloat)containerBottom {
259 | if(!_firstAddedBottom) _firstAddedBottom = YES;
260 | _containerBottom = containerBottom;
261 | if(_bottomButtonToMoveTop) {
262 | _bottomButtonToMoveTop.frame = CGRectMake( _bottomButtonToMoveTop.frame.origin.x, _bottomButtonToMoveTop.frame.origin.y,
263 | _bottomButtonToMoveTop.frame.size.width, containerBottom );
264 | }
265 | }
266 |
267 | - (CGFloat)getContainerBottom {
268 | return (_containerBottom);
269 | }
270 |
271 | - (CGFloat)containerBottom {
272 | if(!_containerBottom) _containerBottom = CUSTOM_BOTTOM;
273 | return ((self.frame.size.height - 50) -_containerBottom);
274 | }
275 |
276 |
277 | /// Enabled Move Middle
278 | - (void)setContainerAllowMiddlePosition:(BOOL)containerAllowMiddlePosition {
279 | _containerAllowMiddlePosition = containerAllowMiddlePosition;
280 | [self containerMove: (containerAllowMiddlePosition) ?ContainerMoveTypeMiddle :ContainerMoveTypeBottom];
281 | }
282 |
283 | - (BOOL)containerAllowMiddlePosition {
284 | return _containerAllowMiddlePosition;
285 | }
286 |
287 |
288 | /// Shadow
289 | - (void)setContainerShadow:(BOOL)containerShadow {
290 | _containerShadow = containerShadow;
291 |
292 | if(containerShadow) {
293 | self.layer.shadowOffset = CGSizeMake(0, 5);
294 | self.layer.shadowOpacity = 0.75;
295 | self.layer.shadowRadius = 5;
296 | } else {
297 | self.layer.shadowOffset = CGSizeMake(0, 0);
298 | self.layer.shadowOpacity = 0.;
299 | self.layer.shadowRadius = 0;
300 | }
301 | }
302 |
303 | - (BOOL)containerShadow {
304 | return _containerShadow;
305 | }
306 |
307 |
308 | /// Header
309 | - (void)setHeaderView:(UIView *)hv {
310 |
311 | if(hv) {
312 | if(_headerView) [self removeHeaderView];
313 | _headerView = hv;
314 | CGFloat width = SCREEN_PORTRAIT ?SCREEN_WIDTH :(SCREEN_HEIGHT - 20);
315 | _headerView.frame = CGRectMake( _headerView.frame.origin.x, _headerView.frame.origin.y, width, _headerView.frame.size.height );
316 | _headerView.autoresizingMask =
317 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin);
318 | [self addSubview:_headerView];
319 | } else {
320 | [self removeHeaderView];
321 | }
322 | [self calculationScrollViewHeight:0];
323 | }
324 |
325 | - (UIView *)headerView {
326 | return _headerView;
327 | }
328 |
329 | - (void)removeHeaderView {
330 | if(_headerView) {
331 | [_headerView removeFromSuperview];
332 | }
333 | _headerView = nil;
334 | }
335 |
336 |
337 | /// Calculation ScrollView
338 | - (void)calculationScrollViewHeight:(CGFloat)containerPositionBottom {
339 | if(self.scrollView) {
340 | CGFloat headerHeight = 0;
341 | CGFloat top = self.containerTop;
342 | CGFloat iphnXpaddingTop = IPHONE_X_PADDING_TOP;
343 | CGFloat iphnXpaddingBottom = IPHONE_X_PADDING_BOTTOM;
344 | CGFloat scrollIndicatorInsetsBottom = 0;
345 |
346 | if(_headerView) {
347 | headerHeight = _headerView.frame.size.height;
348 | if(_headerView.frame.size.height < (0.66 * self.containerCornerRadius)) {
349 | scrollIndicatorInsetsBottom = ((0.66 * self.containerCornerRadius) - _headerView.frame.size.height);
350 | }
351 | } else {
352 | scrollIndicatorInsetsBottom = (0.66 * self.containerCornerRadius);
353 | }
354 |
355 | CGFloat width = (self.portrait) ?(SCREEN_WIDTH) :(SCREEN_HEIGHT - 20);
356 | CGFloat height = (SCREEN_HEIGHT + containerPositionBottom - (top + headerHeight + iphnXpaddingTop));
357 |
358 | self.scrollView.frame = CGRectMake(self.scrollView.frame.origin.x, headerHeight, width, height);
359 |
360 | self.scrollView.scrollIndicatorInsets = UIEdgeInsetsMake( scrollIndicatorInsetsBottom, 0, (self.portrait) ? iphnXpaddingBottom : 0 , 0);
361 | }
362 | }
363 |
364 |
365 | /// Gesture
366 | - (void)panGestureRecognized:(UIPanGestureRecognizer *)recognizer {
367 |
368 | if (recognizer.state == UIGestureRecognizerStateBegan) {
369 | _savePositionContainer = self.transform.ty;
370 | }
371 | else if (recognizer.state == UIGestureRecognizerStateChanged) {
372 | CGAffineTransform
373 | _transform = self.transform;
374 | _transform.ty = (_savePositionContainer + [recognizer translationInView: self].y );
375 | if (_transform.ty < 0) {
376 | _transform.ty = 0;
377 | } else if( _transform.ty < self.containerTop) {
378 | _transform.ty = ( self.containerTop / 2) + (_transform.ty / 2);
379 |
380 | CGFloat containerPositionBottom = (self.containerPosition == ContainerMoveTypeBottom) ?(self.containerTop + 5) :0;
381 |
382 | if( (self.scrollView.contentOffset.y + self.scrollView.frame.size.height + containerPositionBottom) < (int)self.scrollView.contentSize.height) {
383 | [self calculationScrollViewHeight:(_transform.ty + 5)];
384 | }
385 |
386 | self.transform = _transform;
387 | } else {
388 | self.transform = _transform;
389 | }
390 |
391 | if ([self.delegate respondsToSelector:@selector(changeContainerMove:containerY:animated:)]) {
392 | [self.delegate changeContainerMove:ContainerMoveTypeTop containerY:self.transform.ty animated:NO];
393 | }
394 |
395 | self.bottomButtonToMoveTop.hidden = YES;
396 | }
397 | else if (recognizer.state == UIGestureRecognizerStateEnded) {
398 | CGFloat velocityInViewY = [recognizer velocityInView:self].y;
399 | [self containerMoveForVelocityInView:velocityInViewY];
400 | }
401 | }
402 |
403 | /// Container Move
404 | - (void)containerMoveForVelocityInView:(CGFloat)velocityInViewY {
405 |
406 | ContainerMoveType moveType;
407 |
408 | if( self.containerAllowMiddlePosition ) {
409 | if( self.transform.ty < self.containerMiddle ) {
410 | if(velocityInViewY < 0) {
411 | moveType = ContainerMoveTypeTop;
412 | } else {
413 | moveType = (2500 < velocityInViewY) ?ContainerMoveTypeBottom :ContainerMoveTypeMiddle;
414 | }
415 | } else {
416 | if(velocityInViewY < 0) {
417 | moveType = (velocityInViewY < (-2000)) ?ContainerMoveTypeTop :ContainerMoveTypeMiddle;
418 | } else {
419 | moveType = ContainerMoveTypeBottom;
420 | }
421 | }
422 | } else {
423 | if( self.transform.ty < self.containerTop ) {
424 | moveType = (750 < velocityInViewY) ?ContainerMoveTypeBottom :ContainerMoveTypeTop;
425 | } else {
426 | moveType = (velocityInViewY < 0) ?ContainerMoveTypeTop :ContainerMoveTypeBottom;
427 | }
428 | }
429 | [self containerMove:moveType];
430 |
431 | }
432 |
433 |
434 | - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
435 | shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
436 | return NO;
437 | }
438 |
439 |
440 | - (void)changeBlurStyle:(ContainerStyle)styleType {
441 |
442 | self.containerStyle = styleType;
443 |
444 | self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleDefault;
445 |
446 | CGFloat alpha = 0.5;
447 | UIColor *graberColor = GRAYLEVEL(180);
448 | UIColor *separatorColor = [graberColor copy];
449 |
450 | if((styleType == ContainerStyleDark) ||
451 | (styleType == ContainerStyleDefault)) {
452 | graberColor = RGB(235, 239, 245);
453 | separatorColor = GRAYLEVEL(222);
454 | }
455 |
456 | if (styleType == ContainerStyleDark) alpha = 0.2;
457 | else if (styleType == ContainerStyleDefault) alpha = 1.0;
458 |
459 | if(styleType == ContainerStyleDark) {
460 | self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
461 | }
462 |
463 | if(styleType != ContainerStyleDefault) {
464 | self.visualEffectView.backgroundColor = CLR_COLOR;
465 | self.visualEffectViewOrigin.hidden = NO;
466 |
467 | UIBlurEffectStyle effect;
468 | if (styleType == ContainerStyleLight) effect = UIBlurEffectStyleLight;
469 | else if (styleType == ContainerStyleExtraLight) effect = UIBlurEffectStyleExtraLight;
470 | else effect = UIBlurEffectStyleDark;
471 |
472 | self.visualEffectViewOrigin.effect = [UIBlurEffect effectWithStyle:effect];
473 | } else {
474 | self.visualEffectView.backgroundColor = WHITE_COLOR;
475 | self.visualEffectViewOrigin.hidden = YES;
476 | }
477 | }
478 |
479 |
480 | #pragma mark - ContainerMove
481 |
482 | - (void)containerMove:(ContainerMoveType)moveType {
483 | [self containerMove:moveType animated:YES completion:nil];
484 | }
485 |
486 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated {
487 | [self containerMove:moveType animated:animated completion:nil];
488 | }
489 |
490 | - (void)containerMove:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion {
491 |
492 | self.containerPosition = moveType;
493 |
494 | CGFloat position = 0;
495 |
496 | switch (moveType) {
497 | case ContainerMoveTypeTop: position = self.containerTop + IPHONE_X_PADDING_TOP; break;
498 | case ContainerMoveTypeMiddle: position = self.containerMiddle; break;
499 | case ContainerMoveTypeBottom: position = self.containerBottom - IPHONE_X_PADDING_BOTTOM; break;
500 | case ContainerMoveTypeHide: position = SCREEN_HEIGHT; break;
501 | }
502 |
503 | [self containerMovePosition:position moveType:moveType animated:animated completion:completion];
504 | }
505 |
506 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType {
507 | [self containerMoveCustomPosition:position moveType:moveType animated:YES completion:nil];
508 | }
509 |
510 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated {
511 | [self containerMoveCustomPosition:position moveType:moveType animated:animated completion:nil];
512 | }
513 |
514 | - (void)containerMoveCustomPosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion {
515 | [self calculationScrollViewHeight:0];
516 |
517 | self.containerPosition = moveType;
518 | [self containerMovePosition:position moveType:moveType animated:animated completion:completion];
519 | }
520 |
521 | - (void)containerMovePosition:(CGFloat)position moveType:(ContainerMoveType)moveType animated:(BOOL)animated completion:(void (^)(void))completion {
522 |
523 | if(_bottomButtonToMoveTop) self.bottomButtonToMoveTop.hidden = (moveType != ContainerMoveTypeBottom);
524 |
525 | self.scrollView.scrollEnabled = (moveType == ContainerMoveTypeTop);
526 |
527 | CGFloat containerPositionBottom = (self.containerPosition == ContainerMoveTypeBottom) ?(self.containerTop + 5) :0;
528 |
529 | CGAffineTransform _transform = CGAffineTransformMakeTranslation( 0, position);
530 |
531 | if ([self.delegate respondsToSelector:@selector(changeContainerMove:containerY:animated:)]) {
532 | [self.delegate changeContainerMove:moveType containerY:_transform.ty animated:animated];
533 | }
534 |
535 | if(animated) {
536 | ANIMATION_SPRINGCOMP(.45, ^(void) {
537 | self.transform = _transform;
538 | }, ^(BOOL fin) {
539 |
540 | if(self.scrollView) {
541 | if( (self.scrollView.contentOffset.y + self.scrollView.frame.size.height + containerPositionBottom) < self.scrollView.contentSize.height) {
542 | [self calculationScrollViewHeight:containerPositionBottom];
543 | }
544 | }
545 | if(completion) completion();
546 | });
547 | } else {
548 | self.transform = _transform;
549 | if(completion) completion();
550 | }
551 | }
552 |
553 |
554 |
555 | @end
556 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView/Demo/DemoViewController.m:
--------------------------------------------------------------------------------
1 |
2 | // Created by Rustam Motygullin on 03.07.2018.
3 | // Copyright © 2018 mrusta. All rights reserved.
4 |
5 |
6 | #import "DemoViewController.h"
7 | #import "ContainerDefines.h"
8 |
9 | #import "DemoHeaderViews.h"
10 |
11 | #import "DemoScrollViews.h"
12 | #import "DemoTableCell.h"
13 | #import "DemoCollectionCell.h"
14 |
15 |
16 |
17 |
18 | @interface DemoViewController ()
19 |
20 |
21 | @property (strong, nonatomic) NSMutableArray *photoItems;
22 |
23 | @property (strong, nonatomic) UITableView *tableView;
24 | @property (strong, nonatomic) UICollectionView *collectionView;
25 | @property (strong, nonatomic) UITextView *textView;
26 |
27 |
28 | @property (strong, nonatomic) UIImageView *imageView;
29 | @property (strong, nonatomic) IBOutlet UIView *settingsView;
30 | @property (strong, nonatomic) IBOutlet MKMapView *mapView;
31 | @property (strong, nonatomic) IBOutlet UIVisualEffectView *mapViewStatusBarBlur;
32 |
33 | @property (strong, nonatomic) IBOutlet UISegmentedControl *segmentedContainerMove;
34 | @property (strong, nonatomic) IBOutlet UISwitch *switchEnableMiddle;
35 |
36 | @property (strong, nonatomic) IBOutlet UILabel *containerLabelValueTop;
37 | @property (strong, nonatomic) IBOutlet UILabel *containerLabelValueBottom;
38 | @property (strong, nonatomic) IBOutlet UILabel *containerLabelValueCornerRadius;
39 |
40 | @end
41 |
42 |
43 |
44 |
45 | @implementation DemoViewController
46 |
47 |
48 | #pragma mark - Life Cycle
49 |
50 | - (void)viewDidLoad {
51 | [super viewDidLoad];
52 |
53 |
54 | if(!_imageView) {
55 | _imageView = [[UIImageView alloc]initWithFrame:FRAME];
56 | _imageView.contentMode = SCREEN_PORTRAIT ?UIViewContentModeScaleAspectFill :UIViewContentModeScaleAspectFit;
57 | _imageView.clipsToBounds = YES;
58 | _imageView.backgroundColor = GRAYLEVEL(210);
59 | _imageView.autoresizingMask =
60 | (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin |
61 | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin);
62 | _imageView.alpha = 0;
63 | }
64 | [self.bottomView addSubview:_imageView];
65 |
66 |
67 | [self.mapView setRegion:[self.mapView regionThatFits:COORDINATE_SAN_FRANCISCO]];
68 | self.mapView.alpha = 0;
69 |
70 | self.mapViewStatusBarBlur.alpha = 1;
71 |
72 | self.mapViewStatusBarBlur.frame = CGRectMake(
73 | self.mapViewStatusBarBlur.frame.origin.x, self.mapViewStatusBarBlur.frame.origin.y ,
74 | self.mapViewStatusBarBlur.frame.size.width, SCREEN_STATUS_HEIGHT
75 | );
76 |
77 | _tableView = [DemoScrollViews createTableViewWithProtocols:self];
78 | [self changeTableViewSeparatorStyle];
79 | [self.containerView addSubview:_tableView];
80 |
81 | self.containerCornerRadius = 15;
82 | self.containerBottomButtonToMoveTop = YES;
83 | // [self containerMove:ContainerMoveTypeTop animated:NO];
84 |
85 | self.delegate = self;
86 |
87 |
88 |
89 | [self initScrollViewsPhotoItems];
90 |
91 | }
92 |
93 | #pragma mark - Init Photos Items For TableView & CollecionView
94 |
95 | - (void)initScrollViewsPhotoItems {
96 |
97 | for (int count =0; count < 46; count++) {
98 | UIImage *img = IMG( SFMT(@"IMG_%d",count) );
99 | UIImage *imgSmall = [self imageWithImage:img size:200];
100 |
101 | [self.photoItems addObject:@{ @"big" : img,
102 | @"small" : imgSmall }];
103 | }
104 | if(self.tableView) [self.tableView reloadData];
105 | if(self.collectionView) [self.collectionView reloadData];
106 | }
107 |
108 |
109 | - (NSMutableArray *)photoItems {
110 | if(!_photoItems) _photoItems = [NSMutableArray new];
111 | return _photoItems;
112 | }
113 |
114 |
115 | - (UIImage *)imageWithImage:(UIImage *)image size:(NSInteger)size {
116 |
117 | CGSize cgSize = CGSizeMake( size, (image.size.height / (image.size.width / size) ));
118 | CGRect cgRect = CGRectMake( 0, 0, size, (image.size.height / (image.size.width / size) ));
119 | UIGraphicsBeginImageContextWithOptions( cgSize, NO, 0.0);
120 | [image drawInRect: cgRect ];
121 | UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext();
122 | UIGraphicsEndImageContext();
123 | return newImage;
124 | }
125 |
126 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
127 | [self.view endEditing:YES];
128 | }
129 |
130 |
131 | #pragma mark - UIContentContainer Protocol
132 |
133 | - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator {
134 | [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
135 |
136 | if(_imageView) {
137 | _imageView.contentMode = (size.width < size.height) ?UIViewContentModeScaleAspectFill :UIViewContentModeScaleAspectFit;
138 | }
139 | if(_tableView) {
140 | [_tableView reloadData];
141 | }
142 | if(_collectionView) {
143 | [_collectionView reloadData];
144 | }
145 | }
146 |
147 | #pragma mark - SearchBar Delegate
148 |
149 | - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
150 | if(self.containerPosition != ContainerMoveTypeTop) [self containerMove:ContainerMoveTypeTop];
151 | GCD_ASYNC_GLOBAL_BEGIN(0) {
152 | GCD_ASYNC_MAIN_BEGIN {
153 | [searchBar becomeFirstResponder];
154 | });
155 | });
156 | }
157 |
158 | #pragma mark - TableView Delegate
159 |
160 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
161 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
162 | [self selectCellIndex:(SelectType)indexPath.row animated:YES];
163 | }
164 |
165 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
166 | return 88;
167 | }
168 |
169 | #pragma mark - TableView DataSource
170 |
171 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)sectionIndex {
172 | return self.photoItems.count;
173 | }
174 |
175 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
176 |
177 | DemoTableCell * cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell"];
178 | if(!cell) {
179 | cell = [[DemoTableCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @"TableCell" ];
180 | cell.backgroundColor = CLR_COLOR;
181 | }
182 |
183 | cell.separatorInset = UIEdgeInsetsMake(0, 16, 0, 16);
184 |
185 | if(!cell.labelTitle) {
186 | cell.labelTitle = [[UILabel alloc]initWithFrame:CGRectMake( 18 , 20, SCREEN_WIDTH -67 , 30 )];
187 | cell.labelTitle.font = [UIFont fontWithName:@"ProximaNova-Extrabld" size:22];
188 | cell.labelTitle.textColor = BLACK_COLOR;
189 | [cell addSubview:cell.labelTitle];
190 | }
191 |
192 | if(!cell.labelSubTitle) {
193 | cell.labelSubTitle = [[UILabel alloc]initWithFrame:CGRectMake( 18 , 50, SCREEN_WIDTH -67, 16 )];
194 | cell.labelSubTitle.font = [UIFont fontWithName:@"ProximaNova-Regular" size:15];
195 | cell.labelSubTitle.textColor = RGB(124,132,148);
196 | [cell addSubview:cell.labelSubTitle];
197 | }
198 |
199 | cell.labelTitle .text = (indexPath.row) ? (indexPath.row == 1) ? @"mapView" : SFMT(@"photo %d", (int)indexPath.row) : @"settings" ;
200 | cell.labelSubTitle.text = @"Subtitle";
201 | cell.labelTitle.textColor = (self.containerStyle == ContainerStyleDark) ? WHITE_COLOR : BLACK_COLOR;
202 |
203 | cell.tag = indexPath.row;
204 | cell.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTableCellTap:)];
205 | [cell addGestureRecognizer:cell.tapGesture];
206 |
207 | return cell;
208 | }
209 |
210 | - (void)handleTableCellTap:(UIGestureRecognizer *)gestureRecognizer {
211 | NSInteger i = gestureRecognizer.view.tag;
212 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
213 |
214 | [_tableView selectRowAtIndexPath:indexPath
215 | animated:YES
216 | scrollPosition:UITableViewScrollPositionNone];
217 | [self tableView:_tableView didSelectRowAtIndexPath:indexPath];
218 | }
219 |
220 |
221 |
222 | #pragma mark - CollectionView Delegate
223 |
224 | - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
225 | [self selectCellIndex:(SelectType)indexPath.row animated:YES];
226 | }
227 |
228 | - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
229 |
230 | CGFloat widht = SCREEN_PORTRAIT ?SCREEN_WIDTH :(SCREEN_HEIGHT - 20);
231 |
232 | CGFloat indent = (((widht - ((widht * .437333) * 2)) / 3) / 2);
233 | CGFloat imageSize = (widht * .437333);
234 |
235 | CGSize size = (CGSize) {
236 | ((imageSize + (indent * 2)) -1),
237 | (imageSize + indent + 36)
238 | };
239 |
240 | return size;
241 | }
242 |
243 | - (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section{
244 |
245 | CGFloat widht = SCREEN_PORTRAIT ?SCREEN_WIDTH :(SCREEN_HEIGHT - 20);
246 |
247 | CGFloat indent = (((widht - ((widht * .437333) * 2)) / 3) / 2);
248 | return UIEdgeInsetsMake(indent,indent,0,indent);
249 | }
250 |
251 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
252 | return .0;
253 | }
254 |
255 | - (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
256 | return .0;
257 | }
258 |
259 |
260 | #pragma mark - CollectionView DataSource
261 |
262 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
263 | return self.photoItems.count;
264 | }
265 |
266 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
267 |
268 | DemoCollectionCell * cell = [collectionView dequeueReusableCellWithReuseIdentifier: @"collectionCell" forIndexPath: indexPath];
269 | cell.backgroundColor = CLR_COLOR;
270 | cell.clipsToBounds = YES;
271 |
272 | CGFloat widht = SCREEN_PORTRAIT ?SCREEN_WIDTH :(SCREEN_HEIGHT - 20);
273 |
274 | CGFloat indent = (((widht - ((widht * .437333) * 2)) / 3) / 2);
275 | CGFloat imageSize = (widht * .437333);
276 |
277 | CGSize cellSize = (CGSize)
278 | {
279 | ((imageSize + (indent * 2)) -1) ,
280 | (imageSize + indent + 36)
281 | };
282 |
283 | if(!cell.imageView ) {
284 | cell.imageView = [UIImageView new];
285 | cell.imageView.clipsToBounds = 1;
286 | cell.imageView.backgroundColor = CLR_COLOR;
287 | cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
288 | cell.imageView.layer.cornerRadius = 6;
289 | [cell addSubview: cell.imageView];
290 | }
291 |
292 | if(!cell.label) {
293 | cell.label = [[UILabel alloc]initWithFrame:CGRectMake( 8, cellSize.height -26, cellSize.width -16, 18)];
294 | cell.label.font = [UIFont fontWithName:@"ProximaNova-Extrabld" size:14];
295 | cell.label.textColor = BLACK_COLOR;
296 | [cell addSubview:cell.label];
297 | }
298 |
299 | cell.imageView.frame = CGRectMake( indent, indent, imageSize, imageSize);
300 | cell.imageView.image = self.photoItems[indexPath.row][@"small"];
301 |
302 | cell.label.frame = CGRectMake( 8, cellSize.height -26, cellSize.width -16, 18);
303 | cell.label.text = (indexPath.row) ? (indexPath.row == 1) ? @"mapView" : SFMT(@"photo %d",(int)indexPath.row) : @"settings" ;
304 | cell.label.textColor = (self.containerStyle == ContainerStyleDark) ? WHITE_COLOR : BLACK_COLOR;
305 |
306 | cell.tag = indexPath.row;
307 | cell.tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleColletionCellTap:)];
308 | [cell addGestureRecognizer:cell.tapGesture];
309 |
310 | return cell;
311 | }
312 |
313 | - (void)handleColletionCellTap:(UIGestureRecognizer *)gestureRecognizer {
314 | NSInteger i = gestureRecognizer.view.tag;
315 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
316 |
317 | [_collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];
318 | [self collectionView:_collectionView didSelectItemAtIndexPath:indexPath];
319 | }
320 |
321 | #pragma mark - TableView & Collection Select Cell
322 |
323 | - (void)selectCellIndex:(SelectType)index animated:(BOOL)animated {
324 |
325 | __weak typeof(self) weakSelf = self;
326 | ANIMATIONCOMP( (animated) ? 0.25 : 0. , ^(void) {
327 |
328 | weakSelf.imageView.alpha = 0;
329 |
330 | }, ^(BOOL fin) {
331 |
332 | if((index != SelectTypeSettings) &&
333 | (index != SelectTypeMap)) {
334 | weakSelf.imageView.image = self.photoItems[index][@"big"];
335 | }
336 |
337 | ANIMATION( (animated) ? 0.25 : 0. , ^(void){
338 |
339 | weakSelf.mapViewStatusBarBlur.hidden = YES;
340 | weakSelf.mapView.alpha = 0;
341 | weakSelf.settingsView.alpha = 0;
342 |
343 | switch (index) {
344 | case SelectTypeSettings:
345 | weakSelf.settingsView.alpha = 1;
346 | break;
347 | case SelectTypeMap:
348 | weakSelf.mapView.alpha = 1;
349 | weakSelf.mapViewStatusBarBlur.hidden = APP.statusBarHidden;
350 | break;
351 | default:
352 | weakSelf.imageView.alpha = 1;
353 | break;
354 | }
355 | });
356 | });
357 | }
358 |
359 | #pragma mark - ContainerView Delegate
360 |
361 | - (void)changeContainerMove:(ContainerMoveType)containerMove containerY:(CGFloat)containerY animated:(BOOL)animated {
362 | [super changeContainerMove:containerMove containerY:containerY animated:animated];
363 | if(animated) {
364 | self.segmentedContainerMove.selectedSegmentIndex = containerMove;
365 | }
366 | }
367 |
368 | #pragma mark - ContainerView Changes Parameters
369 |
370 | - (IBAction)changeStatusbar:(UISwitch *)sender {
371 | BOOL hidden = (!sender.on);
372 | self.mapViewStatusBarBlur.hidden = hidden;
373 | APP.statusBarHidden = hidden;
374 | }
375 |
376 | - (IBAction)changeContainerEnabledMiddle:(UISwitch *)sender {
377 | self.containerAllowMiddlePosition = sender.on;
378 | }
379 |
380 | - (IBAction)changeContainerZoom:(UISwitch *)sender {
381 | self.containerZoom = sender.on;
382 | }
383 |
384 | - (IBAction)changeShadow:(UISwitch *)sender {
385 | self.containerShadowView = sender.on;
386 | }
387 |
388 | - (IBAction)changeContainerShadow:(UISwitch *)sender {
389 | self.containerShadow = sender.on;
390 | }
391 |
392 | - (IBAction)changeContainerShowBottomButtonToMoveTop:(UISwitch *)sender {
393 | self.containerBottomButtonToMoveTop = sender.on;
394 | }
395 |
396 |
397 | - (IBAction)changeContainerAlpha:(UISlider *)sender {
398 | self.containerView.alpha = sender.value;
399 | }
400 |
401 | - (IBAction)changeContainerMove:(UISegmentedControl *)sender {
402 | if((ContainerMoveType)sender.selectedSegmentIndex == ContainerMoveTypeMiddle) {
403 | self.containerAllowMiddlePosition = YES;
404 | [self.switchEnableMiddle setOn:YES animated: YES];
405 | }
406 | [self containerMove:(ContainerMoveType)sender.selectedSegmentIndex];
407 | }
408 |
409 |
410 | - (IBAction)changeContainerTitleType:(UISegmentedControl *)sender {
411 |
412 | switch (sender.selectedSegmentIndex) {
413 | case 0: self.headerView = nil; break;
414 | case 1: {
415 | HeaderGrib *grib = [DemoHeaderViews createHeaderGrip];
416 | [DemoHeaderViews changeColorsHeaderView:grib forStyle:self.containerStyle];
417 | self.headerView = grib;
418 | } break;
419 | case 2: {
420 | HeaderLabel *label = [DemoHeaderViews createHeaderLabel];
421 | [DemoHeaderViews changeColorsHeaderView:label forStyle:self.containerStyle];
422 | self.headerView = label;
423 | } break;
424 | case 3: {
425 | HeaderSearch *search = [DemoHeaderViews createHeaderSearch];
426 | search.searchBar.delegate = self;
427 | [DemoHeaderViews changeColorsHeaderView:search forStyle:self.containerStyle];
428 | self.headerView = search;
429 | } break;
430 | default: break;
431 | }
432 | }
433 |
434 | - (IBAction)changeContainerStyle:(UISegmentedControl *)sender {
435 |
436 | ContainerStyle style = sender.selectedSegmentIndex;
437 | self.containerStyle = style;
438 |
439 | UIView *view = self.headerView;
440 | if(view) [DemoHeaderViews changeColorsHeaderView:view forStyle:style];
441 |
442 | if(style == ContainerStyleDark) {
443 | if(self.textView) {
444 | self.textView.textColor = WHITE_COLOR;
445 | self.textView.keyboardAppearance = UIKeyboardAppearanceDark;
446 | }
447 |
448 | self.mapView.mapType = MKMapTypeHybrid;
449 | self.mapViewStatusBarBlur.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
450 | STATUSBAR_STYLE(UIStatusBarStyleLightContent);
451 | // self.mapViewStatusBarBlur.hidden
452 | self.view .backgroundColor = RGB(55, 55, 55);
453 | self.settingsView.backgroundColor = RGB(66, 66, 66);
454 | } else {
455 | if(self.textView) {
456 | self.textView.textColor = BLACK_COLOR;
457 | self.textView.keyboardAppearance = UIKeyboardAppearanceDefault;
458 | }
459 | self.mapView.mapType = MKMapTypeStandard;
460 | self.mapViewStatusBarBlur.effect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
461 | STATUSBAR_STYLE(UIStatusBarStyleDefault);
462 | self.view .backgroundColor = RGB(235, 235, 241);
463 | self.settingsView.backgroundColor = RGB(225, 225, 231);
464 | }
465 |
466 | if(self.tableView) {
467 | [self changeTableViewSeparatorStyle];
468 | [self.tableView reloadData];
469 | }
470 | if(self.collectionView) {
471 | [self.collectionView reloadData];
472 | }
473 |
474 | }
475 |
476 | - (void)changeTableViewSeparatorStyle {
477 | UIColor * color;
478 |
479 | switch (self.containerStyle) {
480 | case ContainerStyleDefault:
481 | color = RGBA(222,222,222,1);
482 | break;
483 | case ContainerStyleDark:
484 | color = RGBA(222,222,222,0.2);
485 | break;
486 | case ContainerStyleExtraLight:
487 | case ContainerStyleLight:
488 | color = RGBA(180,180,180,0.5);
489 | break;
490 |
491 | }
492 | [self.tableView setSeparatorColor:color];
493 | }
494 |
495 | - (IBAction)changeContainerSizeTop:(UISlider *)sender {
496 | CGFloat top = sender.value;
497 |
498 | [self containerMoveCustomPosition:top moveType:ContainerMoveTypeTop animated:YES];
499 |
500 | self.containerTop = top - IPHONE_X_PADDING_TOP;
501 | self.containerLabelValueTop.text = SFMT(@"%.0f y", top);
502 | }
503 |
504 | - (IBAction)changeContainerSizeBottom:(UISlider *)sender {
505 | CGFloat bottom = sender.value; // (SCREEN_HEIGHT -((sender.maximumValue +50) -sender.value));
506 |
507 | [self containerMoveCustomPosition: (SCREEN_HEIGHT - bottom) moveType:ContainerMoveTypeBottom animated:NO];
508 |
509 | self.containerBottom = bottom - IPHONE_X_PADDING_BOTTOM;
510 | self.containerLabelValueBottom.text = SFMT(@"%.0f y", bottom);
511 | }
512 |
513 |
514 | - (IBAction)changeContainerCornerRadius:(UISlider *)sender {
515 | self.containerCornerRadius = sender.value;
516 | self.containerLabelValueCornerRadius.text = SFMT(@"%d", (int)sender.value);
517 | }
518 |
519 | - (IBAction)changeContainerScrollViewType:(UISegmentedControl *)sender {
520 |
521 | if(_tableView) {
522 | [_tableView removeFromSuperview];
523 | _tableView = nil;
524 | }
525 | if(_collectionView) {
526 | [_collectionView removeFromSuperview];
527 | _collectionView = nil;
528 | }
529 | if(_textView) {
530 | [_textView removeFromSuperview];
531 | _textView = nil;
532 | }
533 |
534 | switch (sender.selectedSegmentIndex) {
535 | case 0: {
536 | _tableView = [DemoScrollViews createTableViewWithProtocols:self];
537 | [self changeTableViewSeparatorStyle];
538 | [self.containerView addSubview:_tableView];
539 | } break;
540 | case 1: {
541 | _collectionView = [DemoScrollViews createCollectionViewWithProtocols:self];
542 | [self.containerView addSubview:_collectionView];
543 | } break;
544 | case 2: {
545 | _textView = [DemoScrollViews createTextViewWithProtocols:self];
546 | _textView.textColor = (self.containerStyle == ContainerStyleDark) ?WHITE_COLOR :BLACK_COLOR;
547 | _textView.delegate = self;
548 | [self.containerView addSubview:_textView];
549 | } break;
550 | default: break;
551 | }
552 |
553 | }
554 |
555 | - (void)textViewDidBeginEditing:(UITextView *)textView {
556 | [self containerMove:ContainerMoveTypeTop animated:YES];
557 | }
558 |
559 | // TODO: add New Container
560 | //- (IBAction)addNewContainer {
561 | // ContainerView *container = [[ContainerView alloc] initWithFrame: CGRectMake( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT +50 )];
562 | // [container containerMove:ContainerMoveTypeHide animated:NO];
563 | // [self.view addSubview:container];
564 | // [container containerMove:ContainerMoveTypeBottom];
565 | //}
566 |
567 |
568 |
569 | @end
570 |
--------------------------------------------------------------------------------
/DemoContainerView/DemoContainerView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4617423021AC949200730CC5 /* DemoModalViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4617422F21AC949200730CC5 /* DemoModalViewController.m */; };
11 | 4620C5FD219F8D480029326D /* DemoHeaderViews.m in Sources */ = {isa = PBXBuildFile; fileRef = 4620C5FC219F8D480029326D /* DemoHeaderViews.m */; };
12 | 46343B8020F28E4B00EF63F7 /* ProximaNova-Extrabld.otf in Resources */ = {isa = PBXBuildFile; fileRef = 46343B7E20F28E4B00EF63F7 /* ProximaNova-Extrabld.otf */; };
13 | 46343B8120F28E4B00EF63F7 /* ProximaNova-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 46343B7F20F28E4B00EF63F7 /* ProximaNova-Regular.otf */; };
14 | 4648BFCC210E3FA60007D083 /* DemoTableDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4648BFCB210E3FA60007D083 /* DemoTableDelegate.m */; };
15 | 4648BFCF210E3FC60007D083 /* DemoCollectionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4648BFCE210E3FC60007D083 /* DemoCollectionDelegate.m */; };
16 | 4689A7B920EC081A00BC7C8A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4689A7B820EC081A00BC7C8A /* AppDelegate.m */; };
17 | 4689A7BC20EC081A00BC7C8A /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4689A7BB20EC081A00BC7C8A /* DemoViewController.m */; };
18 | 4689A7BF20EC081A00BC7C8A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4689A7BD20EC081A00BC7C8A /* Main.storyboard */; };
19 | 4689A7C120EC081C00BC7C8A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4689A7C020EC081C00BC7C8A /* Assets.xcassets */; };
20 | 4689A7C420EC081C00BC7C8A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4689A7C220EC081C00BC7C8A /* LaunchScreen.storyboard */; };
21 | 4689A7C720EC081C00BC7C8A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4689A7C620EC081C00BC7C8A /* main.m */; };
22 | 4689A7DC20EC08DE00BC7C8A /* DemoTableDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4689A7D720EC08DE00BC7C8A /* DemoTableDataSource.m */; };
23 | 46A1F41C21A5ED1500541435 /* DemoTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A1F41B21A5ED1500541435 /* DemoTableCell.m */; };
24 | 46A1F41F21A5ED8F00541435 /* DemoCollectionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 46A1F41E21A5ED8F00541435 /* DemoCollectionCell.m */; };
25 | 46C519292126267B00A6F607 /* ContainerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C519262126267B00A6F607 /* ContainerView.m */; };
26 | 46C5192A2126267B00A6F607 /* ContainerScrollDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 46C519272126267B00A6F607 /* ContainerScrollDelegate.m */; };
27 | 4A0ACB2521AC517B00465221 /* DemoScrollViews.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A0ACB2421AC517B00465221 /* DemoScrollViews.m */; };
28 | 4A164E9221B1418B0056DCF4 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4A164E9121B1418B0056DCF4 /* README.md */; };
29 | 4A164E9421B1418F0056DCF4 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 4A164E9321B1418F0056DCF4 /* LICENSE */; };
30 | 4A94AE7A21A3F6C90045A212 /* ContainerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A94AE7821A3F6C90045A212 /* ContainerViewController.m */; };
31 | 4A9527E520F8EB4D000DFDFB /* DemoCollectionDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A9527E320F8EB4D000DFDFB /* DemoCollectionDataSource.m */; };
32 | /* End PBXBuildFile section */
33 |
34 | /* Begin PBXFileReference section */
35 | 4617422E21AC949200730CC5 /* DemoModalViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoModalViewController.h; sourceTree = ""; };
36 | 4617422F21AC949200730CC5 /* DemoModalViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoModalViewController.m; sourceTree = ""; };
37 | 4620C5FB219F8D480029326D /* DemoHeaderViews.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoHeaderViews.h; sourceTree = ""; };
38 | 4620C5FC219F8D480029326D /* DemoHeaderViews.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoHeaderViews.m; sourceTree = ""; };
39 | 46343B7E20F28E4B00EF63F7 /* ProximaNova-Extrabld.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ProximaNova-Extrabld.otf"; sourceTree = ""; };
40 | 46343B7F20F28E4B00EF63F7 /* ProximaNova-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "ProximaNova-Regular.otf"; sourceTree = ""; };
41 | 4648BFCA210E3FA60007D083 /* DemoTableDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoTableDelegate.h; sourceTree = ""; };
42 | 4648BFCB210E3FA60007D083 /* DemoTableDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoTableDelegate.m; sourceTree = ""; };
43 | 4648BFCD210E3FC60007D083 /* DemoCollectionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoCollectionDelegate.h; sourceTree = ""; };
44 | 4648BFCE210E3FC60007D083 /* DemoCollectionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCollectionDelegate.m; sourceTree = ""; };
45 | 4689A7B420EC081A00BC7C8A /* DemoContainerView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DemoContainerView.app; sourceTree = BUILT_PRODUCTS_DIR; };
46 | 4689A7B720EC081A00BC7C8A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
47 | 4689A7B820EC081A00BC7C8A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
48 | 4689A7BA20EC081A00BC7C8A /* DemoViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoViewController.h; sourceTree = ""; };
49 | 4689A7BB20EC081A00BC7C8A /* DemoViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoViewController.m; sourceTree = ""; };
50 | 4689A7BE20EC081A00BC7C8A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
51 | 4689A7C020EC081C00BC7C8A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
52 | 4689A7C320EC081C00BC7C8A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
53 | 4689A7C520EC081C00BC7C8A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
54 | 4689A7C620EC081C00BC7C8A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
55 | 4689A7D620EC08DE00BC7C8A /* DemoTableDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTableDataSource.h; sourceTree = ""; };
56 | 4689A7D720EC08DE00BC7C8A /* DemoTableDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTableDataSource.m; sourceTree = ""; };
57 | 46A1F41A21A5ED1500541435 /* DemoTableCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoTableCell.h; sourceTree = ""; };
58 | 46A1F41B21A5ED1500541435 /* DemoTableCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoTableCell.m; sourceTree = ""; };
59 | 46A1F41D21A5ED8F00541435 /* DemoCollectionCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoCollectionCell.h; sourceTree = ""; };
60 | 46A1F41E21A5ED8F00541435 /* DemoCollectionCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoCollectionCell.m; sourceTree = ""; };
61 | 46C519232126267A00A6F607 /* ContainerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerView.h; sourceTree = ""; };
62 | 46C519242126267B00A6F607 /* ContainerDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerDefines.h; sourceTree = ""; };
63 | 46C519252126267B00A6F607 /* ContainerScrollDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerScrollDelegate.h; sourceTree = ""; };
64 | 46C519262126267B00A6F607 /* ContainerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContainerView.m; sourceTree = ""; };
65 | 46C519272126267B00A6F607 /* ContainerScrollDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContainerScrollDelegate.m; sourceTree = ""; };
66 | 46C519282126267B00A6F607 /* ContainerTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerTypes.h; sourceTree = ""; };
67 | 4A0ACB2321AC517B00465221 /* DemoScrollViews.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DemoScrollViews.h; sourceTree = ""; };
68 | 4A0ACB2421AC517B00465221 /* DemoScrollViews.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DemoScrollViews.m; sourceTree = ""; };
69 | 4A164E9121B1418B0056DCF4 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
70 | 4A164E9321B1418F0056DCF4 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
71 | 4A94AE7821A3F6C90045A212 /* ContainerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContainerViewController.m; sourceTree = ""; };
72 | 4A94AE7921A3F6C90045A212 /* ContainerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContainerViewController.h; sourceTree = ""; };
73 | 4A9527E320F8EB4D000DFDFB /* DemoCollectionDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoCollectionDataSource.m; sourceTree = ""; };
74 | 4A9527E420F8EB4D000DFDFB /* DemoCollectionDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoCollectionDataSource.h; sourceTree = ""; };
75 | /* End PBXFileReference section */
76 |
77 | /* Begin PBXFrameworksBuildPhase section */
78 | 4689A7B120EC081A00BC7C8A /* Frameworks */ = {
79 | isa = PBXFrameworksBuildPhase;
80 | buildActionMask = 2147483647;
81 | files = (
82 | );
83 | runOnlyForDeploymentPostprocessing = 0;
84 | };
85 | /* End PBXFrameworksBuildPhase section */
86 |
87 | /* Begin PBXGroup section */
88 | 4620C5FE219F8D8C0029326D /* DemoHeaderViews */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 4620C5FB219F8D480029326D /* DemoHeaderViews.h */,
92 | 4620C5FC219F8D480029326D /* DemoHeaderViews.m */,
93 | );
94 | path = DemoHeaderViews;
95 | sourceTree = "";
96 | };
97 | 4648BFD0210E545F0007D083 /* DemoProtocolsTableView */ = {
98 | isa = PBXGroup;
99 | children = (
100 | 4648BFCA210E3FA60007D083 /* DemoTableDelegate.h */,
101 | 4648BFCB210E3FA60007D083 /* DemoTableDelegate.m */,
102 | 4689A7D620EC08DE00BC7C8A /* DemoTableDataSource.h */,
103 | 4689A7D720EC08DE00BC7C8A /* DemoTableDataSource.m */,
104 | );
105 | path = DemoProtocolsTableView;
106 | sourceTree = "";
107 | };
108 | 4648BFD1210E54650007D083 /* DemoProtocolsCollectionView */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 4648BFCD210E3FC60007D083 /* DemoCollectionDelegate.h */,
112 | 4648BFCE210E3FC60007D083 /* DemoCollectionDelegate.m */,
113 | 4A9527E420F8EB4D000DFDFB /* DemoCollectionDataSource.h */,
114 | 4A9527E320F8EB4D000DFDFB /* DemoCollectionDataSource.m */,
115 | );
116 | path = DemoProtocolsCollectionView;
117 | sourceTree = "";
118 | };
119 | 4689A7AB20EC081A00BC7C8A = {
120 | isa = PBXGroup;
121 | children = (
122 | 4A164E9121B1418B0056DCF4 /* README.md */,
123 | 4A164E9321B1418F0056DCF4 /* LICENSE */,
124 | 46C519222126264600A6F607 /* ContainerView */,
125 | 4689A7B620EC081A00BC7C8A /* DemoContainerView */,
126 | 4689A7B520EC081A00BC7C8A /* Products */,
127 | );
128 | sourceTree = "";
129 | };
130 | 4689A7B520EC081A00BC7C8A /* Products */ = {
131 | isa = PBXGroup;
132 | children = (
133 | 4689A7B420EC081A00BC7C8A /* DemoContainerView.app */,
134 | );
135 | name = Products;
136 | sourceTree = "";
137 | };
138 | 4689A7B620EC081A00BC7C8A /* DemoContainerView */ = {
139 | isa = PBXGroup;
140 | children = (
141 | 4689A7B720EC081A00BC7C8A /* AppDelegate.h */,
142 | 4689A7B820EC081A00BC7C8A /* AppDelegate.m */,
143 | 46E356C121261C2400850BD8 /* Demo */,
144 | 46EA455920FD258F00C0FAE0 /* Resources */,
145 | 4689A7BD20EC081A00BC7C8A /* Main.storyboard */,
146 | 4689A7C020EC081C00BC7C8A /* Assets.xcassets */,
147 | 4689A7C220EC081C00BC7C8A /* LaunchScreen.storyboard */,
148 | 4689A7C520EC081C00BC7C8A /* Info.plist */,
149 | 46EA455A20FD298000C0FAE0 /* Supporting Files */,
150 | );
151 | path = DemoContainerView;
152 | sourceTree = "";
153 | };
154 | 46C519222126264600A6F607 /* ContainerView */ = {
155 | isa = PBXGroup;
156 | children = (
157 | 46C519242126267B00A6F607 /* ContainerDefines.h */,
158 | 46C519282126267B00A6F607 /* ContainerTypes.h */,
159 | 46C519252126267B00A6F607 /* ContainerScrollDelegate.h */,
160 | 46C519272126267B00A6F607 /* ContainerScrollDelegate.m */,
161 | 4A94AE7921A3F6C90045A212 /* ContainerViewController.h */,
162 | 4A94AE7821A3F6C90045A212 /* ContainerViewController.m */,
163 | 46C519232126267A00A6F607 /* ContainerView.h */,
164 | 46C519262126267B00A6F607 /* ContainerView.m */,
165 | );
166 | name = ContainerView;
167 | path = ../ContainerView;
168 | sourceTree = "";
169 | };
170 | 46E356C121261C2400850BD8 /* Demo */ = {
171 | isa = PBXGroup;
172 | children = (
173 | 4620C5FE219F8D8C0029326D /* DemoHeaderViews */,
174 | 4A0ACB2221AC515100465221 /* DemoScrollViews */,
175 | 4689A7BA20EC081A00BC7C8A /* DemoViewController.h */,
176 | 4689A7BB20EC081A00BC7C8A /* DemoViewController.m */,
177 | 4617422E21AC949200730CC5 /* DemoModalViewController.h */,
178 | 4617422F21AC949200730CC5 /* DemoModalViewController.m */,
179 | );
180 | path = Demo;
181 | sourceTree = "";
182 | };
183 | 46EA455920FD258F00C0FAE0 /* Resources */ = {
184 | isa = PBXGroup;
185 | children = (
186 | 46343B7E20F28E4B00EF63F7 /* ProximaNova-Extrabld.otf */,
187 | 46343B7F20F28E4B00EF63F7 /* ProximaNova-Regular.otf */,
188 | );
189 | path = Resources;
190 | sourceTree = "";
191 | };
192 | 46EA455A20FD298000C0FAE0 /* Supporting Files */ = {
193 | isa = PBXGroup;
194 | children = (
195 | 4689A7C620EC081C00BC7C8A /* main.m */,
196 | );
197 | name = "Supporting Files";
198 | sourceTree = "";
199 | };
200 | 4A0ACB2221AC515100465221 /* DemoScrollViews */ = {
201 | isa = PBXGroup;
202 | children = (
203 | 4A0ACB2621AC528300465221 /* DemoCells */,
204 | 4648BFD0210E545F0007D083 /* DemoProtocolsTableView */,
205 | 4648BFD1210E54650007D083 /* DemoProtocolsCollectionView */,
206 | 4A0ACB2321AC517B00465221 /* DemoScrollViews.h */,
207 | 4A0ACB2421AC517B00465221 /* DemoScrollViews.m */,
208 | );
209 | path = DemoScrollViews;
210 | sourceTree = "";
211 | };
212 | 4A0ACB2621AC528300465221 /* DemoCells */ = {
213 | isa = PBXGroup;
214 | children = (
215 | 46A1F41A21A5ED1500541435 /* DemoTableCell.h */,
216 | 46A1F41B21A5ED1500541435 /* DemoTableCell.m */,
217 | 46A1F41D21A5ED8F00541435 /* DemoCollectionCell.h */,
218 | 46A1F41E21A5ED8F00541435 /* DemoCollectionCell.m */,
219 | );
220 | path = DemoCells;
221 | sourceTree = "";
222 | };
223 | /* End PBXGroup section */
224 |
225 | /* Begin PBXNativeTarget section */
226 | 4689A7B320EC081A00BC7C8A /* DemoContainerView */ = {
227 | isa = PBXNativeTarget;
228 | buildConfigurationList = 4689A7CA20EC081C00BC7C8A /* Build configuration list for PBXNativeTarget "DemoContainerView" */;
229 | buildPhases = (
230 | 4689A7B020EC081A00BC7C8A /* Sources */,
231 | 4689A7B120EC081A00BC7C8A /* Frameworks */,
232 | 4689A7B220EC081A00BC7C8A /* Resources */,
233 | );
234 | buildRules = (
235 | );
236 | dependencies = (
237 | );
238 | name = DemoContainerView;
239 | productName = containerView;
240 | productReference = 4689A7B420EC081A00BC7C8A /* DemoContainerView.app */;
241 | productType = "com.apple.product-type.application";
242 | };
243 | /* End PBXNativeTarget section */
244 |
245 | /* Begin PBXProject section */
246 | 4689A7AC20EC081A00BC7C8A /* Project object */ = {
247 | isa = PBXProject;
248 | attributes = {
249 | LastUpgradeCheck = 0940;
250 | ORGANIZATIONNAME = mrusta;
251 | TargetAttributes = {
252 | 4689A7B320EC081A00BC7C8A = {
253 | CreatedOnToolsVersion = 9.4.1;
254 | ProvisioningStyle = Automatic;
255 | };
256 | };
257 | };
258 | buildConfigurationList = 4689A7AF20EC081A00BC7C8A /* Build configuration list for PBXProject "DemoContainerView" */;
259 | compatibilityVersion = "Xcode 8.0";
260 | developmentRegion = en;
261 | hasScannedForEncodings = 0;
262 | knownRegions = (
263 | en,
264 | Base,
265 | );
266 | mainGroup = 4689A7AB20EC081A00BC7C8A;
267 | productRefGroup = 4689A7B520EC081A00BC7C8A /* Products */;
268 | projectDirPath = "";
269 | projectRoot = "";
270 | targets = (
271 | 4689A7B320EC081A00BC7C8A /* DemoContainerView */,
272 | );
273 | };
274 | /* End PBXProject section */
275 |
276 | /* Begin PBXResourcesBuildPhase section */
277 | 4689A7B220EC081A00BC7C8A /* Resources */ = {
278 | isa = PBXResourcesBuildPhase;
279 | buildActionMask = 2147483647;
280 | files = (
281 | 4689A7C420EC081C00BC7C8A /* LaunchScreen.storyboard in Resources */,
282 | 46343B8120F28E4B00EF63F7 /* ProximaNova-Regular.otf in Resources */,
283 | 4689A7C120EC081C00BC7C8A /* Assets.xcassets in Resources */,
284 | 4A164E9421B1418F0056DCF4 /* LICENSE in Resources */,
285 | 4A164E9221B1418B0056DCF4 /* README.md in Resources */,
286 | 46343B8020F28E4B00EF63F7 /* ProximaNova-Extrabld.otf in Resources */,
287 | 4689A7BF20EC081A00BC7C8A /* Main.storyboard in Resources */,
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXResourcesBuildPhase section */
292 |
293 | /* Begin PBXSourcesBuildPhase section */
294 | 4689A7B020EC081A00BC7C8A /* Sources */ = {
295 | isa = PBXSourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | 4689A7BC20EC081A00BC7C8A /* DemoViewController.m in Sources */,
299 | 4620C5FD219F8D480029326D /* DemoHeaderViews.m in Sources */,
300 | 46A1F41F21A5ED8F00541435 /* DemoCollectionCell.m in Sources */,
301 | 4617423021AC949200730CC5 /* DemoModalViewController.m in Sources */,
302 | 4689A7C720EC081C00BC7C8A /* main.m in Sources */,
303 | 4648BFCF210E3FC60007D083 /* DemoCollectionDelegate.m in Sources */,
304 | 4A9527E520F8EB4D000DFDFB /* DemoCollectionDataSource.m in Sources */,
305 | 4648BFCC210E3FA60007D083 /* DemoTableDelegate.m in Sources */,
306 | 46A1F41C21A5ED1500541435 /* DemoTableCell.m in Sources */,
307 | 4689A7DC20EC08DE00BC7C8A /* DemoTableDataSource.m in Sources */,
308 | 46C5192A2126267B00A6F607 /* ContainerScrollDelegate.m in Sources */,
309 | 4A0ACB2521AC517B00465221 /* DemoScrollViews.m in Sources */,
310 | 4A94AE7A21A3F6C90045A212 /* ContainerViewController.m in Sources */,
311 | 46C519292126267B00A6F607 /* ContainerView.m in Sources */,
312 | 4689A7B920EC081A00BC7C8A /* AppDelegate.m in Sources */,
313 | );
314 | runOnlyForDeploymentPostprocessing = 0;
315 | };
316 | /* End PBXSourcesBuildPhase section */
317 |
318 | /* Begin PBXVariantGroup section */
319 | 4689A7BD20EC081A00BC7C8A /* Main.storyboard */ = {
320 | isa = PBXVariantGroup;
321 | children = (
322 | 4689A7BE20EC081A00BC7C8A /* Base */,
323 | );
324 | name = Main.storyboard;
325 | sourceTree = "";
326 | };
327 | 4689A7C220EC081C00BC7C8A /* LaunchScreen.storyboard */ = {
328 | isa = PBXVariantGroup;
329 | children = (
330 | 4689A7C320EC081C00BC7C8A /* Base */,
331 | );
332 | name = LaunchScreen.storyboard;
333 | sourceTree = "";
334 | };
335 | /* End PBXVariantGroup section */
336 |
337 | /* Begin XCBuildConfiguration section */
338 | 4689A7C820EC081C00BC7C8A /* Debug */ = {
339 | isa = XCBuildConfiguration;
340 | buildSettings = {
341 | ALWAYS_SEARCH_USER_PATHS = NO;
342 | CLANG_ANALYZER_NONNULL = YES;
343 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
344 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
345 | CLANG_CXX_LIBRARY = "libc++";
346 | CLANG_ENABLE_MODULES = YES;
347 | CLANG_ENABLE_OBJC_ARC = YES;
348 | CLANG_ENABLE_OBJC_WEAK = YES;
349 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
350 | CLANG_WARN_BOOL_CONVERSION = YES;
351 | CLANG_WARN_COMMA = YES;
352 | CLANG_WARN_CONSTANT_CONVERSION = YES;
353 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
354 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
355 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
356 | CLANG_WARN_EMPTY_BODY = YES;
357 | CLANG_WARN_ENUM_CONVERSION = YES;
358 | CLANG_WARN_INFINITE_RECURSION = YES;
359 | CLANG_WARN_INT_CONVERSION = YES;
360 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
361 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
362 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
363 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
364 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
365 | CLANG_WARN_STRICT_PROTOTYPES = YES;
366 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
367 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
368 | CLANG_WARN_UNREACHABLE_CODE = YES;
369 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
370 | CODE_SIGN_IDENTITY = "iPhone Developer";
371 | COPY_PHASE_STRIP = NO;
372 | DEBUG_INFORMATION_FORMAT = dwarf;
373 | ENABLE_STRICT_OBJC_MSGSEND = YES;
374 | ENABLE_TESTABILITY = YES;
375 | GCC_C_LANGUAGE_STANDARD = gnu11;
376 | GCC_DYNAMIC_NO_PIC = NO;
377 | GCC_NO_COMMON_BLOCKS = YES;
378 | GCC_OPTIMIZATION_LEVEL = 0;
379 | GCC_PREPROCESSOR_DEFINITIONS = (
380 | "DEBUG=1",
381 | "$(inherited)",
382 | );
383 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
384 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
385 | GCC_WARN_UNDECLARED_SELECTOR = YES;
386 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
387 | GCC_WARN_UNUSED_FUNCTION = YES;
388 | GCC_WARN_UNUSED_VARIABLE = YES;
389 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
390 | MTL_ENABLE_DEBUG_INFO = YES;
391 | ONLY_ACTIVE_ARCH = YES;
392 | SDKROOT = iphoneos;
393 | };
394 | name = Debug;
395 | };
396 | 4689A7C920EC081C00BC7C8A /* Release */ = {
397 | isa = XCBuildConfiguration;
398 | buildSettings = {
399 | ALWAYS_SEARCH_USER_PATHS = NO;
400 | CLANG_ANALYZER_NONNULL = YES;
401 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
402 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
403 | CLANG_CXX_LIBRARY = "libc++";
404 | CLANG_ENABLE_MODULES = YES;
405 | CLANG_ENABLE_OBJC_ARC = YES;
406 | CLANG_ENABLE_OBJC_WEAK = YES;
407 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
408 | CLANG_WARN_BOOL_CONVERSION = YES;
409 | CLANG_WARN_COMMA = YES;
410 | CLANG_WARN_CONSTANT_CONVERSION = YES;
411 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
412 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
413 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
414 | CLANG_WARN_EMPTY_BODY = YES;
415 | CLANG_WARN_ENUM_CONVERSION = YES;
416 | CLANG_WARN_INFINITE_RECURSION = YES;
417 | CLANG_WARN_INT_CONVERSION = YES;
418 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
419 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
420 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
421 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
422 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
423 | CLANG_WARN_STRICT_PROTOTYPES = YES;
424 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
425 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
426 | CLANG_WARN_UNREACHABLE_CODE = YES;
427 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
428 | CODE_SIGN_IDENTITY = "iPhone Developer";
429 | COPY_PHASE_STRIP = NO;
430 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
431 | ENABLE_NS_ASSERTIONS = NO;
432 | ENABLE_STRICT_OBJC_MSGSEND = YES;
433 | GCC_C_LANGUAGE_STANDARD = gnu11;
434 | GCC_NO_COMMON_BLOCKS = YES;
435 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
436 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
437 | GCC_WARN_UNDECLARED_SELECTOR = YES;
438 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
439 | GCC_WARN_UNUSED_FUNCTION = YES;
440 | GCC_WARN_UNUSED_VARIABLE = YES;
441 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
442 | MTL_ENABLE_DEBUG_INFO = NO;
443 | SDKROOT = iphoneos;
444 | VALIDATE_PRODUCT = YES;
445 | };
446 | name = Release;
447 | };
448 | 4689A7CB20EC081C00BC7C8A /* Debug */ = {
449 | isa = XCBuildConfiguration;
450 | buildSettings = {
451 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
452 | CODE_SIGN_STYLE = Automatic;
453 | DEVELOPMENT_TEAM = Y7546NLJW9;
454 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
455 | GCC_PREFIX_HEADER = "";
456 | INFOPLIST_FILE = "$(SRCROOT)/DemoContainerView/Info.plist";
457 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
458 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
459 | PRODUCT_BUNDLE_IDENTIFIER = mrusta.containerView;
460 | PRODUCT_NAME = "$(TARGET_NAME)";
461 | TARGETED_DEVICE_FAMILY = "1,2";
462 | };
463 | name = Debug;
464 | };
465 | 4689A7CC20EC081C00BC7C8A /* Release */ = {
466 | isa = XCBuildConfiguration;
467 | buildSettings = {
468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
469 | CODE_SIGN_STYLE = Automatic;
470 | DEVELOPMENT_TEAM = Y7546NLJW9;
471 | FRAMEWORK_SEARCH_PATHS = "$(inherited)";
472 | GCC_PREFIX_HEADER = "";
473 | INFOPLIST_FILE = "$(SRCROOT)/DemoContainerView/Info.plist";
474 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
475 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
476 | PRODUCT_BUNDLE_IDENTIFIER = mrusta.containerView;
477 | PRODUCT_NAME = "$(TARGET_NAME)";
478 | TARGETED_DEVICE_FAMILY = "1,2";
479 | };
480 | name = Release;
481 | };
482 | /* End XCBuildConfiguration section */
483 |
484 | /* Begin XCConfigurationList section */
485 | 4689A7AF20EC081A00BC7C8A /* Build configuration list for PBXProject "DemoContainerView" */ = {
486 | isa = XCConfigurationList;
487 | buildConfigurations = (
488 | 4689A7C820EC081C00BC7C8A /* Debug */,
489 | 4689A7C920EC081C00BC7C8A /* Release */,
490 | );
491 | defaultConfigurationIsVisible = 0;
492 | defaultConfigurationName = Release;
493 | };
494 | 4689A7CA20EC081C00BC7C8A /* Build configuration list for PBXNativeTarget "DemoContainerView" */ = {
495 | isa = XCConfigurationList;
496 | buildConfigurations = (
497 | 4689A7CB20EC081C00BC7C8A /* Debug */,
498 | 4689A7CC20EC081C00BC7C8A /* Release */,
499 | );
500 | defaultConfigurationIsVisible = 0;
501 | defaultConfigurationName = Release;
502 | };
503 | /* End XCConfigurationList section */
504 | };
505 | rootObject = 4689A7AC20EC081A00BC7C8A /* Project object */;
506 | }
507 |
--------------------------------------------------------------------------------