Skip to content

Commit

Permalink
presentation + fix
Browse files Browse the repository at this point in the history
  • Loading branch information
tsucres committed Oct 4, 2017
1 parent 4b709fa commit 918d111
Show file tree
Hide file tree
Showing 19 changed files with 182 additions and 30 deletions.
Expand Up @@ -43,7 +43,7 @@ class BasicHeaderedACTabScrollViewController: HeaderedACTabScrollViewController,

addChildViewController(vc)
subPageViews.append(vc.view)
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
}

self.navBarColor = .green
Expand Down
Expand Up @@ -39,7 +39,7 @@ class BasicHeaderedCAPSPageMenuViewController: HeaderedCAPSPageMenuViewControlle

addChildViewController(vc)
subPageControllers.append(vc)
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
}

let parameters: [CAPSPageMenuOption] = [
Expand Down
Expand Up @@ -30,7 +30,7 @@ class CustomAnimationViewController: HeaderedCAPSPageMenuViewController, CAPSPag

addChildViewController(vc)
subPageControllers.append(vc)
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
}

let parameters: [CAPSPageMenuOption] = [
Expand Down
3 changes: 2 additions & 1 deletion Example/HeaderedTabScrollView/HNUserPageController.swift
Expand Up @@ -29,13 +29,14 @@ class HNUserPageController: HeaderedCAPSPageMenuViewController, CAPSPageMenuDele

self.headerView = head


var controllers: [UIViewController] = []
for i in 0 ..< tabsTexts.count {
let vc = PlaceholderViewController()
vc.placeholderContent = MockupData.subpagesContent[i]
vc.contentText.backgroundColor = #colorLiteral(red: 0.07159858197, green: 0.09406698495, blue: 0.1027848646, alpha: 1)
vc.contentText.textColor = .white
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }

vc.title = tabsTexts[i]
controllers.append(vc)
Expand Down
Expand Up @@ -43,7 +43,7 @@ class HaDExampleViewController: HeaderedACTabScrollViewController, ACTabScrollVi
let vc = PlaceholderViewController()
vc.placeholderContent = MockupData.subpagesContent[i]
self.addSubPage(vc: vc)
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
}

self.tabScrollView.defaultPage = 1
Expand Down
Expand Up @@ -7,6 +7,8 @@
//

import UIKit
import HeaderedTabScrollView

/// ViewController for a scrollable view intented to be used a as subpage of a HeaderedTabScrollView
class PlaceholderViewController: UIViewController, UITextViewDelegate {
var placeholderContent: String = "" {
Expand Down Expand Up @@ -40,6 +42,7 @@ class PlaceholderViewController: UIViewController, UITextViewDelegate {
}
var scrollDelegateFunc: ((UIScrollView)->Void)?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
//parentHeaderedTabScrollViewController?.pleaseScroll(scrollView)
if self.scrollDelegateFunc != nil {
self.scrollDelegateFunc!(scrollView)
}
Expand Down
2 changes: 1 addition & 1 deletion Example/HeaderedTabScrollView/WithoutNavBarExample.swift
Expand Up @@ -27,7 +27,7 @@ class WithoutNavBarExampleController: HeaderedACTabScrollViewController, ACTabSc
let vc = PlaceholderViewController()
vc.placeholderContent = MockupData.subpagesContent[i]
self.addSubPage(vc: vc)
vc.scrollDelegateFunc = self.pleaseScroll
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
}

}
Expand Down
2 changes: 1 addition & 1 deletion HeaderedTabScrollView.podspec
Expand Up @@ -11,7 +11,7 @@ A swift View-Controller managing a scrollable tab-based menu above a header. It
DESC

s.homepage = 'https://github.com/tsucres/HeaderedTabScrollView'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.screenshots = 'https://github.com/tsucres/HeaderedTabScrollView/raw/master/Screenshots/presentationImg.png'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Stéphane Sercu' => 'stefsercu@gmail.com' }
s.source = { :git => 'https://github.com/tsucres/HeaderedTabScrollView.git', :tag => s.version.to_s }
Expand Down
Expand Up @@ -105,9 +105,8 @@ open class AbstractHeaderedTabScrollViewController: UIViewController {
}


/**
The color of the items in the navigation bar (if any)
*/

/// The color of the items in the navigation bar (if any)
public var navBarItemsColor: UIColor = .white {
didSet {
if let navCtrl = self.navigationController {
Expand All @@ -116,6 +115,7 @@ open class AbstractHeaderedTabScrollViewController: UIViewController {
}
}

/// Color of the title in the navigation bar
public var navBarTitleColor: UIColor = .white {
didSet {
if let navCtrl = self.navigationController {
Expand Down
188 changes: 168 additions & 20 deletions README.md
@@ -1,28 +1,32 @@
# HeaderedTabScrollView

<!-- Gifs -->

## Description

A custom viewController managing a header + a tab-based view.


Crapy little UIKit control that add a scrollable header on top of an [ACTabScrollView](https://github.com/azurechen/ACTabScrollView). It's more a complete illustration of how to do it than a control to use "as is".
There are two versions available: one using an [ACTabScrollView](https://github.com/azurechen/ACTabScrollView) as the tab-based view and the other using a [PageMenu](https://github.com/PageMenu/PageMenu/)


I needed that for [my project] and though it could be useful to other people too since I struggled a bit to make it work right.
I needed that for a project and though it could be useful to other people too since I struggled a bit to make it work right.

The main idea of how this works is inspired by this [stackoverflow question](https://stackoverflow.com/questions/25374090/move-a-view-when-scrolling-in-uitableview).


![presentation6](Screenshots/presentation.gif)
![presentationX](Screenshots/iPhoneX.gif)
![Example HaD](Screenshots/HaDExample.gif)


## Installation

### Pod
Depending on which version (ACTabScrollView or PageMenu) you want to use, add one of the following line to your Podfile:

`pod 'HeaderedTabScrollView/ACTabScrollView'`
`pod 'HeaderedTabScrollView/ACTabScrollView', :git => 'https://github.com/tsucres/HeaderedTabScrollView.git'`

or

`pod 'HeaderedTabScrollView/PageMenu'`
`pod 'HeaderedTabScrollView/PageMenu', :git => 'https://github.com/tsucres/HeaderedTabScrollView.git'`

If you don't specify a subspec, the two versions will be installed.

Expand Down Expand Up @@ -54,25 +58,140 @@ First of all you have to subclass a `HeaderedACTabScrollViewController`.

To complete the configuration, you have to set the header view and to configure the ACTabScrollView. The later is accessible throug the property `tabScrollView`.

The whole thing should look something like this:
The whole thing should look to something like this:

```swift

class BasicHeaderedACTabScrollViewController: HeaderedACTabScrollViewController, ACTabScrollViewDelegate, ACTabScrollViewDataSource {

// ACTabScrollView content
var subPageViews: [UIView] = []
var subPageTitles = ["One", "Two", "Three"]

override func viewDidLoad() {
super.viewDidLoad()

// 1) Header init
self.headerView = // Your custom UIView
self.headerHeight = // ...

// 2) ACTabScrollView initialisation
for _ in 0 ..< subPageTitles.count {
let subPageVC = SubPageViewController() // your controller
subPageVC.// do want you want

addChildViewController(subPageVC)
subPageViews.append(subPageVC.view)

// TODO: link subPageVC.scrollviewDidScroll to self.pleaseScroll (see below)
}

// ACTabScrollView delegate & dataSource (optionnal)
self.tabScrollView.dataSource = self
self.tabScrollView.delegate = self

}
}
```


Finally, you have to call the method `pleaseScroll()` each time a subpage is scrolled. The easiest way to do it, is to override the `scrollViewDidScroll` method in each subpage to make it call the `pleaseScroll` method. In your subpage controller you would have something like:

```swift

class SubPageController: UIViewController, UIScrollViewDelegate {
weak var parentHeaderedTabScrollViewController: AbstractHeaderedTabScrollViewController?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.parentHeaderedTabScrollViewController?.pleaseScroll(scrollView)
}
}

class BasicHeaderedACTabScrollViewController: HeaderedACTabScrollViewController, ACTabScrollViewDelegate, ACTabScrollViewDataSource {
// ...
override func viewDidLoad() {
// ...
// For each subpageController:
vc.parentHeaderedTabScrollViewController = self
// ...
}
// ...
}
```

Another solution, instead of passing a reference to the `HeaderedTabScrollViewController` to the `SubPageController`, is to just pass the `pleaseScroll` method:

```swift
class SubPageController: UIViewController, UIScrollViewDelegate {
var scrollDelegateFunc: ((UIScrollView)->Void)?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
self.parentHeaderedTabScrollViewController?.pleaseScroll(scrollView)
}
}

class BasicHeaderedACTabScrollViewController: HeaderedACTabScrollViewController, ACTabScrollViewDelegate, ACTabScrollViewDataSource {
// ...
override func viewDidLoad() {
// ...
// For each subpageController:
vc.scrollDelegateFunc = { [weak self] in self?.pleaseScroll($0) }
// ...
}
// ...
}
```

For more details and a concrete example, check the [`BasicHeaderedACTabScrollViewController.swift`](HeaderedTabScrollView/BasicHeaderedACTabScrollViewController.swift) file.
For more details and a concrete example, check the [`BasicHeaderedACTabScrollViewController.swift`](Example/HeaderedTabScrollView/BasicHeaderedACTabScrollViewController.swift) file.

#### \w CAPSPageMenu

The process is basically the same as for an ACTabScrollView based controller. In this case you have to subclass a `HeaderedCAPSPageMenuViewController`.
The process is basically the same than for an ACTabScrollView based controller. The main difference is that you have to to subclass a `HeaderedCAPSPageMenuViewController`.

As in the previous case, you have to do 2 things to complete the configuration of the controller: set the header view and configure the `CAPSPageMenu`. After initialisation, the later is accessible through the `pageMenuController` property.

```swift
class BasicHeaderedCAPSPageMenuViewController: HeaderedCAPSPageMenuViewController, CAPSPageMenuDelegate {

// PageMenu content: init your controllers the way you want.
var subPageControllers: [UIViewController] = []
var subPageTitles = ["One", "Two", "Three"]

override func viewDidLoad() {
super.viewDidLoad()

// 1) Header init
self.headerView = // Your custom UIView
self.headerHeight = // ...

s
// 2) PageMenu initialisation
for _ in 0 ..< subPageTitles.count {
let subPageVC = SubPageViewController() // your controller
subPageVC.// do want you want

addChildViewController(subPageVC)
subPageControllers.append(subPageVC)

// TODO: link subPageVC.scrollviewDidScroll to self.pleaseScroll
}

let parameters: [CAPSPageMenuOption] = [
// see PageMenu doc
]
self.addPageMenu(menu: CAPSPageMenu(viewControllers: subPageControllers, frame: CGRect(x: 0, y: 0, width: pageMenuContainer.frame.width, height: pageMenuContainer.frame.height), pageMenuOptions: parameters))


// PageMenu delegate (optionnal)
self.pageMenuController!.delegate = self
}
}

```

As in the previous case, you have to do 2 things to complete the configuration of the controller: set the header view and configure the `CAPSPageMenu`

And finally, don't forget to link the `pleaseScroll` method with the `scrollviewDidScroll` method from all the subpage controllers. (see previous section).


For more details and a concrete example, check the [`BasicHeaderedCAPSPageMenuViewController.swift`](HeaderedTabScrollView/BasicHeaderedCAPSPageMenuViewController.swift) file.
For more details and a concrete example, check the [`BasicHeaderedCAPSPageMenuViewController.swift`](Example/HeaderedTabScrollView/BasicHeaderedCAPSPageMenuViewController.swift) file.



Expand All @@ -82,17 +201,34 @@ For more details and a concrete example, check the [`BasicHeaderedCAPSPageMenuVi

### TabBar style

Since the ACTabScrollView/PageMenu is accessible through the `tabScrollView` property, you can customise its apparence as you would normally in any other situation. Just check the respective documentations (ACTabscrollView & PageMenu) for more informations.
Since the ACTabScrollView/PageMenu is accessible through the `tabScrollView`/`pageMenuController` property, you can customise its apparence as you would normally in any other situation. Just check the respective documentations ([ACTabScrollView](https://github.com/azurechen/ACTabScrollView) & [PageMenu](https://github.com/PageMenu/PageMenu/)) for more informations.

### Colors

Some properties have been added to the `AbstractHeaderedTabScrollView` to make the gesture of the colors of the navBar and the header easier.

```swift
public var navBarTransparancy: CGFloat
public var navBarColor: UIColor
public var headerBackgroundColor: UIColor?
public var navBarItemsColor: UIColor
public var navBarTitleColor: UIColor

```

Those properties are particularly useful if you implement custom animations.



### More header animations according to the vertical position

By default, there are 3 effects that are implemented:

- the alpha of the navigation bar (to make it progressivelly appear as the tabScrollView is scrolled up);
- the alpha of the navigation bar (to make it progressively appear as the tabScrollView is scrolled up);
- the y position of the header (to create a parallax effect);
- the alpha of the header (to make it disapear as the tabScrollView is scrolled up).
- the alpha of the header (to make it disappear as the tabScrollView is scrolled up).

Those This is implemented in the `headerDidScroll` method:
Those are called from the `headerDidScroll` method (in `AbstractHeaderedTabScrollView `):

```swift
public func headerDidScroll(minY: CGFloat, maxY: CGFloat, currentY: CGFloat) {
Expand All @@ -102,15 +238,27 @@ public func headerDidScroll(minY: CGFloat, maxY: CGFloat, currentY: CGFloat) {
}
```

If you want to add other effects (that you create) or remove som of theme, just override this method.
If you want to add other effects (that you create) or remove some of them, just override this method.


Check the [`CustomAnimationViewController.swift`](Example/HeaderedTabScrollView/CustomAnimationViewController.swift) (in the `Example` folder) for a concrete example.

## Examples
![Example HaD](Screenshots/customAnim.gif)


## Internal structure of the project

- `HeaderedTabScrollView/Casses`
- `AbstractHeaderedTabScrollViewController.swift` : defines the main class of the project. You can't drectly use it though. You have to use one of its subclass.
- `HeaderedACTabScrollViewController.swift` : defines the subclass using a ACTabScrollView
- `HeaderedCAPSPageMenuViewController.swift`: defines the subclass using a PageMenu
- `Example`: 6 examples are implemented
- `WithoutNavBarExample.swift` : demonstrate the use of a `HeaderedACTabScrollViewController` without navigation bar.
- `BasicHeaderedACTabScrollViewController` : minimal implementation of a `HeaderedACTabScrollViewController`
- `BasicHeaderedCAPSPageMenuViewController.swift` : minimal implementation of a `HeaderedCAPSPageMenuViewController`
- `HNUserPageController.swift` : implementation of a user profile page using a ``
- `HaDExampleViewController` : another example using an `HeaderedACTabScrollViewController `

# TODO
- Add an effect (zoom, parallax) on the header when the subpage is pulled down.
- Support horizontal orientation
- Adapt for iPhone X (use Safe area)
- Support horizontal orientation
Binary file added Screenshots/CustomAnim.mov
Binary file not shown.
Binary file added Screenshots/HaDExample.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/HaDExample.mov
Binary file not shown.
Binary file not shown.
Binary file added Screenshots/HeaderedTabScrollview.mov
Binary file not shown.
Binary file added Screenshots/customAnim.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/iPhoneX.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/presentation.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Screenshots/presentationImg.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 918d111

Please sign in to comment.