Deprecating Soft Assignment

See also: the categories Deprecated parameters and Pages using deprecated templates.

This category contains templates that are "deprecated" – they have been superseded by another template, often because the new template is more flexible or combines the features of two previously separate templates.

Usage without a date parameter categorises templates into this category. Adding the date parameter categorises the template into a dated subcategory.

If a deprecated template is still in use on other pages, add tags around the {{Deprecated template}} template. That way the template page will show the deprecation tag, but pages using it will not. If a template has been fully deprecated, meaning that it not in use on other pages, the noinclude tags may be removed. That way a deprecation tag will show on any page using the deprecated template. Afterwards consider nominating the template for deletion, or marking it with {{Historical template}}.

Inline templates should be marked with {{Deprecated template-inline}}.

Note that deprecated stub templates are not normally deleted, as they are used as soft redirects. These should be marked with {{Deprecated stub}}.


This category has the following 64 subcategories, out of 64 total.

Pages in category "Deprecated templates"

The following 53 pages are in this category, out of 53 total. This list may not reflect recent changes (learn more).

is a cornerstone of classical iOS development and one of the oldest classes. It's used in pretty much all iOS apps and has been around since iPhone OS 2.0. So why would we propose deprecating one of the most used classes?

Simple: . Added in iOS 6 (2012), it's almost a perfect superset of , yet it can do so much more.

Consider the UI in our free app, PDF Viewer, which uses yet includes a layout similar to a table view:

We're not the first ones to call for its retirement and even Apple has figured this out. All one has to do is take a look at some of the new internal classes that appeared in iOS 10: (h/t @BunuelCuboSoto's tweet)

The API even has public and private parts (methods that start with an ), so it seems that the UIKit team at one point considered offering this API but it didn't make the cut. When you take a closer look, you'll see that still uses internally for some features (swipe to delete in this case) so some shortcuts have been made that likely are a reason why this API isn't public yet. Let's hope that this changes with iOS 11. Please duplicate rdar://30098111 to vote for this. Even better if you write your own bug report - see our article for some tips.

Parts of that transition already happened. Consider the (sorry) crime that was and how it was replaced with sane API () in iOS 8. The new API is UI-agnostic and no longer directly ties to a table view, so it can be used with collection views or any custom class as well. (If you still have legacy code this article is a great resource to understand both API variants and shows how to upgrade your code.)

is a masterpiece of flexibility and great API design. Back at WWDC 2012 when Apple previewed iOS 6, we did a rewrite and it took quite some time to even implement a subset of all the features (without animations) - some might remember . It helped people to adopt collection views faster as it supported back to iOS 4.3 and was very easy to switch to the "real" class by using some crazy runtime hackery.


There's a great episode of the Debug podcast where Nitin Ganatra shares a lot about the history of , and the road from iPhone to iPad. (Link includes a transcript if you prefer to read).

In short, iPhone OS 1.0 was very chaotic and while there were shared frameworks, each team built a lot on their own. Eventually, a table class was centralized as and it lived in iOS until it was finally removed in iOS 6 - the runtime header history shows this pretty well.

iPhone OS 2 was a huge cleanup and out of that came - a class that has been tweaked in basically every update of iOS, especially with the grand redesign of iOS 7.

API Warts

is old and most of it was written before we had blocks or Auto Layout. It shows. This is how you update a section in :





And this is the same operation but in :



This may not look like much, but it is very easy to mess up balancing calls to and in more complex setups, whereas this is impossible with 's API. Since this class is so old, there's also a lot of deprecated API that still has to be supported. The Swift view doesn't show header entries that are long deprecated, but if you switch to Objective-C, you'll see the full extend of what's in this cell:



Auto Layout

Auto Layout is relatively new compared to the existence of . No wonder they don’t work very well together. Apple has done a good job with auto-sizing table view cells and after the first iteration they work pretty well. However, there are still cases where you run into strange layout issues or where things feel a bit off.

One example of this is that you can't use the default table view cell styles in a way that support multiline labels. Before Auto Layout, it wasn't possible to, for example, set the 's to and support multi line labels because you weren't able to calculate the correct height of the cell anyway, as you had no knowledge about where the cell would place these labels. Now with Auto Layout and self sizing table view cells, Apple essentially made this process automatic. So it is very tempting to set the to and just let the table view calculate the height the cell needs for any given text. This works fine in many cases, however you will eventually run into layout issues as soon as your table view cell is using more than just the and the . Asking Apple engineers why this does not work as we expected in WWDC’16, we got a very simple answer: dates back way before Auto Layout and it simply was never built to work that way. In fact they told us, you shouldn't touch anything on the cell's internal views other than the property of the labels and the property of the image view. This means that you need to subclass for any customization and add your own labels anyway.

Another issue that can happen easily with Auto Layout in table view cells is that you will see messages like popping up in your console. If you aren't careful when crafting your layout, you may create a cell whose height is off by 0.5pt on retina devices, which is exactly the height of the separator. Usually this happens if you use Auto Layout but calculate the height of the cell yourself. The table view cell tries to make room for one or two separator views (depending on the index path of the cell and the style of the table view) by shrinking its content view. If you are too strict with your layout and don't make it flexible enough to deal with these different heights, the cell can not satisfy all your constraints and ends up with a content view that doesn't work with your layout.

UITableViewCell does way too much

From what we discussed above, it may already be clear that simply does too much. However, there's more!

A is initialized with a style. Let's take a look what we can set there:





The labels and image views that are configured by these styles are an all or nothing approach. For example, if you try to use the of but then add a second label on your own, you will most likely run into layout issues. So when subclassing a table view cell you carry these default API around even though you don't use them. Your cell might have its own labels. So when looking at the API, you will see the table view cell's built in labels as well as your own. Which one should you use? This can be confusing.

also doesn't work well with , which has been around since iOS 6. If you register a standard class with this, the table view will always initialize it with the default style. You can work around this by creating a subclass that overrides in a way that it ignores the passed in style and always passes the style you actually want. But this again is a workaround and feels odd.

And what happens if I set a subtitle with the default style? The reality is that there's too much old logic and if you use , your best bet is to add your own views to the so you don't need to work around 10 years' worth of custom layout logic.

Display Sizes and Size Classes

comes from a time where there was exactly one screen size and class of device: The iPhone. But times have changed. If you are building a universal app and want to fit in on all the supported devices, chances are that your table views don't fit very well on the large screen of an iPad.

Lists that only contain a small amount of text so that they are readable on an iPhone feel out of place on an iPad. You see a couple of words on the screen and the rest is just empty, wasted space. While it's true that you probably shouldn't try to get the same information density on a large screen than on a small screen, you still can put a little bit more on a screen of this size than on an iPhone display. Therefore, it often is a good practice to display two, three, or maybe even more columns on an iPad.

This is exactly what does. So instead of building a collection view for the iPad and a for the iPhone, it would make much more sense to have the same collection view look like a table view on small devices and show multiple columns on devices with larger screens.

This is exactly what Apple did with the iTunes Connect app and they talked about it at WWDC’14 Session 232 - Advanced User Interfaces with Collection Views. They did exactly what we are proposing here: Dropped and replaced it with a subclass that looks like a table view. The best thing about this is: They moved a big part of the layout into the sample code, so this might be a good starting point if you want to move your table views over to collection views.

Data Sources

As we already discovered, there are many cases where you want the look of a table view on devices with a compact horizontal size class but the look of a multi-column collection view on devices with a regular horizontal size class. If you want to do this with today's API, this also means that you need two implementations of the data source and two implementations of the delegate. One of each for and .

One workaround is to write an adapter for one or maybe even both of them, but it would be much easier if there was a system-wide layout available for that makes it look like a table view. You would no longer need to duplicate your code or write adapters to make your app feel at home on both size classes.

Over there in Android-Land

The situation on Android is very similar. Since its first version, the Android framework contained ListView for showing items similar to . With the 2014 release of Android 5.0 Lollipop Google published a successor, the RecyclerView. ships in the Android Support Library, which means it can be used on all Android versions back to Android 2.1 Eclair (2010). also replaces other adapter based views, like GridView and allows other layouts too (for example staggered grid, etc).

Google is more explicit about soft-deprecating ; just read the first sentence in their documentation:

The RecyclerView widget is a more advanced and flexible version of ListView.

While for some legacy features there is no default implementation, which requires developers to write more boilerplate code to migrate their old code, in general provides much better performance and flexibility, and is thus the way to go.


There's no need to manically replace all your table views with collection views, but it's time for Apple to offer API to allow collection views to be used like table views, so we all can make better apps with less code that are more flexible in this multi-size screen world. At PSPDFKit we try hard to structure our API just like Apple would, so we'll keep most of our table views for now, but we'd be the first to adopt the new layout once it becomes available. Please vote by writing a Radar) if you feel that unifying this is a good idea. Ping us on Twitter if you have further ideas or want to start an open source project to build this yourself.

0 Thoughts to “Deprecating Soft Assignment

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *