Deselecting a UITableViewCell within a SelectRowAtIndexPath
- A user shows a UITableView and selects a row.
- The Row highlights to indicate the user made the selection.
- The UITableView scrolls away.
- The user shows the same UITableView again, this time the same row is selected.
- Sad Face for me the programmer
Note: I believe this is only happening with UITableView that is created from a nib file.
So what is the big deal, just use deselectRowAtIndexPath: and it is deselect the row. Well there is a catch, or not if you are smarter than me. The catch is you need out use deselectRowAtIndexPath:indexPath animated:YES and heres why; If you set animated:NO then the row never get highlighted and the user may not really know which cell was selected. But if you use animated:YES then it deselects during the animation, right after it does the selection during the animation. Makes sense? Well not really, but the good part is that the next time the table view is shown the selection is gone, as I wanted.
Sad face gone.
Here is some code to ponder. This is a TableViewDelegate and I'm using the tableview as a modal view.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// do some stuff
[self.navigationController dismissModalViewControllerAnimated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
iPhone Development: Beta 4
Many of the API changes are of the properties type. That look like this:
Modified CLLocation.altitude
|
|
Declaration
|
|
Old
|
@property(readonly)
CLLocationDistance altitude
|
|
New
|
@property(readonly,
nonatomic) CLLocationDistance altitude
|
While there were a large number of these changes, I suspect they are starting to lock down their APIs in much of the SDK.
Without digging too much into this method, I think I'm going to like it: -[UIViewController initWithNibName:bundle:]
I also want an example of how to use the Proxy Object in IB.
My application didn't compile because they removed UIModalView. But added UIActionSheet and they updated their sample code so it will only take me a few minutes to get back online.
iPhone Development: Beta 3 and Interface Builder
But then, while looking at the updated examples, what did I find? But the use of xib files and IB. I was very excited because one example was exactly how I needed to use IB for my IPhone application.
The moral of the story? Don't get ahead of Apple's SDK engineers or you will endure much pain.
iPhone Development: UITableView nib Hell
The gist of the problem is, once the UITableView has been displayed with some cells, when I try to change the state of the cell by using UITableViewDelegate protocols, implemented in my UIViewController for the table view, noting happens. If I try to deselect, reload the data in the view with new data, it just doesn't show up.
For example, making this call doesn't actually visually deselect, but does actually deselect internally, meaning there is not selection in the UITableView.
[(UITableView*)self.view deselectRowAtIndexPath:selectedRowPath animated:animated];
If I want to reload the view with a different set of cell data and I do the following.
- (void)viewWillAppear:(BOOL)animated
{
self.title = [self categoryToShowInTable];
[(UITableView*)self.view reloadData];
}
All the table vie delegates get called such as cellForRowAtIndexPath, but the view as displayed doesn't show the new items.
It almost seems to me that I have something very wrong, and it is causing me this behavior. If that is the case I'll update this entry with the solution.
iPhone Development: The Whole Delegate Trickery
@interface CategoriesViewController : UIViewController
So, I declare my view controller and add in a few protocols and I'm in business. Well, have access to the "business" anyway. I don't know how this is done in the OO runtime world, where it came from, (Smalltalk?) but I sure do like it.
NSTreeController Development: Walking the Tree
The method arrangedObjects is very useful, see here: – arrangedObjects Notice that it returns a proxy root tree node containing the receiver's sorted content object. Those are some very important words and hard to explain, so instead of trying to explain, I''ll show.
NSArray *treeNodes = [[self arrangedObjects] childNodes];
So, arrangedObjects returns a proxy root tree node, so just pass that into the childNodes of NSTreeController, another useful 10.5 method, and you get all the children of the treeNode. Since I used arrangedObject, I get the top of the tree so that I can with it as I please, mostly.
Anyway here are some category classes that allow you to walk the tree using any controller selector as a callback. This example is not perfect, it is a work in progress, but useful none the less.
The code below is defined as a catagory of NSTreeController, in a garbage collected environment, so there is no memory management.
//
// NSTreeController-Extensions.h
//
// Created by Joe Michels on 3/8/08.
// Copyright 2008 Software Ops LLC. All rights reserved.
//
#import Cocoa/Cocoa.h
@interface NSTreeController (NSTreeController_Extensions)
- (void)visitAllNodesStartingWithNode: (NSArray* )treeNodes useSelector: (SEL)inSelector
withObject: (id)inObject;
@end
//
// NSTreeController-Extensions.m
// TeamPlayer
//
// Created by Joe Michels on 3/8/08.
// Copyright 2008 Software Ops LLC. All rights reserved.
//
#import "NSTreeController-Extensions.h"
#import "ProjectsController.h"
@implementation NSTreeController (NSTreeController_Extensions)
- (void)visitAllNodesStartingWithNode: (NSArray* )treeNodes
useSelector: (SEL)inSelector
withObject: (id)inObject
{
// This is a recursive decent routine. It will walk the tree visiting each node
for (id item in treeNodes)
{
NSLog( @"Visiting tree node: %@", [[item representedObject] valueForKeyPath:@"name"] );
[self performSelector:inSelector withObject:item withObject:inObject];
//check for a decendent
NSArray *childNodes = [item childNodes];
if ([childNodes count] > 0)
// we are recursing
[self visitAllNodesStartingWithNode:childNodes useSelector:inSelector withObject:inObject];
}
}
@end
Let's make a call using the above code.
- (NSArray* )itemsForScripting
{
NSLog(@"Getting projects for scripting, returned in array.");
NSArray *treeNodes = [[self arrangedObjects] childNodes];
NSMutableArray *itemsArray = [[NSMutableArray alloc] initWithCapacity: 2]; << 2??, whatever!
[self visitAllNodesStartingWithNode:treeNodes
useSelector:@selector(getOrderedListOfProjects:withArray: )
withObject:itemsArray];
return itemsArray;
}
You can pass nil for the object as in this code snipet:
NSArray *treeNodes = [[self arrangedObjects] childNodes];
[self visitAllNodesStartingWithNode:treeNodes
useSelector:@selector(findAllMatchesInNodes:withObject: )
withObject:nil];
NSTreeController Development: Inserting Objects for Scripting
First I want point out that I want constructive criticism from users who have actually purchased My Eyes Only™.
The Freetards
Where to start with this. The freetards have polluted the App Store. This is a disgrace to the wonderful App Store. Using the word disgrace is an emotional response and I said I would use logic. Well, there is just no logic to the freetards. It is a religion filled with emotion.
Report Your Problems to the Company
It theory, this should not be needed but if you run across repetitive problems that you did have in the first place, then reboot. Here is one comment that was fair but, put the blame in the wrong place. This was for an application that I’m interested in purchasing.
I was just about to post this great review about how the application is easy to use and turns you free time in great fun, when I started to have stability issues with it. At the moment the program does not run at all, clicking ok the icon does nothing but shows the splash screen (which it already annoyed me because it takes time from starting the application) the quits.
Well I had the same problem with my iPhone I was stumped. But, by happen stance I decided to re-download my apps from the store. Did you know you could do that? Well that cleared up my problem.
Reboot Your iPhone
I was testing MEO and I found a bug that I could reproduce. Those are the best! I did it 5 times while having lunch so I had it nailed. Well, I decided to reboot the iPhone, just to see what would happen. Well... I could not reproduce the problem. In fact, I spent an hour and a half trying to reproduce the issue and finally gave up. It most likely wasn’t my problem.
iPhone Development: Interface Builder -Read the Damn Release Notes!
What to do?
Since there was no iPhone example application using IB, I was on my own and started digging around. I first realized that the UINavigationController as setup by the nib loading process was missing a few initialized objects as compared to one initialized with initWithRootViewController. Hmm... OK, so I ditched the nib based UINavigationController with one I created and initWithRootViewController. "That should help", I thought. Ah... no. I better try to find more about IB and iPhone. So I reread the release notes and sure enough, right there in front of my face was the answer:
FAQ: How do I edit a Cocoa Touch view controller? ▪ Drag a view controller object from the library into the document window. ▪ In the document window, double-click the icon for the view controller object to open its editor. ▪ Drag and drop views, navigation items, and tab bar items from the Library onto the editor.
Well, OK. To be fair to me, when I first read this I was not thinking that I defined the UI by dragging and dropping views onto a view controller UI thingy. When I did, cha-ching! it worked.