FLEXTableViewCell.m 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //
  2. // FLEXTableViewCell.m
  3. // FLEX
  4. //
  5. // Created by Tanner on 4/17/19.
  6. // Copyright © 2019 Flipboard. All rights reserved.
  7. //
  8. #import "FLEXTableViewCell.h"
  9. #import "FLEXUtility.h"
  10. #import "FLEXColor.h"
  11. #import "FLEXTableView.h"
  12. @interface UITableView (Internal)
  13. // Exists at least since iOS 5
  14. - (BOOL)_canPerformAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender;
  15. - (void)_performAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender;
  16. @end
  17. @interface UITableViewCell (Internal)
  18. // Exists at least since iOS 5
  19. @property (nonatomic, readonly) FLEXTableView *_tableView;
  20. @end
  21. @implementation FLEXTableViewCell
  22. - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
  23. {
  24. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  25. if (self) {
  26. [self postInit];
  27. }
  28. return self;
  29. }
  30. - (void)postInit {
  31. UIFont *cellFont = UIFont.flex_defaultTableCellFont;
  32. self.titleLabel.font = cellFont;
  33. self.subtitleLabel.font = cellFont;
  34. self.subtitleLabel.textColor = [FLEXColor deemphasizedTextColor];
  35. self.titleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
  36. self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
  37. }
  38. - (UILabel *)titleLabel {
  39. return self.textLabel;
  40. }
  41. - (UILabel *)subtitleLabel {
  42. return self.detailTextLabel;
  43. }
  44. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
  45. {
  46. return [self._tableView _canPerformAction:action forCell:self sender:sender];
  47. }
  48. /// We use this to allow our table view to allow its delegate
  49. /// to handle any action it chooses to support, without
  50. /// explicitly implementing the method ourselves.
  51. ///
  52. /// Alternative considered: override respondsToSelector
  53. /// to return NO. I decided against this for simplicity's
  54. /// sake. I see this as "fixing" a poorly designed API.
  55. /// That approach would require lots of boilerplate to
  56. /// make the menu appear above this cell.
  57. - (void)forwardInvocation:(NSInvocation *)invocation
  58. {
  59. // Must be unretained to avoid over-releasing
  60. __unsafe_unretained id sender;
  61. [invocation getArgument:&sender atIndex:2];
  62. SEL action = invocation.selector;
  63. // [self._tableView _performAction:action forCell:[self retain] sender:[sender retain]];
  64. invocation.selector = @selector(_performAction:forCell:sender:);
  65. [invocation setArgument:&action atIndex:2];
  66. [invocation setArgument:(void *)&self atIndex:3];
  67. [invocation setArgument:(void *)&sender atIndex:4];
  68. [invocation invokeWithTarget:self._tableView];
  69. }
  70. - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
  71. {
  72. if ([self canPerformAction:selector withSender:nil]) {
  73. return [self._tableView methodSignatureForSelector:@selector(_performAction:forCell:sender:)];
  74. }
  75. return [super methodSignatureForSelector:selector];
  76. }
  77. @end