Ribbon šŸŽ€
  • March 11, 2024

A simple cross-platform toolbar/custom input accessory view library for iOS & macOS.
Written in Swift.


Looking for…

  • A type-safe, XPC-availableĀ SourceKittenĀ (SourceKit) interface with some sugar? Check outĀ Sylvester 😼.
  • A Floating Action Button for macOS? Check outĀ Fab.Ā šŸ›ļø.
  • An Expanding Bubble Text Field for macOS? Check outĀ BubbleTextFieldĀ šŸ’¬.
  • An integrated spotlight-based onboarding and help library for macOS? Check outĀ EnlightenĀ šŸ’”.

Features


šŸŽ”Ā Try:Ā Includes an iOS & macOS demo.

  • Provide items either programmatically or from a JSON configuration file.
  • Dark mode.
  • + more!

iOS

  • Supports push buttons—a segmented item’s subitems become push buttons.

  • iOS 13:Ā actionĀ items use the newĀ context menu interaction:

    Note:Ā Due to an internal assertion, the keyboard can no longer remain visible during the interaction.

    macOS

    • Supports push,Ā action, & segmented control toolbar items.
    • ProvidesĀ NSMenuItems for each item.

    Requirements


    • iOS 10.0+ (12.0+ for dark mode)
    • macOS 10.12+ (10.13+ for full functionality)

    Installation


    RibbonĀ is available for installation using Carthage or CocoaPods.

github “chriszielinski/Ribbon”

CocoaPods

pod “Ribbon”

Usage


There are two ways of integratingĀ RibbonĀ into your project:

Configuration File


šŸ”„ The recommended approach.

The configuration file makes for a quick & easy integration. The default configuration filename isĀ ribbon-configuration.jsonĀ and should be copied into the target’s bundle resources (in theĀ Copy Bundle ResourcesĀ build phase).

The JSON below defines a single action item and toolbar configuration—which is only relevant for the macOS platform.

🧐 See: Demos/Shared/ribbon-configuration.json for a more comprehensive example.

{
“items”: [
{
“action”: “actionItemHandler”,
“controlKind”: “action”,
“identifier”: “action-item-identifier”,
“imageName”: “NSActionTemplate”,
“keyEquivalent”: “a”,
“keyEquivalentModifier”: [“command”, “shift”],
“title”: “Action Item”,
“toolTip”: “The action button’s tool-tip.”,
“subitems”: [
{
“action”: “firstActionSubitemHandler”,
“identifier”: “first-action-subitem”,
“imageName”: “hand.thumbsup”,
“keyEquivalent”: “1”,
“keyEquivalentModifier”: [“command”],
“title”: “First Action Subitem”,
“toolTip”: “The first action’s tool-tip.”
},
{
“action”: “secondActionSubitemHandler”,
“identifier”: “second-action-subitem”,
“imageName”: “hand.thumbsdown”,
“keyEquivalent”: “2”,
“keyEquivalentModifier”: [“command”],
“title”: “Second Action Subitem”,
“toolTip”: “The second action’s tool-tip.”
}
]
}
],
“toolbar”: {
“displayMode”: “iconOnly”,
“sizeMode”: “regular”,
“identifier”: “toolbar-identifier”,
“defaultItems” : [“NSToolbarFlexibleSpaceItem”, “action-item-identifier”]
}
}

Integration into your view controller is as simple as:

šŸ“ŒĀ Note:Ā The code below is an abstraction andĀ will notĀ compile.

import Ribbon

class YourViewController … {

var ribbon: Ribbon!

override func viewDidLoad() {
ribbon = try! Ribbon.loadFromMainBundle(target: self)

#if canImport(UIKit)
textView.inputAccessoryView = ribbon
#endif
}

#if canImport(AppKit)
override func viewWillAppear() {
view.window?.toolbar = ribbon.toolbar

super.viewWillAppear()
}
#endif

@objc
func actionItemHandler() { }

@objc
func firstActionSubitemHandler() { }

@objc
func secondActionSubitemHandler() { }

}

Programmatically


šŸ“ŒĀ Note:Ā The code below is an abstraction andĀ will notĀ compile.

import Ribbon

class YourViewController … {

var ribbon: Ribbon!

override func viewDidLoad() {
let firstActionSubitem = RibbonItem(subItemTitle: “First Action Subitem”)
firstActionSubitem.action = #selector(firstActionSubitemHandler)
let secondActionSubitem = RibbonItem(subItemTitle: “Second Action Subitem”)
secondActionSubitem.action = #selector(secondActionSubitemHandler)

let actionItem = RibbonItem(controlKind: .action,
title: “Action Item”,
subitems: [firstActionSubitem, secondActionSubitem])
actionItem.action = #selector(actionItemHandler)
ribbon = Ribbon(items: [actionItem], target: self)

#if canImport(UIKit)
textView.inputAccessoryView = ribbon
#endif
}

#if canImport(AppKit)
override func viewWillAppear() {
view.window?.toolbar = ribbon.toolbar

super.viewWillAppear()
}
#endif

@objc
func actionItemHandler() { }

@objc
func firstActionSubitemHandler() { }

@objc
func secondActionSubitemHandler() { }

}

// ToDo:


  • Ā Add documentation.
  • Ā ImplementĀ UIKeyCommand.

Community


  • Found a bug? Open anĀ issue.
  • Feature idea?Ā Open anĀ issue.Ā Do it yourself & PR when done šŸ˜… (or you can open an issue šŸ™„).
  • Want to contribute? Submit aĀ pull request.

Acknowledgements


Contributors


Frameworks & Libraries


RibbonĀ depends on the wonderful contributions of the Swift community, namely:

GitHub


View Github

#carthage #cocoapods #ios #swift #toolbar
YOU MIGHT ALSO LIKE...
MijickPopups Hero

  Popups Alerts Resizable Sheets Banners

SwiftUI Tooltip

This package provides you with an easy way to show tooltips over any SwiftUI view, since Apple does not provide ...

SimpleToast for SwiftUI

SimpleToast is a simple, lightweight, flexible and easy to use library to show toasts / popup notifications inside iOS or ...

SSToastMessage

Create Toast Views with Minimal Effort in SwiftUI Using SSToastMessage. SSToastMessage enables you to effortlessly add toast notifications, alerts, and ...

ToastUI

A simple way to show toast in SwiftUI   Getting Started • Documentation • Change Log Ā Ā