How to limit a variable in Swift
No Clamping in the Swift Standard Library?!
Over the years, I’ve had a few instances where I needed to limit the potential of a variable. For instance, maybe I have a shopping app and I need to limit the maximum price of any given item. You may be surprised to learn that there’s no built-in way to tackle this in the Swift Standard Library. There are many solutions, but most come with glaring caveats.
Let’s start with a use-case
I have a UICollectionView. In this collectionView, I only want to display a maximum of 2 cells. This collection view’s count is based on an array that could have thousands of entries. How do I limit how many cells I display?
Create a FIFO Queue
This is an option — and a good one for memory-sake. But it comes with some extra work, and we ain't got time for that! Essentially, we’d remove the oldest entry from the collection every time we append one once the collection’s count reaches 2.
Also, what if we want to pass this data around our app and don’t want to modify the collection we’re using, and also don’t want to create a copy?
Just return 2 in numberOfItemsInSection
Well, we could do this, but the problem is the collection may not have 2 items to display. What I really want to do is return up to 2 cells, but respect the number in the collection up to that amount.
Now, let’s see what other people are doing, shall we?
When I’m not sure where to start, I usually take a trip over to the good old Google machine, which often leads me to StackOverflow. Today is no different. I came across this post which has a plethora of ideas, all of them centered around the same line of code:
This essentially says: “Don’t go below the lower range, and don’t go above the upper range”… but it comes with a glaring issue. It’s not limited to a closed range, and using an open range will allow you to go out of bounds by 1. There are many other solutions on the page, but I focused on the one using a property wrapper because property wrappers tend to keep things cleaner than using other methods. In addition, the property wrapper syntax draws attention to what you’re defining because it’s not used very often by the majority. In a case like this, I think the extra attention is a good thing.
You may notice that this solution takes care of a couple of edge cases. For one, it doesn’t allow us to use an open range, since
range is typed as a
ClosedRange. There’s also a precondition checking to see if the value we’re attempting to set is in the range we’ve defined.
So, if we implement this property wrapper and use it in the example I talked about above, we can easily limit how many items are displayed from our collection without modifying the collection:
NOTE: You’ll need to create a cell with the identifier “id” and link an outlet to the collectionView you’re using in your project
It may not be in Swift’s Standard Library, but
@Clamping sure is part of my standard library!
Have you come across other solutions to this problem that you’d like to share? Drop them in the comments!