FLEXTableViewCell.m 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
  24. if (self) {
  25. [self postInit];
  26. }
  27. return self;
  28. }
  29. - (void)postInit {
  30. UIFont *cellFont = UIFont.flex_defaultTableCellFont;
  31. self.titleLabel.font = cellFont;
  32. self.subtitleLabel.font = cellFont;
  33. self.subtitleLabel.textColor = [FLEXColor deemphasizedTextColor];
  34. self.titleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
  35. self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
  36. self.titleLabel.numberOfLines = 1;
  37. self.subtitleLabel.numberOfLines = 1;
  38. }
  39. - (UILabel *)titleLabel {
  40. return self.textLabel;
  41. }
  42. - (UILabel *)subtitleLabel {
  43. return self.detailTextLabel;
  44. }
  45. - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
  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. // Must be unretained to avoid over-releasing
  59. __unsafe_unretained id sender;
  60. [invocation getArgument:&sender atIndex:2];
  61. SEL action = invocation.selector;
  62. // [self._tableView _performAction:action forCell:[self retain] sender:[sender retain]];
  63. invocation.selector = @selector(_performAction:forCell:sender:);
  64. [invocation setArgument:&action atIndex:2];
  65. [invocation setArgument:(void *)&self atIndex:3];
  66. [invocation setArgument:(void *)&sender atIndex:4];
  67. [invocation invokeWithTarget:self._tableView];
  68. }
  69. - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
  70. if ([self canPerformAction:selector withSender:nil]) {
  71. return [self._tableView methodSignatureForSelector:@selector(_performAction:forCell:sender:)];
  72. }
  73. return [super methodSignatureForSelector:selector];
  74. }
  75. @end