HGPlaceholders
Nice library to show placeholders and Empty States for any UITableView/UICollectionView in your project
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
- 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
}
}
}
- Showing a loading placeholder:
tableView.showLoadingPlaceholder()
- 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()
- 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
-
Install HGPlaceholders via CocoaPods by adding to your Podfile:
pod 'HGPlaceholders'
-
Import the library in your Swift file:
import HGPlaceholders
-
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 } }
-
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 designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
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.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
- Inherit your UITableView class from TableView Or inherit UICollectionView from CollectionView
- Call the placeholder to show
tableView.showLoadingPlaceholder()
orcollectionView.showLoadingPlaceholder()
tableView.showNoResultsPlaceholder()
orcollectionView.showNoResultsPlaceholder()
tableView.showErrorPlaceholder()
orcollectionView.showErrorPlaceholder()
tableView.showNoConnectionPlaceholder()
orcollectionView.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.
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
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot