StickyFooterScrollView is a lightweight and powerful Swift library that simplifies the creation of UIScrollView with a sticky footer. It eliminates the complexity of manually setting up constraints and provides an intuitive API for creating scrollable content with persistently visible footer elements.
When creating UIScrollView in iOS development, developers often struggle with:
- Complex constraint management for scroll views
- Sticky footer implementation that remains visible during scrolling
- Content layout calculations for proper scrolling behavior
- Boilerplate code repetition across projects
StickyFooterScrollView solves these problems by providing a simple, declarative API that handles all the complexity internally.
- π§ Simple Setup: Initialize with just one line of code
- π Sticky Footer: Footer remains visible at the bottom while content scrolls
- π± Auto Layout: Automatic constraint handling and layout management
- π¨ Flexible Content: Support for any UIView as content and footer
- βοΈ Customizable: Configurable spacing and padding options
- π Performance Optimized: Efficient scrolling and memory management
- π¦ Easy Integration: CocoaPods support with minimal setup
- iOS: 11.0+
- Swift: 5.0+
- Xcode: 11.0+
CocoaPods is the recommended way to install StickyFooterScrollView. Add the following line to your Podfile
:
pod 'StickyFooterScrollView'
Then run:
pod install
- Download the project
- Drag and drop the
StickyFooterScrollView
folder into your Xcode project - Make sure to add it to your target
import StickyFooterScrollView
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupScrollView()
}
private func setupScrollView() {
// 1. Create StickyFooterScrollView
let scrollView = StickyFooterScrollView(minimumFooterTopOffset: 24)
// 2. Add to parent view
view.addSubview(scrollView)
// 3. Setup constraints
scrollView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
scrollView.topAnchor.constraint(equalTo: view.topAnchor),
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
])
// 4. Setup content and footer
setupContent(scrollView)
setupFooter(scrollView)
}
}
let scrollView = StickyFooterScrollView(minimumFooterTopOffset: 24)
The minimumFooterTopOffset
parameter defines the minimum spacing between the content and the footer.
Create your main content and add it to the scroll view:
private func setupContent(_ scrollView: StickyFooterScrollView) {
// Create a stack view for organizing content
let mainContentView = UIStackView()
mainContentView.axis = .vertical
mainContentView.spacing = 16
// Add your content elements
let imageView = UIImageView(image: UIImage(named: "hero_image"))
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
mainContentView.addArrangedSubview(imageView)
let titleLabel = UILabel()
titleLabel.text = "Welcome to Our App"
titleLabel.font = UIFont.boldSystemFont(ofSize: 24)
titleLabel.textColor = .black
titleLabel.textAlignment = .center
mainContentView.addArrangedSubview(titleLabel)
let descriptionLabel = UILabel()
descriptionLabel.text = "Experience the power of StickyFooterScrollView for creating beautiful, scrollable interfaces with persistent footer elements."
descriptionLabel.font = UIFont.systemFont(ofSize: 16)
descriptionLabel.textColor = .gray
descriptionLabel.numberOfLines = 0
descriptionLabel.textAlignment = .center
mainContentView.addArrangedSubview(descriptionLabel)
// Apply content view with padding
scrollView.applyContentView(
mainContentView,
with: UIEdgeInsets(top: 24, left: 24, bottom: 24, right: 24)
)
}
Create your footer content (typically buttons or actions):
private func setupFooter(_ scrollView: StickyFooterScrollView) {
// Create footer container
let footerContainer = UIStackView()
footerContainer.axis = .vertical
footerContainer.spacing = 12
// Primary action button
let primaryButton = UIButton(type: .system)
primaryButton.setTitle("Get Started", for: .normal)
primaryButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
primaryButton.setTitleColor(.white, for: .normal)
primaryButton.backgroundColor = .systemBlue
primaryButton.layer.cornerRadius = 12
primaryButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
// Secondary action button
let secondaryButton = UIButton(type: .system)
secondaryButton.setTitle("Learn More", for: .normal)
secondaryButton.titleLabel?.font = UIFont.systemFont(ofSize: 16)
secondaryButton.setTitleColor(.systemBlue, for: .normal)
secondaryButton.backgroundColor = .clear
secondaryButton.layer.borderWidth = 1
secondaryButton.layer.borderColor = UIColor.systemBlue.cgColor
secondaryButton.layer.cornerRadius = 12
secondaryButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
footerContainer.addArrangedSubview(primaryButton)
footerContainer.addArrangedSubview(secondaryButton)
// Apply footer view with padding
scrollView.applyFooterView(
footerContainer,
with: UIEdgeInsets(top: 16, left: 24, bottom: 24, right: 24)
)
}
In your viewDidAppear
method, call updateLayout()
to ensure proper constraint setup:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
scrollView.updateLayout()
}
You can customize the spacing and padding for both content and footer:
// Content with custom padding
scrollView.applyContentView(
contentView,
with: UIEdgeInsets(top: 32, left: 16, bottom: 32, right: 16)
)
// Footer with custom padding
scrollView.applyFooterView(
footerView,
with: UIEdgeInsets(top: 20, left: 20, bottom: 40, right: 20)
)
You can update the content dynamically:
func updateContent() {
let newContentView = createDynamicContent()
scrollView.applyContentView(newContentView, with: standardPadding)
scrollView.updateLayout()
}
Create sophisticated footer layouts with multiple elements:
private func createComplexFooter() -> UIView {
let container = UIView()
container.backgroundColor = UIColor.systemBackground
// Add shadow
container.layer.shadowColor = UIColor.black.cgColor
container.layer.shadowOffset = CGSize(width: 0, height: -2)
container.layer.shadowRadius = 4
container.layer.shadowOpacity = 0.1
// Add your complex layout here
// ...
return container
}
- Always call
updateLayout()
inviewDidAppear
for proper constraint setup - Use UIStackView for organizing content to leverage auto layout
- Set proper height constraints for footer elements to ensure consistent appearance
- Consider safe area insets when setting up the scroll view constraints
- Test on different device sizes to ensure responsive design
To run the example project:
- Clone the repository
- Navigate to the Example directory
- Run
pod install
- Open the
.xcworkspace
file - Build and run the project
StickyFooterScrollView is perfect for:
- Onboarding screens with persistent action buttons
- Product detail pages with add-to-cart buttons
- Forms with submit buttons always visible
- Terms and conditions with accept/decline buttons
- Article readers with sharing options
- E-commerce product listings with checkout buttons
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add some amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- Make sure to call
updateLayout()
inviewDidAppear
for proper layout - When updating content dynamically, always call
updateLayout()
afterward
If you encounter any issues or have questions:
- Check the Issues page
- Create a new issue with detailed information
- Contact the maintainer at thinhnguyen12389@gmail.com
- The iOS developer community for inspiration and feedback
- Contributors who help improve the library
- Developers who test and provide valuable feedback
StickyFooterScrollView is available under the MIT license. See the LICENSE file for more information.
fanta1ty
- GitHub: @fanta1ty
- Email: thinhnguyen12389@gmail.com
Made with β€οΈ for the iOS development community
If this library helps you in your projects, please consider giving it a βοΈ on GitHub!