Scrollable UINavigationBar that follows the scrolling of a UIScrollView

Overview

CocoaPods Build status Carthage compatible Swift 5 Join the chat at https://gitter.im/andreamazz/AMScrollingNavbar Donate

A custom UINavigationController that enables the scrolling of the navigation bar alongside the scrolling of an observed content view

Versioning notes

  • Version 2.x is written as a subclass of UINavigationController, in Swift.
  • Version 2.0.0 introduced Swift 2.0 syntax.
  • Version 3.0.0 introduced Swift 3.0 syntax.
  • Version 4.0.0 introduced Swift 4.0 syntax.
  • Version 5.1.0 introduced Swift 4.2 syntax.

If you are looking for the category implementation in Objective-C, make sure to checkout version 1.x and prior, although the 2.x is recomended.

Screenshot

Setup with CocoaPods

pod 'AMScrollingNavbar'

use_frameworks!

Setup with Carthage

github "andreamazz/AMScrollingNavbar"

Usage

Make sure to use ScrollingNavigationController instead of the standard UINavigationController. Either set the class of your UINavigationController in your storyboard, or create programmatically a ScrollingNavigationController instance in your code.

Use followScrollView(_: delay:) to start following the scrolling of a scrollable view (e.g.: a UIScrollView or UITableView).

Swift

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if let navigationController = navigationController as? ScrollingNavigationController {
        navigationController.followScrollView(tableView, delay: 50.0)
    }
}

Objective-C

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [(ScrollingNavigationController *)self.navigationController followScrollView:self.tableView delay:0 scrollSpeedFactor:1 collapseDirection:NavigationBarCollapseDirectionScrollDown followers:nil];
}

Use stopFollowingScrollview() to stop the behaviour. Remember to call this function on disappear:

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    if let navigationController = navigationController as? ScrollingNavigationController {
        navigationController.stopFollowingScrollView()
    }
}

ScrollingNavigationViewController

To DRY things up you can let your view controller subclass ScrollingNavigationViewController, which provides the base setup implementation. You will just need to call followScrollView(_: delay:):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    if let navigationController = navigationController as? ScrollingNavigationController {
        navigationController.followScrollView(tableView, delay: 50.0)
    }
}

Followers

To move another view, like a toolbar, alongside the navigation bar you can provide the view or multiple views as the followers parameter. Since you might want to have the follower up or down, you'll have to specify the scroll direction of the view once it starts to follow the navigation bar:

if let navigationController = navigationController as? ScrollingNavigationController {
    navigationController.followScrollView(tableView, delay: 50.0, followers: [NavigationBarFollower(view: customFooter, direction: .scrollDown)])
}

Note that when navigating away from the controller the followers might keep the scroll offset. Refer to Handling navigation for proper setup.

Additional scroll

If you want to furhter scroll the navigation bar out of the way, you can use the optional parameter additionalOffset in the followScrollView call.

Scrolling the TabBar

You can also pass a UITabBar in the followers array:

if let navigationController = navigationController as? ScrollingNavigationController {
    navigationController.followScrollView(tableView, delay: 50.0, followers: [tabBarController.tabBar])
}

ScrollingNavigationControllerDelegate

You can set a delegate to receive a call when the state of the navigation bar changes:

if let navigationController = navigationController as? ScrollingNavigationController {
    navigationController.scrollingNavbarDelegate = self
}

Delegate function:

func scrollingNavigationController(_ controller: ScrollingNavigationController, didChangeState state: NavigationBarState) {
    switch state {
    case .collapsed:
        print("navbar collapsed")
    case .expanded:
        print("navbar expanded")
    case .scrolling:
        print("navbar is moving")
    }
}

Handling navigation

If the view controller with the scroll view pushes new controllers, you should call showNavbar(animated:) in your viewWillDisappear(animated:):

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    if let navigationController = navigationController as? ScrollingNavigationController {
      navigationController.showNavbar(animated: true)
    }
}

Scrolling to top

When the user taps the status bar, by default a scrollable view scrolls to the top of its content. If you want to also show the navigation bar, make sure to include this in your controller:

func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
    if let navigationController = navigationController as? ScrollingNavigationController {
        navigationController.showNavbar(animated: true, scrollToTop: true)
    }
    return true
}

Scroll speed

You can control the speed of the scrolling using the scrollSpeedFactor optional parameter:

controller.followScrollView(view, delay: 0, scrollSpeedFactor: 2)

Check out the sample project for more details.

Changing UINavigationBar.tintColor

AMScrollingNavBar maintains its own copy of the UINavigationBar's tintColor property. You need to notify the AMScrollingNavBar of a tint change by calling navBarTintUpdated():

navigationBar.tintColor = UIColor.red
controller.navBarTintUpdated()

Check out the sample project for more details.

Author

Andrea Mazzini. I'm available for freelance work, feel free to contact me.

Want to support the development of these free libraries? Buy me a coffee ☕️ via Paypal.

Contributors

Syo Ikeda and everyone kind enough to submit a pull request.

MIT License

The MIT License (MIT)

Copyright (c) 2014-2019 Andrea Mazzini

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Comments
  • Stange white bar

    Stange white bar

    Hello, This is how I'm integrating the AMScrollingNavBar :

    -(void)viewWillAppear:(BOOL)animated{
        [self setUseSuperview:YES];
        [self followScrollView:self.collectionView ];
        [self.collectionView reloadData];
    
    }
    
    - (void)viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
        [self showNavBarAnimated:NO];
    }
    - (void)dealloc
    {
        [self stopFollowingScrollView];
    }
    

    So The problem that when I set this view as the start view I got strange white bar like this one : sans titre

    and When I refresh this view or I don't set it as rootView It work fine and the white bar is not appearing

    bug help wanted 
    opened by chlebta 39
  • After scroll, the scrollview inset is wrong

    After scroll, the scrollview inset is wrong

    Hi, I am using this in a UIViewController, as a child view controller of a uitabbarcontroller. After scroll, the tableView (root view in UITableviewController) will have an offset below the navigation bar. The extra space is about the height of the navigation bar. From Xcode, if I uncheck the Adjust Scroll View Insets checkbox for the view controller, the extra space will disappear after scroll, but the content section will go under the nav bar before the scroll.

    To repro this, go with the instruction video, but after embedding the UIViewController with a navigation controller, connect this navigation controller to a UITabbarController. I am using the latest version 1.0, installed via cocoapod.

    awaiting feedback 
    opened by yichen 37
  • Release 2.0.10 deployment target should be iOS 8.0

    Release 2.0.10 deployment target should be iOS 8.0

    I rememeber 2.0.9 is target iOS 8.0. but 2.0.10 is target iOS 8.4. Module file's minimum deployment target is ios8.4 v8.4: /App/AMScrollingNavbar.framework/Modules/AMScrollingNavbar.swiftmodule/x86_64.swiftmodule

    opened by strong84 25
  • What if no IBOutlet?

    What if no IBOutlet?

    What if I programatically made a UITableViewController. There is no View where I can connect an IBOutlet for tableView, therefore

    [self followScrollView:self.tableView]; --> will not work for me... how can I call this method in my case?

    opened by bobi33 23
  • If the tableView has the header, the header does not move with the cell content

    If the tableView has the header, the header does not move with the cell content

    I had a tableView with two different kinds of cells, one for section header, one for the content. The content cell move correctly, however the header cell stuck there until the header of next section come up and push it away.

    help wanted 
    opened by becarefullee 18
  • Update ScrollingNavigationController.swift

    Update ScrollingNavigationController.swift

    Support Objective-c with Swift 4

    At the moment your project is not supporting objective c with swift 4 that is really bad for my project. For more information take a look of this: http://evgenii.com/blog/disabling-swift3-objc-inference-in-xcode9/

    Functions like this are not working: [((ScrollingNavigationController *)self.navigationController) followScrollView: tableView delay:(0.0) scrollSpeedFactor:1.0 followers:followers];

    Please accept the pull request to enable objective c with swift4. thanks

    opened by alejouribesanchez 17
  • Black Bar on scroll (when pushing a view with a search controller in navigation bar)

    Black Bar on scroll (when pushing a view with a search controller in navigation bar)

    The navbar scrolls perfectly on first load. When I navigate away using a ViewController from another storyboard, and then return with a back button, I get the issue with a black bar:

    screen shot 2015-12-21 at 11 04 24 am

    The black bar corrects itself when scrolling up.

    EDIT: See better description below of issue below

    stale 
    opened by Errortype520 17
  • [beta] Release 2.0.0-beta5

    [beta] Release 2.0.0-beta5

    The library was rewritten in Swift, as a subclass of UINavigationController. This version contains major breaking changes.
    Moving from a category to a subclass cleaned up the code quite a bit, making it more maintainable and hopefully less fragile. It also fully supports translucent navbars now.

    I'm closing all current Issues, please test this new version if you can, your feedback is important and always welcome. If this version does not fix your issue encountered in 1.5 and previous, please feel free to reopen the issue.

    This is a work in progress, I ported most of the features, but some of them are missing:

    • [X] test with UITableViewControllers
    • [X] improved documentation
    • [X] improved demo project
    • [X] delegate methods
    • [ ] test coverage (as of #131)
    • [ ] floating header

    I'm going to keep track of the new changes and bugs here.

    The version 1.x won't be maintained in the future, for now I'll create a new branch, v1.x, for hotfixes.

    Thank you all for your contribution and feedback.

    opened by andreamazz 17
  • Sticky Followers Handling

    Sticky Followers Handling

    Added the sticky followers request https://github.com/andreamazz/AMScrollingNavbar/issues/291

    See in video how it works https://streamable.com/3dhtj

    Made a branch with the example as shown from the video: https://github.com/Alexookah/AMScrollingNavbar/tree/sticky-followers (simply do pod install to get my repo's master branch code)

    This is tested using: UINavigationBar.appearance().isTranslucent = false

    Currently its pretty simple handling. Each follower is checking the previous followers height. This could be changed into some more customizable setup with some followers to be fully hidden or not.

    I think this might be useful for some people like i needed this :)

    Hope my implementation is good enough for merge. Feel free to tell me if something needs to be changed.

    opened by alexookah 15
  • Nav Bar gets Black when Scrolling

    Nav Bar gets Black when Scrolling

    Thanks for the library. I've been using AMScrollingNavbar successfully for the last period of time. However, now I added support for empty views using this library: DZNEmptyDataSet*. By doing this, whenever I show an empty view, then load some data in the table, the navigation bar gets black when scrolling. Whenever it finishes scrolling (it fully disappears or appears), everything gets back to normal. Any ideas?

    Normal Navigation Bar: 033999ec-5640-11e6-99e4-d3afc8806a62

    Navigation Bar When Scrolling: 031405f6-5640-11e6-9fce-c4b829398164

    stale 
    opened by florinzf 14
  •  UITableViewController

    UITableViewController "out of box" install yields black gap

    Hi, thanks for this great library. :+1:

    I couldn't find any documentation on using the project with UITableViewController, and when I use it with a table view controller "out of the box":

    [self followScrollView:self.tableView]

    there is a 64px gap added to the frame as soon as I start scrolling.

    1. How do I get rid of that gap?
    2. Since this is likely the most common integration scenario, it seems like documentation should exist for this.
    wontfix 
    opened by dmur 14
  • Not Able to Scroll Up to the Top after Scrolling Down in iOS 15+

    Not Able to Scroll Up to the Top after Scrolling Down in iOS 15+

    Describe the bug Im currently running the latest sample app from master. After scrolling down the Table view if we scroll up again we are unable to see the top most rows.

    To Reproduce Steps to reproduce the behavior:

    1. Run the sample App from this repo on an iOS Device Running 15+
    2. Scroll Down for 20 rows and scroll up again
    3. Observe error

    This issue Happens in collection view example as well

    Expected behavior We should be able to see the Top Most rows

    Screenshots Attaching a Video

    https://user-images.githubusercontent.com/58021031/143550230-47fafa41-07ad-4c8b-87ee-1ba9278734cb.mp4

    opened by jenixgnanadhas 1
  • UITabbarController show space above navigationbar ios15

    UITabbarController show space above navigationbar ios15

    Describe the bug When adding UITbbarController in viewcontroller stack of AMScrollNavBar.The top space does'nt go away.

    To Reproduce Steps to reproduce the behavior:

    1. Adding tabbarcontroller to navigation bar like this self.navigationController?.viewControllers = [UIStoryboard.main.instantiateViewController(withIdentifier: TabbarViewController.className)] and navigationcontroller is ScrollingNavigationViewController.
    2. Child controllers of tabbarcontroller shows space above navigationbar.
    3. I'm using ios version 15.Xcode version 13.1.Macos version 11.6

    Expected behavior These top space should not be visible.

    Screenshots simulator_screenshot_26D60CA4-6983-4DCF-AE15-365842E38082

    opened by mmdHussain 0
  • No more scrolling with iOS 15.1

    No more scrolling with iOS 15.1

    This can be reproduced with the demo app running iOS 15.1 (screen capture)

    https://user-images.githubusercontent.com/150367/139125055-b5a61d02-5b0f-40c2-9071-fdb729dc3d02.mov

    opened by tifroz 10
  • Navigation bar background color changing

    Navigation bar background color changing

    Describe the bug I updated from version 5.6.1 to 5.7.2 and I now have a scrolling nav bar that change color after scrolling or navigating to another controller. Note that my nav bar has it's color set using appearance at the beginning of the app, but somehow it changes from white to grey. This bug was probably introduced by #392 or #399.

    To Reproduce Steps to reproduce the behavior:

    1. Set the background/tint color of all UINavigationBar to a light color using appearance when the app starts
    2. Make a controller with a scrollview that has a dark background color and a scrolling nav bar on top
    3. Start the app and scroll to reduce the nav bar and scroll to top again or push an other view controller and come back

    Expected behavior The color of the scrolling nav bar should stay the same

    opened by Okizeme 6
  • Container navigation controller breaks bar

    Container navigation controller breaks bar

    Seems that if I use a navigation controller as a child view controller, the scroll does not appear to work as expected:

    Screen Capture on 2020-08-14 at 09-40-06-2

    CHECKOUT OPTIONS:
      AMScrollingNavbar:
        :commit: 37743f772b6a5e1328285d295b38cc400ff82d1e
        :git: https://github.com/andreamazz/AMScrollingNavbar.git
    
    opened by markst 3
Releases(5.3.0)
Owner
Andrea Mazzini
💻 Software Engineer 🌲 Woodworker
Andrea Mazzini
A UINavigationBar extension to show loading effects

BusyNavigationBar A UINavigationBar extension to show loading effects above navigation bar's background. Screenshot Stripes Bars Your custom layer Usa

Günay Mert Karadoğan 992 Dec 3, 2022
A UINavigationController subclass that support pop interactive UINavigationbar with hidden or show.

KDInteractiveNavigationController Features ✨ UINavigationController interactive with UINavigationBar hidden or show Hide all UINavigationController ba

Kingiol 154 Dec 3, 2022
An easy way to change backgroundColor of UINavigationBar when Push & Pop

RainbowNavigation 中文介绍 Feature RainbowNavigation is written in Swift 2.0. It helps you change the backgroundColor of UINavigationBar in animations and

danisfabric 789 Dec 3, 2022
iOS UI library to show and hide an extension to your UINavigationBar

ADNavigationBarExtension is a UI library written in Swift. It allows you to show and hide an extension to your UINavigationBar Features Use Extensible

FABERNOVEL 58 Aug 29, 2022
Scrollable UINavigationBar that follows the scrolling of a UIScrollView

A custom UINavigationController that enables the scrolling of the navigation bar alongside the scrolling of an observed content view Versioning notes

Andrea Mazzini 6.1k Jan 6, 2023
ScrollingFollowView is a simple view which follows UIScrollView scrolling.

ScrollingFollowView ScrollingFollowView is a simple view which follows UIScrollView scrolling. ScrollingFollowView Sample Images SearchBarSample : Sea

Tanaka Kenji 186 Dec 21, 2022
CrownControl is a tiny accessory that makes scrolling through scrollable content possible without lifting your thumb.

CrownControl Overview Features Example Project Requirements Installation Usage Quick Usage Crown Attributes Scroll Axis Anchor Position Spin Direction

Daniel Huri 96 Dec 27, 2022
A container view that responds to scrolling of UIScrollView

FlexibleHeader A container view that responds to scrolling of UIScrollView. normal threshold FlexibleHeaderExecutantType Getting Started Progressive I

DongHee Kang 69 May 2, 2022
Give pull-to-refresh & infinite scrolling to any UIScrollView with 1 line of code.

SVPullToRefresh + SVInfiniteScrolling These UIScrollView categories makes it super easy to add pull-to-refresh and infinite scrolling fonctionalities

Sam Vermette 4.9k Dec 1, 2022
Multi-tier UIScrollView nested scrolling solution. 😋😋😋

Multi-tier UIScrollView nested scrolling solution. Snapshots Requirements iOS 9.0+ Xcode 10.0+ Swift 4.2+ Installation CocoaPods CocoaPods is a depend

Jiar 1.2k Dec 30, 2022
A UINavigationController subclass that support pop interactive UINavigationbar with hidden or show.

KDInteractiveNavigationController Features ✨ UINavigationController interactive with UINavigationBar hidden or show Hide all UINavigationController ba

Kingiol 154 Dec 3, 2022
Zingle – An alert will display underneath your UINavigationBar 🎅

Zingle Zingle – An alert will display underneath your UINavigationBar ?? ?? Note: Zingle has a dependency to have a UINavigationController in your app

Hemang 109 Jun 24, 2022
UINavigationBar Category which allows you to change its appearance dynamically

Deprecated This lib uses a hacky way to achieve the result, in the new iOS version, the structure of UINavigation is changed and this lib no longer wo

Leo 4.5k Dec 3, 2022
A UINavigationBar extension to show loading effects

BusyNavigationBar A UINavigationBar extension to show loading effects above navigation bar's background. Screenshot Stripes Bars Your custom layer Usa

Günay Mert Karadoğan 992 Dec 3, 2022
A UINavigationController subclass that support pop interactive UINavigationbar with hidden or show.

KDInteractiveNavigationController Features ✨ UINavigationController interactive with UINavigationBar hidden or show Hide all UINavigationController ba

Kingiol 154 Dec 3, 2022
An easy way to change backgroundColor of UINavigationBar when Push & Pop

RainbowNavigation 中文介绍 Feature RainbowNavigation is written in Swift 2.0. It helps you change the backgroundColor of UINavigationBar in animations and

danisfabric 789 Dec 3, 2022
iOS UI library to show and hide an extension to your UINavigationBar

ADNavigationBarExtension is a UI library written in Swift. It allows you to show and hide an extension to your UINavigationBar Features Use Extensible

FABERNOVEL 58 Aug 29, 2022
An adaptive scrollable graph view for iOS to visualise simple discrete datasets. Written in Swift.

ScrollableGraphView Announcements 9-7-2017 - Version 4: Version 4 was released which adds multiple plots, dynamic reloading of values, more reference

Phillip 5.3k Jan 5, 2023
Core Charts | Basic Scrollable Chart Library for iOS

Core Charts | Basic Chart Library for iOS HCoreBarChart VCoreBarChart Requirements Installation Usage Appearance Customization Getting Started You nee

Çağrı ÇOLAK 71 Nov 17, 2022
Light and scrollable view controller for tvOS to present blocks of text

TvOSTextViewer Light and scrollable view controller for tvOS to present blocks of text Description TvOSTextViewer is a view controller to present bloc

David Cordero 45 Oct 27, 2022