// // IQTextView.m // https://github.com/hackiftekhar/IQKeyboardManager // Copyright (c) 2013-16 Iftekhar Qurashi. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. #import "IQTextView.h" #import #import #import #import @interface IQTextView () @property(nullable, nonatomic, strong) UILabel *IQ_PlaceholderLabel; @end @implementation IQTextView @synthesize placeholder = _placeholder; @synthesize IQ_PlaceholderLabel = _IQ_PlaceholderLabel; @synthesize placeholderTextColor = _placeholderTextColor; -(void)initialize { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshPlaceholder) name:UITextViewTextDidChangeNotification object:self]; } -(void)dealloc { [_IQ_PlaceholderLabel removeFromSuperview]; _IQ_PlaceholderLabel = nil; [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (instancetype)init { self = [super init]; if (self) { [self initialize]; } return self; } -(void)awakeFromNib { [super awakeFromNib]; [self initialize]; } -(void)refreshPlaceholder { if([[self text] length] || [[self attributedText] length]) { if (self.IQ_PlaceholderLabel.alpha != 0) { [self.IQ_PlaceholderLabel setAlpha:0]; [self setNeedsLayout]; [self layoutIfNeeded]; } } else if(self.IQ_PlaceholderLabel.alpha != 1) { [self.IQ_PlaceholderLabel setAlpha:1]; [self setNeedsLayout]; [self layoutIfNeeded]; } } - (void)setText:(NSString *)text { [super setText:text]; [self refreshPlaceholder]; } -(void)setAttributedText:(NSAttributedString *)attributedText { [super setAttributedText:attributedText]; [self refreshPlaceholder]; } -(void)setFont:(UIFont *)font { [super setFont:font]; self.IQ_PlaceholderLabel.font = self.font; [self setNeedsLayout]; [self layoutIfNeeded]; } -(void)setTextAlignment:(NSTextAlignment)textAlignment { [super setTextAlignment:textAlignment]; self.IQ_PlaceholderLabel.textAlignment = textAlignment; [self setNeedsLayout]; [self layoutIfNeeded]; } -(void)layoutSubviews { [super layoutSubviews]; self.IQ_PlaceholderLabel.frame = [self placeholderExpectedFrame]; } -(void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; self.IQ_PlaceholderLabel.text = placeholder; [self refreshPlaceholder]; } -(void)setAttributedPlaceholder:(NSAttributedString *)attributedPlaceholder { _attributedPlaceholder = attributedPlaceholder; self.IQ_PlaceholderLabel.attributedText = attributedPlaceholder; [self refreshPlaceholder]; } -(void)setPlaceholderTextColor:(UIColor*)placeholderTextColor { _placeholderTextColor = placeholderTextColor; self.IQ_PlaceholderLabel.textColor = placeholderTextColor; } -(UIEdgeInsets)placeholderInsets { return UIEdgeInsetsMake(self.textContainerInset.top, self.textContainerInset.left + self.textContainer.lineFragmentPadding, self.textContainerInset.bottom, self.textContainerInset.right + self.textContainer.lineFragmentPadding); } -(CGRect)placeholderExpectedFrame { UIEdgeInsets placeholderInsets = [self placeholderInsets]; CGFloat maxWidth = CGRectGetWidth(self.frame)-placeholderInsets.left-placeholderInsets.right; CGSize expectedSize = [self.IQ_PlaceholderLabel sizeThatFits:CGSizeMake(maxWidth, CGRectGetHeight(self.frame)-placeholderInsets.top-placeholderInsets.bottom)]; return CGRectMake(placeholderInsets.left, placeholderInsets.top, maxWidth, expectedSize.height); } -(UILabel*)IQ_PlaceholderLabel { if (_IQ_PlaceholderLabel == nil) { _IQ_PlaceholderLabel = [[UILabel alloc] init]; _IQ_PlaceholderLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight); _IQ_PlaceholderLabel.lineBreakMode = NSLineBreakByWordWrapping; _IQ_PlaceholderLabel.numberOfLines = 0; _IQ_PlaceholderLabel.font = self.font; _IQ_PlaceholderLabel.textAlignment = self.textAlignment; _IQ_PlaceholderLabel.backgroundColor = [UIColor clearColor]; _IQ_PlaceholderLabel.isAccessibilityElement = NO; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000 if (@available(iOS 13.0, *)) { _IQ_PlaceholderLabel.textColor = [UIColor systemGrayColor]; } else #endif { _IQ_PlaceholderLabel.textColor = [UIColor lightTextColor]; } _IQ_PlaceholderLabel.alpha = 0; [self addSubview:_IQ_PlaceholderLabel]; } return _IQ_PlaceholderLabel; } //When any text changes on textField, the delegate getter is called. At this time we refresh the textView's placeholder -(id)delegate { [self refreshPlaceholder]; return [super delegate]; } -(CGSize)intrinsicContentSize { if (self.hasText) { return [super intrinsicContentSize]; } UIEdgeInsets placeholderInsets = [self placeholderInsets]; CGSize newSize = [super intrinsicContentSize]; newSize.height = [self placeholderExpectedFrame].size.height + placeholderInsets.top + placeholderInsets.bottom; return newSize; } @end