Animated top menu for UITableView / UICollectionView / UIScrollView written in Swift

Overview

Persei

Build Status License

Preview

Animated top menu for UITableView / UICollectionView / UIScrollView written in Swift!

Made in Yalantis.

Check this project on Dribbble

Check this project on Behance

Supported Swift versions

Swift Version Persei
1.x 1.1
2.x 2.0
3.x 3.0
4.x 3.1
5.x 4.0

Installation

CocoaPods

use_frameworks!

pod 'Persei', '~> 4.0'

Carthage

github "Yalantis/Persei" ~> 4.0

Manual Installation

For application targets that do not support embedded frameworks, such as iOS 7, Persei can be integrated by including source files from the Persei folder directly, optionally wrapping the top-level types into struct Persei to simulate a namespace. Yes, this sucks.

  1. Add Persei as a submodule by opening the Terminal, cd-ing into your top-level project directory, and entering the command git submodule add https://github.com/yalantis/Persei.git
  2. Open the Persei folder, and drag Persei.xcodeproj into the file navigator of your app project.
  3. In Xcode, navigate to the target configuration window by clicking on the blue project icon, and selecting the application target under the "Targets" heading in the sidebar.
  4. Ensure that the deployment target of Persei.framework matches that of the application target.
  5. In the tab bar at the top of that window, open the "Build Phases" panel.
  6. Expand the "Target Dependencies" group, and add Persei.framework.
  7. Expand the "Link Binary With Libraries" group, and add SideMenu.framework
  8. Click on the + button at the top left of the panel and select "New Copy Files Phase". Rename this new phase to "Copy Frameworks", set the "Destination" to "Frameworks", and add Persei.framework.

Usage

Import Persei module

import Persei

Init

let menu = MenuView()    
tableView.addSubview(menu)

Configuring items

In order to set items you need to instantiate array of MenuItem:

let items = feedModes.map { mode: SomeYourCustomFeedMode -> MenuItem in
	return MenuItem(image: mode.image)
}

menu.items = items

Handling selection

You can specify selected item manually:

menu.selectedIndex = 3

Note, that selectedIndex declared as Int? and will be nil in case of menu.items = nil.

Also, you can implement MenuViewDelegate to be notified about selection change:

// during init
menu.delegate = self

// actual implementation
extension FeedViewController: MenuViewDelegate {
    func menu(menu: MenuView, didSelectItemAt index: Int) {
    	dataSource.mode = feedModes[index] // alter mode of dataSource

    	tableView.reload() // update tableView
    }
}

Reveal menu manually

Menu can be reveal as a result of button tap:

func menuButtonSelected(sender: UIControl) {
	menu.revealed = !menu.revealed

	// or animated
	menu.setRevealed(true, animated: true)
}

Content Gravity

Use contentViewGravity to control sticking behavior. There are 3 available options:

  • Top: contentView sticked to the top position of the view
  • Center: contentView is aligned to the middle of the streched view
  • Bottom: contentView sticked to the bottom

Customization

MenuItem declares set of attributes, that allow you to customize appearance of items:

struct MenuItem {
    var image: UIImage // default image
    var highlightedImage: UIImage? // image used during selection

    var backgroundColor: UIColor // default background color
    var highlightedBackgroundColor: UIColor // background color used during selection

    var shadowColor: UIColor // color of bottom 2px shadow line
}

Also you're free to configure background of MenuView by utilizing backgroundColor or backgroundImage. Note, that image should be resizeable:

let menu = MenuView()
menu.backgroundImage = UIImage(named: "top_menu_background")

Advanced customization

  • Can I place the UIImageView instead?
  • Sure! Just subclass / use StickyHeaderView directly. It offers layout, positioning and reveal control. All you have to do is to assign your custom view (animated nian-cat UIImageView) to contentView:
let headerView = StickyHeaderView()
let imageView = UIImageView(...)

headerView.contentView = imageView

Obviously, your custom view can have heigh different from default:

headerView.contentHeight = image.size.height

As well as control distance to trigger open/close of the header:

headerView.threshold = 0.5

Threshold is a float value from 0 to 1, specifies how much user needs to drag header for reveal.

Let us know!

We’d be really happy if you sent us links to your projects where you use our component. Just send an email to [email protected] And do let us know if you have any questions or suggestion regarding the animation.

P.S. We’re going to publish more awesomeness wrapped in code and a tutorial on how to make UI for iOS (Android) better than better. Stay tuned!

License

The MIT License (MIT)

Copyright © 2017 Yalantis

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.
Issues
  • Unfortunately not runnning on XCode7/Swift2

    Unfortunately not runnning on XCode7/Swift2

    Any chnace for a fix for this nice little menu...?

    opened by headkit 9
  • Menu Position error after upgrade to ios 11.0.3

    Menu Position error after upgrade to ios 11.0.3

    Run the example project and this happens:

    img_2431

    opened by Derek-X-Wang 8
  • No interaction on item click using iOS 7 iPhone 5 simulator

    No interaction on item click using iOS 7 iPhone 5 simulator

    Hello,

    First of all, thanks you for this project.

    I'm using Persei on my app and it works fine on iOS 8. However, the "didSelectRow" doesn't seems to work on iOS 7. It reveal normally the menu but there is no action when clicking on items.

    Do you have an idea about this problem ?

    Edited: The items thumbnails are also reduced.

    opened by Aymenworks 6
  • Turn bounces off without removing the menu.

    Turn bounces off without removing the menu.

    I was wondering if there was a way to turn bounces off in the tableView without stopping the Persei menu from appearing?

    opened by ArthurU 5
  • Crashes on Device.

    Crashes on Device.

    This is crashing in device but running fine in simulator , i also checked in your Example project but its also crashing in Example app when using with device, I am using 10.0.2 (iPhone 6s) Xcode 8.0 .

    Error: - fatal error: unexpectedly found nil while unwrapping an Optional value (Menu View is nil always)

    opened by ErAbhishekChandani 4
  • NSInternalInconsistencyException - UITableView was deallocated while key value observers were still registered with it.

    NSInternalInconsistencyException - UITableView was deallocated while key value observers were still registered with it.

    I have a TableViewController that uses Persei. I push the TableViewController when I select a button on my starting view. When I hit the back button in the navigation bar I get the following error:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance of class UITableView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x7fd003571060> ( <NSKeyValueObservance 0x7fd003576350: Observer: 0x7fd00370e800, Key path: contentOffset, Options: <New: YES, Old: NO, Prior: NO> Context: 0x103111190, Property: 0x7fd00378e3a0>

    It looks like in StickyHeaderView is setting the observer here:

    public weak var scrollView: UIScrollView! {
        willSet {
            self.scrollView?.removeObserver(self, forKeyPath: "contentOffset", context: &ContentOffsetContext)
            self.scrollView?.panGestureRecognizer.removeTarget(self, action: "handlePan:")
    
            appliedInsets = UIEdgeInsetsZero
        }
    
        didSet {
            scrollView?.addObserver(self, forKeyPath: "contentOffset", options: .Initial | .New, context: &ContentOffsetContext)
            scrollView?.panGestureRecognizer.addTarget(self, action: "handlePan:")
        }
    }
    

    How can I fix this issue? Thanks!

    opened by rankinit 4
  • Unable to update to 3.0 with cocoapods

    Unable to update to 3.0 with cocoapods

    Hi!

    I'm trying to update the Persei pod with cocoapods to use swift 3.0, in my Podfile I've added this line, like the readme file describes:

    use_frameworks! 
    
    pod 'Persei', '~> 3.0'
    

    but I've this error

    [!] Unable to satisfy the following requirements:
    
    - `Persei (~> 3.0)` required by `Podfile`
    - `Persei (~> 3.0)` required by `Podfile`
    
    None of your spec sources contain a spec satisfying the dependency: `Persei (~> 3.0)`.
    
    You have either:
     * out-of-date source repos which you can update with `pod repo update`.
     * mistyped the name or version.
     * not added the source repo that hosts the Podspec to your Podfile.
    

    What can I do?

    Thanks! \m

    opened by mrigo 3
  • Swift 1.2 Xcode 6.3 -Missing argument for parameter 'coder' in call

    Swift 1.2 Xcode 6.3 -Missing argument for parameter 'coder' in call

    Persei-master/Example/Example/Controllers/ViewController.swift:23:28: Missing argument for parameter 'coder' in call

    opened by Rollersway 3
  • setRevealed throwing as nil optional

    setRevealed throwing as nil optional

    When I attempt to set the revealed state, the initialized MenuView returns as a nil optional.

    My code

    // TableViewController properties
    var picker: MenuView {
        let m = MenuView()
        // Init other options and add items
        return m
    }
    // -----------------------
    override func viewWillAppear(animated: Bool) {
        picker.setRevealed(true, animated: true)
    }
    

    I have also tried setting m.revealed when initializing the property. I get the same error every time

    Also good to note that this TVC is sometimes a child VC and sometimes not

    priority: medium status: queued type: enhancement 
    opened by MatrixSenpai 3
  • Keeping menu collectionview top to of tableview at all times

    Keeping menu collectionview top to of tableview at all times

    I noticed that if you pull the collectionview down further it will move down. Is there a way to lock the menu collectionview so it stays on the top regardless?

    opened by johnamcruz 3
  • equal spacing

    equal spacing

    Report

    If I have less than 4 icons they all get aligned to the left How can I align them with equal spacing?

    ⚠️ Select what you want - a feature request or report a bug. Please remove the section you aren't interested in.

    A feature request

    What do you want to add?

    Please describe what you want to add to the component.

    How should it look like?

    Please add images.

    Report a bug

    What did you do?

    Please replace this with what you did.

    What did you expect to happen?

    Please replace this with what you expected to happen.

    What happened instead?

    Please replace this with what happened instead.

    Your Environment

    • Version of the component: insert here
    • Swift version: insert here
    • iOS version: insert here
    • Device: insert here
    • Xcode version: insert here
    • If you use Cocoapods: run pod env | pbcopy and insert here
    • If you use Carthage: run carthage version | pbcopy and insert here

    Project that demonstrates the bug

    Please add a link to a project we can download that reproduces the bug.

    opened by galblank 0
  • Scroll from Bot to Top

    Scroll from Bot to Top

    A feature request

    Hi Guys ! I would like to know if it's possible to inverse menu fade-in ? For example if I scroll from bot to top, the menu appear on the bot of my tableview.

    status: pending type: enhancement 
    opened by Ze-ro-G 1
Releases(3.1.1)
Owner
Yalantis
Knowledge is power and the way to get power is by sharing knowledge. We are open source because this is a smart way to live, work and play.
Yalantis
Nice library to show placeholders and Empty States for any UITableView/UICollectionView in your project

HGPlaceholders Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 8.0+ Xcode 9

Hamza Ghazouani 2.1k Jan 13, 2022
🚴 A declarative library for building component-based user interfaces in UITableView and UICollectionView.

A declarative library for building component-based user interfaces in UITableView and UICollectionView. Declarative Component-Based Non-Destructive Pr

Ryo Aoyama 1.1k Jan 4, 2022
A UICollectionViewLayout subclass displays its items as rows of items similar to the App Store Feature tab without a nested UITableView/UICollectionView hack.

CollectionViewShelfLayout A UICollectionViewLayout subclass displays its items as rows of items similar to the App Store Feature tab without a nested

Pitiphong Phongpattranont 374 Dec 29, 2021
WLEmptyState is an iOS based component that lets you customize the view when the dataset of a UITableView or a UICollectionView is empty. We created a sample project with the WLEmptyState component to show how you can use it.

Table of Content Overview Running an Example Project Installing WLEmptyState Configuring WLEmptyState Using WLEmptyState Customizing WLEmptyState Cont

Wizeline 311 Nov 23, 2021
Elissa displays a notification on top of a UITabBarItem or any UIView anchor view to reveal additional information.

Elissa Attach a local notification to any UIView to reveal additional user guidance. Usage Example Per default, Elissa will try to align to the center

null 167 Dec 8, 2021
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 2, 2022
A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView and iPhone X safe area support for content reloading. Built for iOS 10 and later.

Arale A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView support for reloading your content. Built f

Putra Z. 42 Nov 10, 2021
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 66 Nov 10, 2021
Simple parallax header for UIScrollView

MXParallaxHeader ⚠️ This project is no longer maintained, see #124 ⚠️ MXParallaxHeader is a simple header class for UIScrollView. In addition, MXScrol

Maxime Epain 1.6k Dec 23, 2021
↕️ VegaScroll is a lightweight animation flowlayout for UICollectionView completely written in Swift 4, compatible with iOS 11 and Xcode 9.

Made by Applikey Solutions Find this project on Dribbble Also check another flowlayout for UICollectionView: https://github.com/ApplikeySolutions/Grav

Applikey Solutions 2.7k Jan 14, 2022
iOS Slide Menu View based on Google+, iQON, Feedly, Ameba iOS app. It is written in pure swift.

SlideMenuControllerSwift iOS Slide View based on iQON, Feedly, Google+, Ameba iPhone app. Installation CocoaPods pod 'SlideMenuControllerSwift' Carth

Yuji Hato 3.3k Jan 3, 2022
iOS Interactive Side Menu written in Swift.

Interactive Side Menu A customizable, interactive, auto expanding and collapsing side menu for iOS written in Swift. Here are some of the ways Interac

Handsome 708 Dec 31, 2021
A simple side menu for iOS written in Swift.

ENSwiftSideMenu A lightweight flyover side menu component for iOS with the UIDynamic's bouncing animation, UIGestures and UIBlurEffect. Allows you to

Evgeny Nazarov 1.8k Jan 6, 2022
Cool Animated music indicator view written in Swift

Cool Animated music indicator view written in Swift. ESTMusicIndicator is an implementation of NAKPlaybackIndicatorView in Swift for iOS 8. 本人著作的书籍《La

Aufree 455 Dec 13, 2021
Beautiful animated Alert View. Written in Swift

SCLAlertView Animated Alert View written in Swift, which can be used as a UIAlertView or UIAlertController replacement. Since UIAlertView is deprecate

Viktor Radchenko 5.2k Jan 11, 2022
Cute Animated Button written in Swift.

DOFavoriteButton Cute Animated Button written in Swift. It could be just right for favorite buttons! Requirements iOS 7.0+ Swift 1.2 Installation Cart

Daiki Okumura 3.5k Jan 10, 2022
A set of cool animated page controls written in Swift to replace boring UIPageControl. Mady by @ChiliLabs - https://chililabs.io

CHIPageControl CHIPageControl is a set of cool animated page controls to replace boring UIPageControl. We were inspired by Jardson Almeida dribbble sh

Chili Labs 2.9k Jan 12, 2022
Live animated Alert View for iOS written in Swift

Sweet Alert iOS Beautiful Animated custom Alert View inspired from javascript library SweetAlert. Written in Swift this SweetAlertView can be used in

Sahil 2k Dec 13, 2021
Animated Social share buttons control for iOS written in Swift

SwiftShareBubbles Animated Social share buttons control for iOS written in Swift. This library is inspired AAShareBubbles. I tried AAShareBubbles with

Takeshi Fujiki 172 Nov 24, 2021