You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I’ve been diving into iOS for the past month building an app for my startup. One of the things I want the app to do is to let the user swipe a cell in a table view to reveal more options (similar to how the Mail app reveals “More” and “Delete” options). In this article I will discuss a few way of doing this, including how to build it yourself.
Hopefully, if you’re looking for swipeable table view cells, you’ll find what you need in one of the above solutions. But then why am I writing about how to build it yourself? In my case, I needed some of the functionality of MGSwipeTableCell, but it turned out to do things in ways that didn’t work for me. If you’re also looking to build it from scratch, or just want to know how it works, read on!
Making a table view cell swipeable is actually pretty simple. The gist of it is to create a UIScrollView inside the cell’s contentView and then populate it with one UIView for the buttons and one UIView for the content. The hardest part is really configuring the scroll view. Here’s an image showing the main values we’ll be touching on the UIScrollView:
The size of the view (the actual area that will be rendered on screen). In the picture above I gave it more height to make room for the labels, but in our code it will have the same height as the content.
52
-
contentSize
53
-
In scroll views, the content will often be a different size than the view itself. When content is bigger than the view, the view will scroll to let the user see all of the content. This property represents the width and height of the content inside of the scroll view. In our case, we’ll actually keep it the same size as the view, thanks to a property called contentInset.
54
-
contentInset
55
-
This is the property that will make our scroll view actually scroll. Normally, when the contentSize property is set to the same (or smaller) size as the view itself, the view won’t scroll. However, contentInset will extend the area that is scrollable outside the content, so that you can scroll past the content boundary. Why is this useful? It’s used by pull-to-refresh controls, for example, to allow a throbber to show above the content. In our case, we’ll use it to make room for revealing the buttons.
56
-
contentOffset
57
-
This is the value that represents how much the scroll view is currently scrolled. As the user scrolls around, this value will change. You can also change it programmatically, which we’ll do later to snap the scrolling to just where the buttons end.
Since we’ll want to have control over scroll behaviors, we need to specify that our class supports the UIScrollViewDelegate protocol. Do this by adding the protocol in angle brackets after the interface declaration:
Next up, we’ll set up the scroll view. This is done when the cell initializes. Depending on how you create your cells, the cell may initialize in either initWithCoder: or initWithStyle:reuseIdentifier:. I would recommend creating a common method for setting up your cell and calling it from both places.
There’s a few things happening here after we create the scroll view. First, we set its resizing mask. This means how the view will act when its super view changes size. We want the scroll view to fill the entire cell when it changes size at runtime (which is likely to happen with iPhone 5, 6 and 6 Plus all having different screen widths). Then we set the content size to be the same, but also add a left inset with the width of the buttons we intend to add. Setting scrollsToTop to be turned off means this scroll view doesn’t care about the status bar being tapped (which normally scrolls a view to the top). This’ll let our table view take care of that instead of breaking that behavior. We also turn off horizontal and vertical scroll indicators so that the little translucent black bar doesn’t appear when we scroll.
Nothing really surprising going on above, we’re just adding in the necessary parts for presenting the main area of the table cell (which is normally in the contentView).
This creates a view which contains the action buttons. The important things to note here is that the view has the same width as all the buttons together, and it’s inserted as the first view in the hierarchy (which will make it appear under everything else). Then we just add the buttons we want there. I didn’t add tap handlers to keep the example short.
174
-
175
-
If you run the app now, it should let you scroll to make the button appear. If you’re running this on an iPhone 6 or larger you may notice a glitch that we’ll fix later. Another thing missing is the snapping in place of the button being either visible or not visible when you stop scrolling. Let’s fix that now.
@@ -190,12 +145,6 @@ If you run the app now, it should let you scroll to make the button appear. If y
190
145
191
146
```
192
147
193
-
When your class gets notified that the user has stopped swiping (via the UIScrollViewDelegate protocol), you make the scroll view scroll back to either exactly where the buttons end (if they swiped past the buttons), or back to hide the buttons completely (if they didn’t swipe far enough).
194
-
195
-
That’s pretty much the basics of building a swipeable cell! We’ve got a few loose ends that we’ll tie up now, so keep reading.
196
-
197
-
The biggest problem with our code right now is handling of bigger screens (such as iPhone 6). We can fix that with this simple “hack” (please let me know if this can be done better!)
@@ -214,8 +163,6 @@ The biggest problem with our code right now is handling of bigger screens (such
214
163
215
164
```
216
165
217
-
That’ll avoid graphical glitches. Next up, we may want to prevent the cell from being scrollable in the other direction (which doesn’t have any buttons to show). That’s simple:
@@ -228,8 +175,6 @@ That’ll avoid graphical glitches. Next up, we may want to prevent the cell fro
228
175
}
229
176
```
230
177
231
-
Finally, you may want the buttons to stay in place under the cell instead of moving with the cell content. To make that happen, we will simply move the buttons container view to counteract the scrolling offset. We’ll do this by changing the scrollViewDidScroll: method above to the following:
@@ -245,20 +190,6 @@ Finally, you may want the buttons to stay in place under the cell instead of mov
245
190
246
191
```
247
192
248
-
Where to go from here
249
-
Now that we’ve gone through the basics there’s many things that can still be improved. Here’s a few:
250
-
251
-
Auto-hiding buttons when scrolling the table view
252
-
Auto-hiding buttons when swiping open another cell
253
-
Allowing buttons on both sides of the cell
254
-
Enabling button creation outside the class (e.g., in the view controller)
255
-
Dynamically calculating the buttons container size
256
-
Making opening/closing of the actions menu behave better
257
-
To fast-forward a bit, I’ve implemented the features above and made the code available on GitHub: https://github.com/blixt/SwipeableTableViewCell
258
-
259
-
Thank you for reading! Please reach out to me with any comments. The easiest way to reach me is on Twitter, where I’m known as @blixt.
0 commit comments