You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.2 KiB

  1. //
  2. // FLEXClassesTableViewController.m
  3. // Flipboard
  4. //
  5. // Created by Ryan Olson on 2014-05-03.
  6. // Copyright (c) 2014 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXClassesTableViewController.h"
  9. #import "FLEXObjectExplorerViewController.h"
  10. #import "FLEXObjectExplorerFactory.h"
  11. #import "FLEXUtility.h"
  12. #import <objc/runtime.h>
  13. @interface FLEXClassesTableViewController () <UISearchBarDelegate>
  14. @property (nonatomic, strong) NSArray<NSString *> *classNames;
  15. @property (nonatomic, strong) NSArray<NSString *> *filteredClassNames;
  16. @property (nonatomic, strong) UISearchBar *searchBar;
  17. @end
  18. @implementation FLEXClassesTableViewController
  19. - (void)viewDidLoad
  20. {
  21. [super viewDidLoad];
  22. self.searchBar = [[UISearchBar alloc] init];
  23. self.searchBar.placeholder = [FLEXUtility searchBarPlaceholderText];
  24. self.searchBar.delegate = self;
  25. [self.searchBar sizeToFit];
  26. self.tableView.tableHeaderView = self.searchBar;
  27. }
  28. - (void)setBinaryImageName:(NSString *)binaryImageName
  29. {
  30. if (![_binaryImageName isEqual:binaryImageName]) {
  31. _binaryImageName = binaryImageName;
  32. [self loadClassNames];
  33. [self updateTitle];
  34. }
  35. }
  36. - (void)setClassNames:(NSArray<NSString *> *)classNames
  37. {
  38. _classNames = classNames;
  39. self.filteredClassNames = classNames;
  40. }
  41. - (void)loadClassNames
  42. {
  43. unsigned int classNamesCount = 0;
  44. const char **classNames = objc_copyClassNamesForImage([self.binaryImageName UTF8String], &classNamesCount);
  45. if (classNames) {
  46. NSMutableArray<NSString *> *classNameStrings = [NSMutableArray array];
  47. for (unsigned int i = 0; i < classNamesCount; i++) {
  48. const char *className = classNames[i];
  49. NSString *classNameString = [NSString stringWithUTF8String:className];
  50. [classNameStrings addObject:classNameString];
  51. }
  52. self.classNames = [classNameStrings sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)];
  53. free(classNames);
  54. }
  55. }
  56. - (void)updateTitle
  57. {
  58. NSString *shortImageName = self.binaryImageName.lastPathComponent;
  59. self.title = [NSString stringWithFormat:@"%@ Classes (%lu)", shortImageName, (unsigned long)[self.filteredClassNames count]];
  60. }
  61. #pragma mark - Search
  62. - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
  63. {
  64. if ([searchText length] > 0) {
  65. NSPredicate *searchPreidcate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", searchText];
  66. self.filteredClassNames = [self.classNames filteredArrayUsingPredicate:searchPreidcate];
  67. } else {
  68. self.filteredClassNames = self.classNames;
  69. }
  70. [self updateTitle];
  71. [self.tableView reloadData];
  72. }
  73. - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
  74. {
  75. [searchBar resignFirstResponder];
  76. }
  77. - (void)scrollViewDidScroll:(UIScrollView *)scrollView
  78. {
  79. // Dismiss the keyboard when interacting with filtered results.
  80. [self.searchBar endEditing:YES];
  81. }
  82. #pragma mark - Table View Data Source
  83. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  84. {
  85. return 1;
  86. }
  87. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  88. {
  89. return [self.filteredClassNames count];
  90. }
  91. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  92. {
  93. static NSString *CellIdentifier = @"Cell";
  94. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  95. if (!cell) {
  96. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  97. cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
  98. cell.textLabel.font = [FLEXUtility defaultTableViewCellLabelFont];
  99. }
  100. cell.textLabel.text = self.filteredClassNames[indexPath.row];
  101. return cell;
  102. }
  103. #pragma mark - Table View Delegate
  104. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  105. {
  106. NSString *className = self.filteredClassNames[indexPath.row];
  107. Class selectedClass = objc_getClass([className UTF8String]);
  108. FLEXObjectExplorerViewController *objectExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:selectedClass];
  109. [self.navigationController pushViewController:objectExplorer animated:YES];
  110. }
  111. @end