FLEXArgumentInputTextView.m 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. //
  2. // FLEXArgumentInputTextView.m
  3. // FLEXInjected
  4. //
  5. // Created by Ryan Olson on 6/15/14.
  6. //
  7. //
  8. #import "FLEXColor.h"
  9. #import "FLEXArgumentInputTextView.h"
  10. #import "FLEXUtility.h"
  11. @interface FLEXArgumentInputTextView ()
  12. @property (nonatomic) UITextView *inputTextView;
  13. @property (nonatomic) UILabel *placeholderLabel;
  14. @property (nonatomic, readonly) NSUInteger numberOfInputLines;
  15. @end
  16. @implementation FLEXArgumentInputTextView
  17. - (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding
  18. {
  19. self = [super initWithArgumentTypeEncoding:typeEncoding];
  20. if (self) {
  21. self.inputTextView = [UITextView new];
  22. self.inputTextView.font = [[self class] inputFont];
  23. self.inputTextView.backgroundColor = [FLEXColor secondaryGroupedBackgroundColor];
  24. self.inputTextView.layer.cornerRadius = 10.f;
  25. self.inputTextView.contentInset = UIEdgeInsetsMake(0, 5, 0, 0);
  26. self.inputTextView.autocapitalizationType = UITextAutocapitalizationTypeNone;
  27. self.inputTextView.autocorrectionType = UITextAutocorrectionTypeNo;
  28. self.inputTextView.delegate = self;
  29. self.inputTextView.inputAccessoryView = [self createToolBar];
  30. if (@available(iOS 11, *)) {
  31. [self.inputTextView.layer setValue:@YES forKey:@"continuousCorners"];
  32. } else {
  33. self.inputTextView.layer.borderWidth = 1.f;
  34. self.inputTextView.layer.borderColor = [FLEXColor borderColor].CGColor;
  35. }
  36. self.placeholderLabel = [UILabel new];
  37. self.placeholderLabel.font = self.inputTextView.font;
  38. self.placeholderLabel.textColor = [FLEXColor deemphasizedTextColor];
  39. self.placeholderLabel.numberOfLines = 0;
  40. [self addSubview:self.inputTextView];
  41. [self.inputTextView addSubview:self.placeholderLabel];
  42. }
  43. return self;
  44. }
  45. #pragma mark - Private
  46. - (UIToolbar *)createToolBar
  47. {
  48. UIToolbar *toolBar = [UIToolbar new];
  49. [toolBar sizeToFit];
  50. UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc]
  51. initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
  52. target:nil action:nil
  53. ];
  54. UIBarButtonItem *pasteItem = [[UIBarButtonItem alloc]
  55. initWithTitle:@"Paste" style:UIBarButtonItemStyleDone
  56. target:self.inputTextView action:@selector(paste:)
  57. ];
  58. UIBarButtonItem *doneItem = [[UIBarButtonItem alloc]
  59. initWithBarButtonSystemItem:UIBarButtonSystemItemDone
  60. target:self.inputTextView action:@selector(resignFirstResponder)
  61. ];
  62. toolBar.items = @[spaceItem, pasteItem, doneItem];
  63. return toolBar;
  64. }
  65. - (void)setInputPlaceholderText:(NSString *)placeholder
  66. {
  67. self.placeholderLabel.text = placeholder;
  68. if (placeholder.length) {
  69. if (!self.inputTextView.text.length) {
  70. self.placeholderLabel.hidden = NO;
  71. } else {
  72. self.placeholderLabel.hidden = YES;
  73. }
  74. } else {
  75. self.placeholderLabel.hidden = YES;
  76. }
  77. [self setNeedsLayout];
  78. }
  79. - (NSString *)inputPlaceholderText
  80. {
  81. return self.placeholderLabel.text;
  82. }
  83. #pragma mark - Superclass Overrides
  84. - (BOOL)inputViewIsFirstResponder
  85. {
  86. return self.inputTextView.isFirstResponder;
  87. }
  88. #pragma mark - Layout and Sizing
  89. - (void)layoutSubviews
  90. {
  91. [super layoutSubviews];
  92. self.inputTextView.frame = CGRectMake(0, self.topInputFieldVerticalLayoutGuide, self.bounds.size.width, [self inputTextViewHeight]);
  93. // Placeholder label is positioned by insetting origin,
  94. // which is the line fragment padding for X and 0 for Y,
  95. // by the content inset then the text container inset
  96. CGFloat leading = self.inputTextView.textContainer.lineFragmentPadding;
  97. CGSize s = self.inputTextView.frame.size;
  98. self.placeholderLabel.frame = CGRectMake(leading, 0, s.width, s.height);
  99. self.placeholderLabel.frame = UIEdgeInsetsInsetRect(
  100. UIEdgeInsetsInsetRect(self.placeholderLabel.frame, self.inputTextView.contentInset),
  101. self.inputTextView.textContainerInset
  102. );
  103. }
  104. - (NSUInteger)numberOfInputLines
  105. {
  106. switch (self.targetSize) {
  107. case FLEXArgumentInputViewSizeDefault:
  108. return 2;
  109. case FLEXArgumentInputViewSizeSmall:
  110. return 1;
  111. case FLEXArgumentInputViewSizeLarge:
  112. return 8;
  113. }
  114. }
  115. - (CGFloat)inputTextViewHeight
  116. {
  117. return ceil([[self class] inputFont].lineHeight * self.numberOfInputLines) + 16.0;
  118. }
  119. - (CGSize)sizeThatFits:(CGSize)size
  120. {
  121. CGSize fitSize = [super sizeThatFits:size];
  122. fitSize.height += [self inputTextViewHeight];
  123. return fitSize;
  124. }
  125. #pragma mark - Class Helpers
  126. + (UIFont *)inputFont
  127. {
  128. return [UIFont systemFontOfSize:14.0];
  129. }
  130. #pragma mark - UITextViewDelegate
  131. - (void)textViewDidChange:(UITextView *)textView
  132. {
  133. [self.delegate argumentInputViewValueDidChange:self];
  134. self.placeholderLabel.hidden = !(self.inputPlaceholderText.length && !textView.text.length);
  135. }
  136. @end