<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Tewha.net</title>
    <link>https://tewha.net/tags/cocoa-touch/</link>
    <description>Recent content on Tewha.net</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Sat, 17 Jan 2015 16:00:00 +0000</lastBuildDate>
    <atom:link href="https://tewha.net/tags/cocoa-touch/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How to fix UITableView rows changing size</title>
      <link>https://tewha.net/2015/01/how-to-fix-uitableview-rows-changing-size/</link>
      <pubDate>Sat, 17 Jan 2015 16:00:00 +0000</pubDate>
      <guid>https://tewha.net/2015/01/how-to-fix-uitableview-rows-changing-size/</guid>
      <description>&lt;p&gt;Do you have an app where the row heights in a table view shift, especially when navigating away from a view controller?&lt;/p&gt;
&lt;p&gt;This seems to be an iOS bug and is caused by using autolayout within a table cell without a &lt;code&gt;tableView:estimatedHeightForRowAtIndexPath:&lt;/code&gt; method.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Do you have an app where the row heights in a table view shift, especially when navigating away from a view controller?</p>
<p>This seems to be an iOS bug and is caused by using autolayout within a table cell without a <code>tableView:estimatedHeightForRowAtIndexPath:</code> method.</p>
<p>If you do not implement this method, the UITableView will treat that as an estimated row height of ``. AutoLayout will panic and try to compensate for this, and you’ll still see an incorrect size. (I believe this to be the minimum size that it thinks would satisfy your content without any spacing and taking wrapping into account, but I’m not sure of this.) You see this bug in some of Apple’s apps, including Settings.</p>
<p>To fix it, you need to implement <code>tableView:estimatedHeightForRowAtIndexPath:</code> and return a rough estimate of the size of the row. iOS includes a constant for this, if you have no good estimate: <code>UITableViewAutomaticDimension</code>.</p>
<p>This may introduce a few other (minor) problems, as providing estimates can lead to views being poorly sized as you scroll. Apple discusses this in their documentation. If you are impacted by something like that, a <code>tableView:estimatedHeightForRowAtIndexPath:</code> that returns values closer to actual might help. That said, while I had problems from rough estimation on the <strong>simulator</strong> I’ve never noticed it on a real device. Seems like the logic is a bit different between them.</p>
<p>However:</p>
<ul>
<li>You should <strong>not</strong> attempt to calculate real height values. The entire point of this method is to short-circuit involved height calculation. It’s just unnecessary.</li>
<li>You should not attempt to cache heights returned by the real <code>tableView:heightForRowAtIndexPath:</code>, either. The values in that cache will be wrong when <strong>estimatedHeightForRowAtIndexPath</strong> is first called anyway; they’re really no better than <code>UITableViewAutomaticDimension</code>. And if you return ``, you’ll hit this bug.</li>
</ul>
<p>So what <em>should</em> you do? It really is this simple:</p>
<pre><code>- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}
</code></pre>
<p>And you’re done!</p>]]></content:encoded>
    </item>
    <item>
      <title>Built-in categories</title>
      <link>https://tewha.net/2014/03/built-in-categories/</link>
      <pubDate>Wed, 26 Mar 2014 14:00:00 +0000</pubDate>
      <guid>https://tewha.net/2014/03/built-in-categories/</guid>
      <description>&lt;p&gt;&lt;strong&gt;NSIndexPath&lt;/strong&gt; is easier to use than you might think.&lt;/p&gt;
&lt;p&gt;If you read the documentation for the class, you’ll see this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><strong>NSIndexPath</strong> is easier to use than you might think.</p>
<p>If you read the documentation for the class, you’ll see this:</p>
<blockquote>
<p>Creating Index Paths</p>
<ul>
<li>
<p>indexPathWithIndex:</p>
</li>
<li>
<p>indexPathWithIndexes:length:</p>
</li>
</ul>
<ul>
<li>
<p>initWithIndex:</p>
</li>
<li>
<p>initWithIndexes:length:</p>
</li>
<li>
<p>init</p>
</li>
</ul>
</blockquote>
<p>Yes, you can use these to construct an index path. But you probably don’t want to. UIKit defines a category on <strong>NSIndexPath</strong> specific to <strong>UITableView</strong>’s needs:</p>
<pre><code>// This category provides convenience methods to make it easier to use an NSIndexPath to represent a section and row
@interface NSIndexPath (UITableView)

+ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;

@property(nonatomic,readonly) NSInteger section;
@property(nonatomic,readonly) NSInteger row;

@end
</code></pre>
<p>There’s a similar category defined by <strong>UICollectionView</strong>:</p>
<pre><code>@interface NSIndexPath (UICollectionViewAdditions)

+ (NSIndexPath *)indexPathForItem:(NSInteger)item inSection:(NSInteger)section NS_AVAILABLE_IOS(6_0);

@property (nonatomic, readonly) NSInteger item NS_AVAILABLE_IOS(6_0);

@end
</code></pre>
<p>The absence of section in this category isn’t significant; the same property is already defined by <strong>NSIndexPath (UITableView)</strong>.</p>
<p>UIKit defines other categories, such as drawing categories on <strong>NSString</strong>.</p>
<p>Why are these separated? Well, <strong>NSIndexPath</strong> is part of Foundation. <strong>UITableView</strong> is part of UIKit. String drawing is added to <strong>NSString</strong> which is part of Foundation, but Foundation, but uses <strong>UIFont</strong> which is part of UIKit. In short, there’s good technical reasons for this to be splatted out. But knowing that is not helpful to us developers.</p>
<p>So how do you find out about these methods? I don’t think there’s a good way to find categories like these in Apple’s class references. Some of them are mentioned in Apple’s less reference-like material. For instance, there’s ”<a href="https://developer.apple.com/library/ios/Documentation/Cocoa/Conceptual/Collections/Articles/IndexPaths.htm">Collections Programming Topics: Index Paths: Storing a Path Through Nested Arrays</a>”:</p>
<blockquote>
<p>In iOS, UITableView and its delegate and data source use index paths to manage much of their content and to handle user interaction. To assist with this, UIKit adds programming interfaces to NSIndexPath to incorporate the rows and sections of a table view more fully into index paths. For more information, see NSIndexPath UIKit Additions. For instance, index paths are used to designate user selections using the tableView:didSelectRowAtIndexPath: delegate method.</p>
</blockquote>
<p>Google searches are probably your best bet, such as <a href="https://www.google.com/#q=nsindexpath+from+row+and+section">index path from row and section</a>.</p>
<p>I hope we’ll see improvements on this in the future.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
