FLEXTableViewCell.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. self.titleLabel.numberOfLines = 1;
  38. self.subtitleLabel.numberOfLines = 1;
  39. }
  40. - (UILabel *)titleLabel {
  41. return self.textLabel;
  42. }
  43. - (UILabel *)subtitleLabel {
  44. return self.detailTextLabel;
  45. }
  46. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
  47. {
  48. return [self._tableView _canPerformAction:action forCell:self sender:sender];
  49. }
  50. /// We use this to allow our table view to allow its delegate
  51. /// to handle any action it chooses to support, without
  52. /// explicitly implementing the method ourselves.
  53. ///
  54. /// Alternative considered: override respondsToSelector
  55. /// to return NO. I decided against this for simplicity's
  56. /// sake. I see this as "fixing" a poorly designed API.
  57. /// That approach would require lots of boilerplate to
  58. /// make the menu appear above this cell.
  59. - (void)forwardInvocation:(NSInvocation *)invocation
  60. {
  61. // Must be unretained to avoid over-releasing
  62. __unsafe_unretained id sender;
  63. [invocation getArgument:&sender atIndex:2];
  64. SEL action = invocation.selector;
  65. // [self._tableView _performAction:action forCell:[self retain] sender:[sender retain]];
  66. invocation.selector = @selector(_performAction:forCell:sender:);
  67. [invocation setArgument:&action atIndex:2];
  68. [invocation setArgument:(void *)&self atIndex:3];
  69. [invocation setArgument:(void *)&sender atIndex:4];
  70. [invocation invokeWithTarget:self._tableView];
  71. }
  72. - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
  73. {
  74. if ([self canPerformAction:selector withSender:nil]) {
  75. return [self._tableView methodSignatureForSelector:@selector(_performAction:forCell:sender:)];
  76. }
  77. return [super methodSignatureForSelector:selector];
  78. }
  79. @end