Swapper
Swap between many different UIViews within your app quick and easy.
Android developer? Check out the Android version of Swapper!
What is Swapper?
You know those moments in your app when you have a UITableView
that has no rows to show? You know those moments when you perform a HTTP network request and you want to show a non-blocking loading view to the user? These are very common scenarios for mobile apps. Swapper is a UIView
that allows you to swap between a set of other UIView
s with just 1 line of code.
Why use Swapper?
- Swift API
- Lightweight. Zero dependencies.
- UI testing friendly.
- Setup with default values that should work for 95% of your use cases. Customizable for those other cases.
- Full test suite.
- Full documentation.
I recommend you check out 2 other libraries that work nicely with Swapper: Empty and PleaseHold.
Installation
Swapper is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'Swapper', '~> version-here'
Replace version-here
with: as this is the latest version at this time.
Getting started
- Create an instance of
SwapperView
in yourUIViewController
. You can do this with Storyboard by adding aUIView
to Storyboard and setting theUIView
class toSwapperView
, or create an instance in your Swift code:
let swapperView: SwapperView<ViewControllerSwapViews> = {
let view = SwapperView<ViewControllerSwapViews>()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
return view
}()
- Make sure to create the
UIView
s that you want to swap between. In this example, let’s assume that I created aUITableView
and aUIImageView
that I want to swap between.
In your UIViewController
, add your UIView
s to your SwapperView
:
import Swapper
// It's recommended to use emum for the identifier. It will prevent bugs by not worrying about typos.
// However, you can just as easily use `SwapperView<String>` or something similar.
enum ViewControllerSwapViews: String, CustomStringConvertible {
case imageView
case tableView
var description: String {
return rawValue
}
}
class ViewController: UIViewController {
let swapperView = SwapperView<ViewControllerSwapViews>()
override func viewDidLoad() {
super.viewDidLoad()
// `setSwappingViews` will remove all subviews from the SwapperView. Reset it.
swapperView.setSwappingViews([
(.imageView, myImageView),
(.tableView, myTableView)
], swapTo: .imageView) // `swapTo` is optional and is used to swap to one of the views after setting new swapping views.
}
}
Note: Swapper holds onto UIView
instances given with setSwappingViews()
as a weak reference. Keep your own strong reference to make sure the app is working.
Note: Swapper will update the AutoLayout constraints of the UIView
s you set as the swapping views. Swapper will set the size as the same size you set as the SwapperView
. Therefore, no need to set AutoLayout constraints on your own! If you’re not using AutoLayout, edit the configuration for SwapperView
to not update the constraints: SwapperView.defaultConfig.updateAutoLayoutConstraints = false
.
- Lastly, all you need to do is to tell Swapper to swap!
try! swapperView.swapTo(.tableView)
Swapper will now show the UITableView
for you. Swapper will even fade out the UIImageView
and fade in the UITbleView
for you for a nice touch 👌. If you want to override the default animation, you can override the behavior yourself:
SwapperView.defaultConfig.swapToAnimateOldView = { oldView in
// Run `UIView.animate()` function here on `oldView` to animate it out.
}
SwapperView.defaultConfig.swapToAnimateNewView = { newView in
// Run `UIView.animate()` function here on `newView` to animate it in.
}
Note: .swapTo()
will thrown an error if the id passed in was not given in .setSwappingViews()
. Or, the view you passed in has been garbage collected. Swapper only keeps weak references to given UIView
s.
Configure Swapper
Swapper works great without any configuration necessary. However, if you wish to customize it yourself, you can.
If you want to change the default values of all instances of SwapperView
in your app, change the values in the default singleton:
SwapperView.defaultConfig.transitionAnimationDuration = 0.8
Or, you can configure 1 single instance of SwapperView
:
let swapperView = SwapperView()
var instanceConfig: SwapperViewConfig {
let config = SwapperViewConfig()
config.backgroundColor = instanceConfigBackgroundColor
return config
}
swapperView.config = instanceConfig
For a list of all the configuration options, view the docs on SwapperViewConfig
Testing with Swapper
If you want to write tests for your app and include Swapper in it, it’s highly recommended to disable animations.
UIView.setAnimationsEnabled(false)
Done! Swapper inherits this property and will enable or disable animations with this setting.
Example
Swapper comes with an example app you can use to play with the library. To run the example project, clone the repo, and run pod install
from the Example directory first. Then, open the workspace in XCode.
Development
Swapper is a pretty simple CocoaPods library project. Follow the directions below for the optimal development experience.
- Install cocoapods/gems and setup workspace:
$> bundle install
$> cd Swapper/Example
$> pod install
$> brew install swiftformat
$> brew install swiftlint
- Setup git hooks to run misc tasks for you when using git.
$> brew install pre-commit
$> ./hooks/autohook.sh install
The git hook scripts are installed in hooks/
. View them if you wish.
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Contribute
Swapper is open for pull requests. Check out the list of issues for tasks I am planning on working on. Check them out if you wish to contribute in that way.
Want to add features to Swapper? Before you decide to take a bunch of time and add functionality to the library, please, create an issue stating what you wish to add. This might save you some time in case your purpose does not fit well in the use cases of Swapper.
License
Swapper is available under the MIT license. See the LICENSE file for more info.