Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p><strong>Edit:</strong> Please see Daniel Hanly's comment. Categories may be selectively applied using <code>#import</code>. My apologies to anyone that may have been misled by this answer. Relevant sections will be redacted for future reference.</p> <p>Okay, attempt number two. <strike>As far as I am aware, there is no other documented way to implement the functionality you require without subclassing UITableViewCell.</strike> It's worth noting that Apple's docs on UITableViewCell specifically mention that the state transition methods are meant to be implemented by subclasses. That having been said, If you <em>absolutely</em> need to implement them without a subclass, there are a couple of less conventional solutions. Each comes with its own issues, and it may end up being unfeasible for you to implement them, but it's an interesting question nonetheless.</p> <h2>Disclaimer</h2> <p><strike>If you only want a sane and relatively simple explanation, then consider the answer to your question to be "no, there is no way to do what you want."</strike> I only present the options below with the assertion that they will work. In no way do I endorse actually using them. Consider this my penance for providing my first answer with such an obvious flaw.</p> <h3>Option One - Categories</h3> <p>It is possible to get the functionality you're looking for by overriding the methods you listed in a custom UITableViewCell category.</p> <p><strike>The problem is that this approach would be a pretty bad idea 99% of the time. Once you define the category on UITableViewCell, those methods would be defined for <em>all</em> UITableViewCell objects throughout the app. Unless you want the exact same state transition functionality for every single table cell in the app, this approach isn't very helpful.</strike></p> <h3>Option Two - Runtime magic</h3> <p>You can use the low-level Objective-C runtime functions to change the implementation of any method on the fly. Unlike the categories option, this approach is flexible enough to redefine the intended behavior whenever you need to, instead of being a one-shot deal. </p> <p>For example, if you're trying to manage state transitions from a UITableViewController, you could do this:</p> <pre><code>CustomTableViewController.m #import &lt;objc/runtime.h&gt; - (void) customStateWillChange:(UITableViewCellStateMask)state { //custom UITableViewCell code } - (void) viewDidAppear:(BOOL)animated { //Store the original implementation Method originalStateWillChangeMethod = class_getInstanceMethod([UITableViewCell class], @selector(willTransitionToState:)); originalStateWillChangeImplementation = method_getImplementation(originalStateWillChangeMethod); //variable declared in header file as type IMP //Get the new implementation Method newStateWillChangeMethod = class_getInstanceMethod([self class], @selector(customStateWillChange:)); IMP newStateWillChangeImplementation = method_getImplementation(newStateWillChangeMethod); //Replace implementation method_setImplementation(originalStateWillChangeMethod, newStateWillChangeImplementation); //the rest of your viewDidAppear code [super viewDidAppear:animated]; } - (void) viewDidDisappear:(BOOL)animated { //restore the original implementation Method originalStateWillChangeMethod = class_getInstanceMethod([UITableViewCell class], @selector(willTransitionToState:)); method_setImplementation(originalStateWillChangeMethod, originalStateWillChangeImplementation); //rest of viewDidDisappear code [super viewDidDisappear:animated]; } </code></pre> <p>This code may not suit your exact purposes, but I think it provides a useful example.</p> <p>It's incredibly ugly though because the <code>customStateWillChange:</code> method defined here is only intended to be run as a part of the UITableViewCell class, but in this example it will be compiled as though it were part of the CustomTableController class. Among other annoyances, you would have to eschew the property dot notation, ignore compiler warnings and give up most if not all compile-time checks for that method's body.</p> <h3>Option 3 - Category with runtime magic</h3> <p>Exactly what it sounds like. Define any custom state change methods you like within a category (or several categories) on UITableViewCell. Be sure that each one has a separate name - adding two categories that each have a method of the same name will result in undefined behavior. Also, each one needs to have the same return type and argument types as the method it is intended to replace.</p> <p>Then the references to [self class] in the above code would be replaced with [UITableViewCell class], and the <code>customStateWillChange:</code> method would be moved to the custom category. While still ugly, you can at least rely on the compiler to interpret the method bodies properly.</p> <p>Of course, messing with the runtime adds a whole lot of complexity to keep track of. It could work fine, but it's not good design, it would take serious effort to ensure it worked safely and correctly, and it would be likely to bring anguish and despair to anyone maintaining it.</p> <h3>References</h3> <p><a href="http://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1" rel="nofollow">The Objective-C Programming Language - Categories and Extensions</a><br> <a href="http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html" rel="nofollow">Objective-C Runtime Reference</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload