Convert Figma logo to code with AI

HamzaGhazouani logoHGPlaceholders

Nice library to show placeholders and Empty States for any UITableView/UICollectionView in your project

2,199
159
2,199
24

Top Related Projects

☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting

A collection of awesome loading animations

A showcase of the many different styles of windows possible with NSWindow on macOS

Quick Overview

HGPlaceholders is a Swift library for iOS that provides customizable placeholder views for empty states, loading, and error scenarios in UITableView and UICollectionView. It offers a simple and elegant way to enhance user experience by displaying informative and visually appealing placeholders when content is not available or still loading.

Pros

  • Easy integration with existing UITableView and UICollectionView implementations
  • Highly customizable placeholder views with support for images, titles, and subtitles
  • Smooth animations for transitioning between different placeholder states
  • Supports both Swift and Objective-C projects

Cons

  • Limited to UITableView and UICollectionView, not applicable to other UI components
  • Requires additional setup and configuration compared to using default empty states
  • May increase app size due to additional resources for placeholder views
  • Documentation could be more comprehensive for advanced customization

Code Examples

  1. Basic setup for a UITableView:
class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.placeholderDelegate = self
    }
}

extension ViewController: HGPlaceholderTableViewDelegate {
    func view(for state: HGPlaceholderState, in tableView: UITableView) -> UIView? {
        switch state {
        case .loading:
            return LoadingView()
        case .noResults:
            return EmptyStateView()
        default:
            return nil
        }
    }
}
  1. Showing a loading placeholder:
tableView.showLoadingPlaceholder()
  1. Customizing placeholder appearance:
let customView = UIView()
customView.backgroundColor = .lightGray
let label = UILabel()
label.text = "No data available"
customView.addSubview(label)

tableView.customPlaceholder = customView
tableView.showNoResultsPlaceholder()
  1. Handling placeholder tap events:
extension ViewController: HGPlaceholderTableViewDelegate {
    func placeholderTableView(_ tableView: UITableView, didTapPlaceholderButton button: UIButton) {
        // Handle tap event, e.g., retry loading data
        loadData()
    }
}

Getting Started

  1. Install HGPlaceholders via CocoaPods by adding to your Podfile:

    pod 'HGPlaceholders'
    
  2. Import the library in your Swift file:

    import HGPlaceholders
    
  3. Set up your view controller to conform to the placeholder delegate:

    class ViewController: UIViewController, HGPlaceholderTableViewDelegate {
        @IBOutlet weak var tableView: UITableView!
        
        override func viewDidLoad() {
            super.viewDidLoad()
            tableView.placeholderDelegate = self
        }
        
        func view(for state: HGPlaceholderState, in tableView: UITableView) -> UIView? {
            // Return custom views for different placeholder states
        }
    }
    
  4. Use placeholder methods as needed:

    tableView.showLoadingPlaceholder()
    tableView.showNoResultsPlaceholder()
    tableView.removePlaceholder()
    

Competitor Comparisons

☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting

Pros of SkeletonView

  • More customizable appearance with gradient animations and multiline text support
  • Better integration with UIKit and SwiftUI
  • Actively maintained with frequent updates and bug fixes

Cons of SkeletonView

  • Steeper learning curve due to more complex API
  • May have a slightly higher performance overhead for complex layouts
  • Limited built-in placeholder types compared to HGPlaceholders

Code Comparison

SkeletonView:

view.isSkeletonable = true
view.showSkeleton()

HGPlaceholders:

tableView.placeholdersProvider = .default
tableView.showPlaceholder()

Both libraries offer simple ways to add placeholder views, but SkeletonView requires setting the isSkeletonable property before showing the skeleton. HGPlaceholders provides a more straightforward approach with built-in placeholder types.

SkeletonView offers more customization options:

view.showAnimatedGradientSkeleton(usingGradient: .init(colors: [.blue, .purple]))

While HGPlaceholders focuses on predefined placeholder styles:

tableView.placeholdersProvider = .custom(CustomPlaceholderProvider())

Overall, SkeletonView provides more flexibility and customization options, while HGPlaceholders offers a simpler API with ready-to-use placeholder types.

A collection of awesome loading animations

Pros of NVActivityIndicatorView

  • Offers a wide variety of animated loading indicators (over 30 types)
  • Highly customizable with options for size, color, and animation speed
  • Lightweight and easy to integrate into existing projects

Cons of NVActivityIndicatorView

  • Limited to loading indicators, lacks placeholder views for other content types
  • May require additional code for managing different loading states
  • Not designed for handling empty states or error messages

Code Comparison

NVActivityIndicatorView:

let activityIndicator = NVActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40), type: .ballPulse, color: .white, padding: 0)
view.addSubview(activityIndicator)
activityIndicator.startAnimating()

HGPlaceholders:

tableView.placeholdersProvider = PlaceholdersProvider(
    placeholders: [
        .noResults(title: "No Results", subtitle: "Try a different search term", action: nil),
        .error(title: "Error", subtitle: "Something went wrong", action: nil)
    ]
)
tableView.showLoadingPlaceholder()

NVActivityIndicatorView focuses on providing various loading animations, while HGPlaceholders offers a more comprehensive solution for managing different view states, including loading, empty, and error states. HGPlaceholders is better suited for handling multiple placeholder scenarios in table views and collection views, whereas NVActivityIndicatorView excels in creating visually appealing loading indicators for general use throughout an app.

A showcase of the many different styles of windows possible with NSWindow on macOS

Pros of NSWindowStyles

  • Focuses specifically on macOS window styling, providing a comprehensive collection of window customization options
  • Includes visual examples and screenshots for each window style, making it easier for developers to choose the desired look
  • Offers a wider range of window customization options, including titlebar appearances, traffic light button styles, and more

Cons of NSWindowStyles

  • Limited to macOS development, whereas HGPlaceholders is cross-platform (iOS and tvOS)
  • Lacks built-in placeholder functionality for loading states or error handling
  • Requires more manual implementation compared to the ready-to-use components in HGPlaceholders

Code Comparison

NSWindowStyles:

let window = NSWindow(contentRect: .zero, styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: .buffered, defer: false)
window.titlebarAppearsTransparent = true
window.titleVisibility = .hidden
window.styleMask.insert(.fullSizeContentView)

HGPlaceholders:

tableView.placeholdersProvider = PlaceholdersProvider(
    placeholders: [.noResults, .error, .loading],
    dataSource: self,
    delegate: self
)

The code snippets demonstrate the different focus areas of each library, with NSWindowStyles concentrating on window customization and HGPlaceholders on managing placeholder views for various states in table and collection views.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

HGPlaceholders

Backers on Open Collective Sponsors on Open Collective CI Status Version License Language Supports Platform

Twitter: @GhazouaniHamza codebeat badge Documentation Readme Score

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

Requirements

  • iOS 8.0+
  • Xcode 9.2

You also may like

  • HGCircularSlider - A custom reusable circular slider control for iOS application.
  • HGRippleRadarView - A beautiful radar view to show nearby users with ripple animation, fully customizable

Installation

HGPlaceholders is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'HGPlaceholders'

HGPlaceholders is also available through Carthage. To install it, simply add the following line to your Cartfile:

github "HamzaGhazouani/HGPlaceholders"

Usage

  1. Inherit your UITableView class from TableView Or inherit UICollectionView from CollectionView
  2. Call the placeholder to show
  • tableView.showLoadingPlaceholder() or collectionView.showLoadingPlaceholder()
  • tableView.showNoResultsPlaceholder() or collectionView.showNoResultsPlaceholder()
  • tableView.showErrorPlaceholder() or collectionView.showErrorPlaceholder()
  • tableView.showNoConnectionPlaceholder() or collectionView.showNoConnectionPlaceholder()

Customization

If you want to change only images, just set them in your asset with this names (the framework check firstly in the main bundle):

  • loading : "hg_default-loading"
  • no_connection : "hg_default-no_connection"
  • no_results : "hg_default-no_results"
  • error : "hg_default-error"

The framework contains different defaults placeholders:

  • Basic :

tableView.placeholdersProvider = .basic or collectionView.placeholdersProvider = .basic

  • Default :

tableView.placeholdersProvider = .default or collectionView.placeholdersProvider = .default

  • Default2 :

tableView.placeholdersProvider = .default2 or collectionView.placeholdersProvider = .default2

  • Hallowen :

tableView.placeholdersProvider = .halloween or collectionView.placeholdersProvider = .halloween // for fun :)`

If you want to change the default palceholders for all table views in your project:

class ProjectNameTableView: TableView {

    override func customSetup() {
        placeholdersProvider = .basic
    }
}
class ProjectNameCollectionView: CollectionView {

    override func customSetup() {
        placeholdersProvider = .basic
    }
}

You can also add new placeholders fully customizable, you should keep in mind that the view will take table view frame, and placeholder can have only one action, please check the example project

Creating a new theme from scratch

static var summer: PlaceholdersProvider {
        
        var commonStyle = PlaceholderStyle()
        commonStyle.backgroundColor = UIColor(red: 1.0, green: 236.0/255, blue: 209.0/255.0, alpha: 1.0)
        commonStyle.actionBackgroundColor = .black
        commonStyle.actionTitleColor = .white
        commonStyle.titleColor = .black
        commonStyle.isAnimated = false
        
        commonStyle.titleFont = UIFont(name: "AvenirNextCondensed-HeavyItalic", size: 19)!
        commonStyle.subtitleFont = UIFont(name: "AvenirNextCondensed-Italic", size: 19)!
        commonStyle.actionTitleFont = UIFont(name: "AvenirNextCondensed-Heavy", size: 19)!
        
        var loadingStyle = commonStyle
        loadingStyle.actionBackgroundColor = .clear
        loadingStyle.actionTitleColor = .gray
        
        var loadingData: PlaceholderData = .loading
        loadingData.image = #imageLiteral(resourceName: "summer-hat")
        let loading = Placeholder(data: loadingData, style: loadingStyle, key: .loadingKey)
        
        var errorData: PlaceholderData = .error
        errorData.image = #imageLiteral(resourceName: "summer-ball")
        let error = Placeholder(data: errorData, style: commonStyle, key: .errorKey)
        
        var noResultsData: PlaceholderData = .noResults
        noResultsData.image = #imageLiteral(resourceName: "summer-cocktail")
        let noResults = Placeholder(data: noResultsData, style: commonStyle, key: .noResultsKey)
        
        var noConnectionData: PlaceholderData = .noConnection
        noConnectionData.image = #imageLiteral(resourceName: "summer-beach-slippers")
        let noConnection = Placeholder(data: noConnectionData, style: commonStyle, key: .noConnectionKey)
        
        let placeholdersProvider = PlaceholdersProvider(loading: loading, error: error, noResults: noResults, noConnection: noConnection)
        
        let xibPlaceholder = Placeholder(cellIdentifier: "CustomPlaceholderCell", key: PlaceholderKey.custom(key: "XIB"))
        
        placeholdersProvider.add(placeholders: xibPlaceholder)
        
        return placeholdersProvider
    }

Adding a custom placeholder to an existing theme

   private static var starWarsPlaceholder: Placeholder {
       var starwarsStyle = PlaceholderStyle()
       starwarsStyle.backgroundColor = .black
       starwarsStyle.actionBackgroundColor = .clear
       starwarsStyle.actionTitleColor = .white
       starwarsStyle.titleColor = .white
       starwarsStyle.isAnimated = false
       
       var starwarsData = PlaceholderData()
       starwarsData.title = NSLocalizedString("\"This is a new day, a\nnew beginning\"", comment: "")
       starwarsData.subtitle = NSLocalizedString("Star Wars", comment: "")
       starwarsData.image = #imageLiteral(resourceName: "star_wars")
       starwarsData.action = NSLocalizedString("OK!", comment: "")
       
       let placeholder = Placeholder(data: starwarsData, style: starwarsStyle, key: PlaceholderKey.custom(key: "starWars"))
       
       return placeholder
   }
   
   let provider = PlaceholdersProvider.summer 
   provider.addPlaceholders(MyUtilityClass.starWarsPlaceholder) 

Documentation

Full documentation is available on CocoaDocs.
You can also install documentation locally using jazzy.

Author

Hamza Ghazouani, hamza.ghazouani@gmail.com

License

HGPlaceholders is available under the MIT license. See the LICENSE file for more info.