Showing posts with label UITableView. Show all posts
Showing posts with label UITableView. Show all posts

Friday, February 3, 2012

How to Get Magnifying Glass into UITableView Index

If your app contains a list, you might want to considere adding an index bar at right side of the screen. If your list supports search, you might want to add a magnifying glass at top of the index (similar to built-in Contacts application).

Ok, so how do you do that?

Good news is that it's really simple - as soon as you figure it out once. Check Apple iOS SDK for UITableView Class Rerefence and you'll find:

Thursday, March 31, 2011

Beware Using [UIScreen mainScreen].bounds

Found and fixed another device rotation defect, was using wrong bounds to check screen size. Should have used self.tableView instead of [UIScreen mainScreen]:

Sunday, March 27, 2011

Hide UITableView Empty Cell Separator Lines

Plain UITableView displays cell separator lines, when table is empty or has only a few real cells. This is the default behaviour - and it is good. You should not change it.

But sometimes it looks a bit too weird. When your cells have different heights, all empty cells following the last real one will use last cell's height. If this changes at every table refresh, the "jumping" empty cells start annoying users. Or at least developers.

Monday, February 14, 2011

UISearchDisplayController with No Results

Don't know what it is, but I just can't make UISearchDisplayDelegate shouldReloadTableForSearchString method work the way I read the documentation:
You might implement this method if you want to perform an asynchronous search. You would initiate the search in this method, then return NO. You would reload the table when you have results.

Monday, February 7, 2011

UITableView with Custom Cell Height

I'm writing an application, where startup view contains UITableView - which seemed pretty slow. Basic version is not too bad, but when using a custom UITableViewCell created from XIB, it became totally unusable.

Time to debug whether Interface Builder's XIB makes things slow!

Thursday, October 14, 2010

How to Control UISearchBar Background Color

When you have a list, you want to search it. How would you do that? No, don't code it by yourself. Done it, removed it.

By default each UITableView comes with search support via a built-in UISearchDisplayController. You just add and connect UISearchBar to your table in Interface Builder and provide some delegate methods to make it work. Pretty easy:
self.searchDisplayController.delegate =
self.searchDisplayController.searchBar.delegate =
self.searchDisplayController.searchResultsDataSource =
self.searchDisplayController.searchResultsDelegate = self.mySearchObject;
Controlling how your UISearchBar looks like is a bit more difficult. If you want to show search box and some other component(s) side by side, you can do it by putting UIToolbar at back and a short UISearchBar on top of it. By default their backgrounds are different, looking pretty ugly together. Like a hack, what it really is.

You can fix that by doing two things. First get rid of default background:
for (UIView *view in self.searchBar.subviews)
{
   if ([view isKindOfClass:NSClassFromString
     (@"UISearchBarBackground")])
   {
     [view removeFromSuperview];
     break;
   }
}
...and the second thing? Something that will be extremely hard to find out, unless you get it right by accident? You have to set UISearchBar style Black Translucent!

Sad to think how many hours I wasted experimenting Things That Will Not Work, just to find out that kind of miniscule solution. Also bet that this will not work one year from now...

Wednesday, October 13, 2010

Custom Data Formatter for NSIndexPath

Have been using UITableViews for a long time, always complained to myself why cannot I see section and row right away in debugger or variable popup. Something like with CGRect or CGSize. Well, this morning I was doing something completely different. Suddenly solving NSIndexPath debug problem was the much easier task:
section={(int)[$VAR section]}, row={(int)[$VAR row]}
Start debugging anything with a local NSIndexPath variable, even a temporary dummy one. Put breakpoint right after it. When debugger stops, double click on debugger window summary row for NSIndexPath variable and paste the string above there. Seems to stick even after restarting Xcode.

Now I can continue fixing The Real Problem.

Thursday, September 30, 2010

How to Create Default.png

Every released application must have a Default.png file, which is presented during startup. It is supposed to present the default startup view - but empty.


Since all applications are unique (even the thousands of fart apps), there is no single way to create a default.png. However here's two tips, which I use:

1) If your startup view contains a list, create empty list by defining number of sections as 0 (zero):
 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // For Default.png creation
    return 0;
}
2) If your application has UITabBar, clear tab titles:
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    // For Default.png creation
    for (UITabBarItem *item in self.parentViewController.tabBarController.tabBar.items)
        item.title = @"";
}
In general Default.png should not contain any text strings, since one day you might translate your application to other languages. That day you don't want to flash different language strings during app launch.


...oh, and how to create the actual file? Fix your app to present an "empty screen", build and launch debug version in your handset and take a screenshot in your real device by pressing "Power Button" at top and "The Other Button" at front at the same time. Finally open iPhoto in Mac OSX machine and transfer the pic from iPhone...

Tuesday, September 21, 2010

How to Hide UITabBar

Sometimes you need to show a single stand-alone UIView without letting user change tabs. For example there is a list, where you provide an info view using a disclosure accessory button. The question is then: how to hide UITabBar:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
    InfoViewController *info = [[InfoViewController alloc] init];
    info.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:info animated:YES];
    [info release];
}
 Pretty simple, when you find the right location to add right line(s) of code.

Thursday, July 15, 2010

Random Crashes while Debugging - by Debugging

Sometimes the problem is that there is no problem. Trying to debug it more can make the situation even worse - while the real problem was caused by debugging in the first place!

If you have mysterious freezes while debugging UITableView, try reducing the amount of logging. Fixed one such problem by NOT sending any NSLog messages from cellForRowAtIndexPath delegate callback. Seems like too many log messages messed up internal iOS timing.

Wonder how many times I have to re-iLearn this iLesson!

Thursday, May 20, 2010

How to reload current UIViewController

Sometimes you might need to reopen currently open UIViewController. There might be a UITableView, but doing just [self.myTable reloadData] might not be enough. Try this:
[self viewWillDisappear:NO];
[self viewWillAppear:NO];
Of course this will work only, if those methods contain operations you need to do while closing and opening your view.

Friday, April 23, 2010

UITableView doesn't scroll

This makes no sense, but seems like (in Interface Builder) your UITableView must have Scroll View section item Delay Content Touches checked.

Otherwise your table doesn't scroll by touch events.

Monday, February 1, 2010

How to Disable UITableCell Selection

Sometimes you just want to show a list (UITableView) without selecting any row. By default a table (cell) is selectable, so how to disable it. What worked for me was defining each cell separately as non-selectable:

cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
...
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

You could also try controlling the whole table, but it didn't work for me:

- (void)viewDidLoad
{
// Prevent message cell selection
self.chatTableView.allowsSelection = NO;
// HOX: not iPhone 2.2.1 compatible --> crash
[super viewDidLoad];
}

This is also supposed to work, but I recall I still got a selection flash:


- (NSIndexPath *) tableView:(UITableView *)_tableView willSelectRowAtIndexPath:(NSIndexPath *)_indexPath
{
// Return nil if you don't want the row selected.
// Hox: interferes with didSelectRowAtIndexPath
return nil;
}

Wednesday, January 27, 2010

How to Scroll TextField visible Under Keyboard

Very thorough keyboard handling tutorial "iPhone Programming - Editing TextFields without Obscuring Them" by Steve at act_as_geek blog. Lots of pictures, very patiently walking through how to setup things in Interface Builder!

Wonder how it behaves when you have UITableView somewhere.

Currently I use UIControl as root which contains UINavigationBar, UITableView, UIView and UIButton. When keyboard appears, I got to scroll... well, everything visible. Basically I do what is done in that tutorial, but without UIScrollView. Resize one table and one view. Messy.

Time to refactor. Will try how that sample works.

Why Does UITableView Update Sometimes Crash

In some rare cases application can crash, when you do UITableView update (Out of Bounds error). This is more easy in multi-threading applications using NSMutableArray, NSMutableDictionary etc. as data source, where data source is written in non-Main thread(s) and read in Main thread for screen UI update.

Add there some asynchronous calls with automatic data change notifications just to complicate things.

Things which might help:
  • Random delay(s) in random places, maybe before table update starts
  • @synchronized directive to control multi-thread access
  • NSLock to control read/write access
  • Remember index of last safe data item count
Multi-threading and asynchronous operations might be needed to keep UI responsive, mutexes could help keep things under control, automated notifications might offer better architecture.

FIRST update your data, THEN update your table. If you cannot guarantee that, be prepared for endless debugging of just one more crash.