Created
January 13, 2014 10:05
-
-
Save n-b/8397563 to your computer and use it in GitHub Desktop.
Demo for a NSAttributedString / HTML parsing issue on iOS 7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import UIKit; | |
#pragma mark - Main View Controller | |
@interface ViewController : UITableViewController | |
@end | |
@implementation ViewController | |
// A simple TableViewController with a large number of cell | |
// | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 10000; } | |
// A small HTML fragment is parsed and set as the attributed title for each cell | |
// | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath | |
{ | |
UITableViewCell * cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; | |
NSString * htmlSource = [NSString stringWithFormat:@"<html><p>Row <i>%@</i></p></html>", @(indexPath.row)]; | |
NSAttributedString * attributedText = [[NSAttributedString alloc] initWithData:[htmlSource dataUsingEncoding:NSUTF8StringEncoding] | |
options:@{NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType} | |
documentAttributes:nil | |
error:nil]; | |
cell.textLabel.attributedText = attributedText; | |
return cell; | |
} | |
- (void) scrollViewDidScroll:(UIScrollView *)scrollView | |
{ | |
for (NSIndexPath * indexPath in [self.tableView indexPathsForVisibleRows]) { | |
[self.tableView cellForRowAtIndexPath:indexPath]; // CRASH | |
// This crashes as soon as you start scrolling. | |
// | |
// [self.tableView visibleCells] doesn't match [self.tableView indexPathsForVisibleRows] | |
// (There are less cells than there are visible rows.) | |
// | |
// This happens because HTML parsing uses Webkit in the main thread, which requires running the main runloop in a common mode. | |
// | |
// In other words, -scrollViewDidScroll is called inside -cellForRowAtIndexPath. | |
} | |
} | |
@end | |
#pragma mark - App Setup | |
@interface AppDelegate : UIResponder <UIApplicationDelegate> | |
@property (strong, nonatomic) UIWindow *window; | |
@end | |
@implementation AppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions | |
{ | |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | |
self.window.rootViewController = [ViewController new]; | |
[self.window makeKeyAndVisible]; | |
return YES; | |
} | |
@end | |
int main(int argc, char * argv[]) | |
{ | |
@autoreleasepool { | |
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Filed as rdar://15803156