http://git-wip-us.apache.org/repos/asf/usergrid/blob/c638c774/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextView.m ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextView.m b/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextView.m deleted file mode 100644 index a1433b7..0000000 --- a/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextView.m +++ /dev/null @@ -1,1117 +0,0 @@ -// -// Copyright 2014 Slack Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import "SLKTextView.h" - -#import "SLKTextView+SLKAdditions.h" - -#import "SLKUIConstants.h" - -NSString * const SLKTextViewTextWillChangeNotification = @"SLKTextViewTextWillChangeNotification"; -NSString * const SLKTextViewContentSizeDidChangeNotification = @"SLKTextViewContentSizeDidChangeNotification"; -NSString * const SLKTextViewSelectedRangeDidChangeNotification = @"SLKTextViewSelectedRangeDidChangeNotification"; -NSString * const SLKTextViewDidPasteItemNotification = @"SLKTextViewDidPasteItemNotification"; -NSString * const SLKTextViewDidShakeNotification = @"SLKTextViewDidShakeNotification"; - -NSString * const SLKTextViewPastedItemContentType = @"SLKTextViewPastedItemContentType"; -NSString * const SLKTextViewPastedItemMediaType = @"SLKTextViewPastedItemMediaType"; -NSString * const SLKTextViewPastedItemData = @"SLKTextViewPastedItemData"; - -static NSString *const SLKTextViewGenericFormattingSelectorPrefix = @"slk_format_"; - -@interface SLKTextView () - -// The label used as placeholder -@property (nonatomic, strong) UILabel *placeholderLabel; - -// The initial font point size, used for dynamic type calculations -@property (nonatomic) CGFloat initialFontSize; - -// The keyboard commands available for external keyboards -@property (nonatomic, strong) NSArray *keyboardCommands; - -// Used for moving the caret up/down -@property (nonatomic) UITextLayoutDirection verticalMoveDirection; -@property (nonatomic) CGRect verticalMoveStartCaretRect; -@property (nonatomic) CGRect verticalMoveLastCaretRect; - -// Used for detecting if the scroll indicator was previously flashed -@property (nonatomic) BOOL didFlashScrollIndicators; - -@property (nonatomic, strong) NSMutableArray *registeredFormattingTitles; -@property (nonatomic, strong) NSMutableArray *registeredFormattingSymbols; -@property (nonatomic, getter=isFormatting) BOOL formatting; - -@end - -@implementation SLKTextView -@synthesize delegate = _delegate; - -#pragma mark - Initialization - -- (instancetype)initWithFrame:(CGRect)frame textContainer:(NSTextContainer *)textContainer -{ - if (self = [super initWithFrame:frame textContainer:textContainer]) { - [self slk_commonInit]; - } - return self; -} - -- (instancetype)initWithCoder:(NSCoder *)coder -{ - if (self = [super initWithCoder:coder]) { - [self slk_commonInit]; - } - return self; -} - -- (void)slk_commonInit -{ - _pastableMediaTypes = SLKPastableMediaTypeNone; - _dynamicTypeEnabled = YES; - - self.undoManagerEnabled = YES; - self.autoCompleteFormatting = YES; - - self.editable = YES; - self.selectable = YES; - self.scrollEnabled = YES; - self.scrollsToTop = NO; - self.directionalLockEnabled = YES; - self.dataDetectorTypes = UIDataDetectorTypeNone; - - [self slk_registerNotifications]; - - [self addObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize)) options:NSKeyValueObservingOptionNew context:NULL]; -} - - -#pragma mark - UIView Overrides - -- (CGSize)intrinsicContentSize -{ - CGFloat height = self.font.lineHeight; - height += self.textContainerInset.top + self.textContainerInset.bottom; - - return CGSizeMake(UIViewNoIntrinsicMetric, height); -} - -+ (BOOL)requiresConstraintBasedLayout -{ - return YES; -} - -- (void)layoutIfNeeded -{ - if (!self.window) { - return; - } - - [super layoutIfNeeded]; -} - -- (void)layoutSubviews -{ - [super layoutSubviews]; - - self.placeholderLabel.hidden = [self slk_shouldHidePlaceholder]; - - if (!self.placeholderLabel.hidden) { - - [UIView performWithoutAnimation:^{ - self.placeholderLabel.frame = [self slk_placeholderRectThatFits:self.bounds]; - [self sendSubviewToBack:self.placeholderLabel]; - }]; - } -} - - -#pragma mark - Getters - -- (UILabel *)placeholderLabel -{ - if (!_placeholderLabel) { - _placeholderLabel = [UILabel new]; - _placeholderLabel.clipsToBounds = NO; - _placeholderLabel.autoresizesSubviews = NO; - _placeholderLabel.numberOfLines = 1; - _placeholderLabel.font = self.font; - _placeholderLabel.backgroundColor = [UIColor clearColor]; - _placeholderLabel.textColor = [UIColor lightGrayColor]; - _placeholderLabel.hidden = YES; - - [self addSubview:_placeholderLabel]; - } - return _placeholderLabel; -} - -- (NSString *)placeholder -{ - return self.placeholderLabel.text; -} - -- (UIColor *)placeholderColor -{ - return self.placeholderLabel.textColor; -} - -- (NSUInteger)numberOfLines -{ - CGSize contentSize = self.contentSize; - - CGFloat contentHeight = contentSize.height; - contentHeight -= self.textContainerInset.top + self.textContainerInset.bottom; - - NSUInteger lines = fabs(contentHeight/self.font.lineHeight); - - // This helps preventing the content's height to be larger that the bounds' height - // Avoiding this way to have unnecessary scrolling in the text view when there is only 1 line of content - if (lines == 1 && contentSize.height > self.bounds.size.height) { - contentSize.height = self.bounds.size.height; - self.contentSize = contentSize; - } - - // Let's fallback to the minimum line count - if (lines == 0) { - lines = 1; - } - - return lines; -} - -- (NSUInteger)maxNumberOfLines -{ - NSUInteger numberOfLines = _maxNumberOfLines; - - if (SLK_IS_LANDSCAPE) { - if ((SLK_IS_IPHONE4 || SLK_IS_IPHONE5)) { - numberOfLines = 2.0; // 2 lines max on smaller iPhones - } - else if (SLK_IS_IPHONE) { - numberOfLines /= 2.0; // Half size on larger iPhone - } - } - - if (self.isDynamicTypeEnabled) { - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; - CGFloat pointSizeDifference = [SLKTextView pointSizeDifferenceForCategory:contentSizeCategory]; - - CGFloat factor = pointSizeDifference/self.initialFontSize; - - if (fabs(factor) > 0.75) { - factor = 0.75; - } - - numberOfLines -= floorf(numberOfLines * factor); // Calculates a dynamic number of lines depending of the user preferred font size - } - - return numberOfLines; -} - -- (BOOL)isTypingSuggestionEnabled -{ - return (self.autocorrectionType == UITextAutocorrectionTypeNo) ? NO : YES; -} - -- (BOOL)autoCompleteFormatting -{ - if (_registeredFormattingSymbols.count == 0) { - return NO; - } - return _autoCompleteFormatting; -} - -// Returns only a supported pasted item -- (id)slk_pastedItem -{ - NSString *contentType = [self slk_pasteboardContentType]; - NSData *data = [[UIPasteboard generalPasteboard] dataForPasteboardType:contentType]; - - if (data && [data isKindOfClass:[NSData class]]) - { - SLKPastableMediaType mediaType = SLKPastableMediaTypeFromNSString(contentType); - - NSDictionary *userInfo = @{SLKTextViewPastedItemContentType: contentType, - SLKTextViewPastedItemMediaType: @(mediaType), - SLKTextViewPastedItemData: data}; - return userInfo; - } - if ([[UIPasteboard generalPasteboard] URL]) { - return [[[UIPasteboard generalPasteboard] URL] absoluteString]; - } - if ([[UIPasteboard generalPasteboard] string]) { - return [[UIPasteboard generalPasteboard] string]; - } - - return nil; -} - -// Checks if any supported media found in the general pasteboard -- (BOOL)slk_isPasteboardItemSupported -{ - if ([self slk_pasteboardContentType].length > 0) { - return YES; - } - return NO; -} - -- (NSString *)slk_pasteboardContentType -{ - NSArray *pasteboardTypes = [[UIPasteboard generalPasteboard] pasteboardTypes]; - NSMutableArray *subpredicates = [NSMutableArray new]; - - for (NSString *type in [self slk_supportedMediaTypes]) { - [subpredicates addObject:[NSPredicate predicateWithFormat:@"SELF == %@", type]]; - } - - return [[pasteboardTypes filteredArrayUsingPredicate:[NSCompoundPredicate orPredicateWithSubpredicates:subpredicates]] firstObject]; -} - -- (NSArray *)slk_supportedMediaTypes -{ - if (self.pastableMediaTypes == SLKPastableMediaTypeNone) { - return nil; - } - - NSMutableArray *types = [NSMutableArray new]; - - if (self.pastableMediaTypes & SLKPastableMediaTypePNG) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypePNG)]; - } - if (self.pastableMediaTypes & SLKPastableMediaTypeJPEG) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeJPEG)]; - } - if (self.pastableMediaTypes & SLKPastableMediaTypeTIFF) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeTIFF)]; - } - if (self.pastableMediaTypes & SLKPastableMediaTypeGIF) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeGIF)]; - } - if (self.pastableMediaTypes & SLKPastableMediaTypeMOV) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeMOV)]; - } - if (self.pastableMediaTypes & SLKPastableMediaTypePassbook) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypePassbook)]; - } - - if (self.pastableMediaTypes & SLKPastableMediaTypeImages) { - [types addObject:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeImages)]; - } - - return types; -} - -NSString *NSStringFromSLKPastableMediaType(SLKPastableMediaType type) -{ - if (type == SLKPastableMediaTypePNG) { - return @"public.png"; - } - if (type == SLKPastableMediaTypeJPEG) { - return @"public.jpeg"; - } - if (type == SLKPastableMediaTypeTIFF) { - return @"public.tiff"; - } - if (type == SLKPastableMediaTypeGIF) { - return @"com.compuserve.gif"; - } - if (type == SLKPastableMediaTypeMOV) { - return @"com.apple.quicktime"; - } - if (type == SLKPastableMediaTypePassbook) { - return @"com.apple.pkpass"; - } - if (type == SLKPastableMediaTypeImages) { - return @"com.apple.uikit.image"; - } - - return nil; -} - -SLKPastableMediaType SLKPastableMediaTypeFromNSString(NSString *string) -{ - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypePNG)]) { - return SLKPastableMediaTypePNG; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeJPEG)]) { - return SLKPastableMediaTypeJPEG; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeTIFF)]) { - return SLKPastableMediaTypeTIFF; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeGIF)]) { - return SLKPastableMediaTypeGIF; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeMOV)]) { - return SLKPastableMediaTypeMOV; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypePassbook)]) { - return SLKPastableMediaTypePassbook; - } - if ([string isEqualToString:NSStringFromSLKPastableMediaType(SLKPastableMediaTypeImages)]) { - return SLKPastableMediaTypeImages; - } - return SLKPastableMediaTypeNone; -} - -- (BOOL)isExpanding -{ - if (self.numberOfLines >= self.maxNumberOfLines) { - return YES; - } - return NO; -} - -- (BOOL)slk_shouldHidePlaceholder -{ - if (self.placeholder.length == 0 || self.text.length > 0) { - return YES; - } - return NO; -} - -- (CGRect)slk_placeholderRectThatFits:(CGRect)bounds -{ - CGFloat padding = self.textContainer.lineFragmentPadding; - - CGRect rect = CGRectZero; - rect.size.height = [self.placeholderLabel sizeThatFits:bounds.size].height; - rect.size.width = self.textContainer.size.width - padding*2.0; - rect.origin = UIEdgeInsetsInsetRect(bounds, self.textContainerInset).origin; - rect.origin.x += padding; - - return rect; -} - - -#pragma mark - Setters - -- (void)setPlaceholder:(NSString *)placeholder -{ - self.placeholderLabel.text = placeholder; - self.accessibilityLabel = placeholder; - - [self setNeedsLayout]; -} - -- (void)setPlaceholderColor:(UIColor *)color -{ - self.placeholderLabel.textColor = color; -} - -- (void)setUndoManagerEnabled:(BOOL)enabled -{ - if (self.undoManagerEnabled == enabled) { - return; - } - - self.undoManager.levelsOfUndo = 10; - [self.undoManager removeAllActions]; - [self.undoManager setActionIsDiscardable:YES]; - - _undoManagerEnabled = enabled; -} - -- (void)setTypingSuggestionEnabled:(BOOL)enabled -{ - if (self.isTypingSuggestionEnabled == enabled) { - return; - } - - self.autocorrectionType = enabled ? UITextAutocorrectionTypeDefault : UITextAutocorrectionTypeNo; - self.spellCheckingType = enabled ? UITextSpellCheckingTypeDefault : UITextSpellCheckingTypeNo; - - [self refreshFirstResponder]; -} - - -#pragma mark - UITextView Overrides - -- (void)setSelectedRange:(NSRange)selectedRange -{ - [super setSelectedRange:selectedRange]; -} - -- (void)setSelectedTextRange:(UITextRange *)selectedTextRange -{ - [super setSelectedTextRange:selectedTextRange]; - - [[NSNotificationCenter defaultCenter] postNotificationName:SLKTextViewSelectedRangeDidChangeNotification object:self userInfo:nil]; -} - -- (void)setText:(NSString *)text -{ - // Registers for undo management - [self slk_prepareForUndo:@"Text Set"]; - - [super setText:text]; - - [[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self]; -} - -- (void)setAttributedText:(NSAttributedString *)attributedText -{ - // Registers for undo management - [self slk_prepareForUndo:@"Attributed Text Set"]; - - [super setAttributedText:attributedText]; - - [[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:self]; -} - -- (void)setFont:(UIFont *)font -{ - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; - - [self setFontName:font.fontName pointSize:font.pointSize withContentSizeCategory:contentSizeCategory]; - - self.initialFontSize = font.pointSize; -} - -- (void)setFontName:(NSString *)fontName pointSize:(CGFloat)pointSize withContentSizeCategory:(NSString *)contentSizeCategory -{ - if (self.isDynamicTypeEnabled) { - pointSize += [SLKTextView pointSizeDifferenceForCategory:contentSizeCategory]; - } - - UIFont *dynamicFont = [UIFont fontWithName:fontName size:pointSize]; - - [super setFont:dynamicFont]; - - // Updates the placeholder font too - self.placeholderLabel.font = dynamicFont; -} - -- (void)setDynamicTypeEnabled:(BOOL)dynamicTypeEnabled -{ - if (self.isDynamicTypeEnabled == dynamicTypeEnabled) { - return; - } - - _dynamicTypeEnabled = dynamicTypeEnabled; - - NSString *contentSizeCategory = [[UIApplication sharedApplication] preferredContentSizeCategory]; - - [self setFontName:self.font.fontName pointSize:self.initialFontSize withContentSizeCategory:contentSizeCategory]; -} - -- (void)setTextAlignment:(NSTextAlignment)textAlignment -{ - [super setTextAlignment:textAlignment]; - - // Updates the placeholder text alignment too - self.placeholderLabel.textAlignment = textAlignment; -} - - -#pragma mark - UITextInput Overrides - -- (void)beginFloatingCursorAtPoint:(CGPoint)point -{ - [super beginFloatingCursorAtPoint:point]; - - _trackpadEnabled = YES; -} - -- (void)updateFloatingCursorAtPoint:(CGPoint)point -{ - [super updateFloatingCursorAtPoint:point]; -} - -- (void)endFloatingCursor -{ - [super endFloatingCursor]; - - _trackpadEnabled = NO; - - // We still need to notify a selection change in the textview after the trackpad is disabled - if (self.delegate && [self.delegate respondsToSelector:@selector(textViewDidChangeSelection:)]) { - [self.delegate textViewDidChangeSelection:self]; - } - - [[NSNotificationCenter defaultCenter] postNotificationName:SLKTextViewSelectedRangeDidChangeNotification object:self userInfo:nil]; -} - - -#pragma mark - UIResponder Overrides - -- (BOOL)canBecomeFirstResponder -{ - [self slk_addCustomMenuControllerItems]; - - return [super canBecomeFirstResponder]; -} - -- (BOOL)becomeFirstResponder -{ - return [super becomeFirstResponder]; -} - -- (BOOL)canResignFirstResponder -{ - // Removes undo/redo items - if (self.undoManagerEnabled) { - [self.undoManager removeAllActions]; - } - - return [super canResignFirstResponder]; -} - -- (BOOL)resignFirstResponder -{ - return [super resignFirstResponder]; -} - -- (BOOL)canPerformAction:(SEL)action withSender:(id)sender -{ - if (self.isFormatting) { - NSString *title = [self slk_formattingTitleFromSelector:action]; - NSString *symbol = [self slk_formattingSymbolWithTitle:title]; - - if (symbol.length > 0) { - if (self.delegate && [self.delegate respondsToSelector:@selector(textView:shouldOfferFormattingForSymbol:)]) { - return [self.delegate textView:self shouldOfferFormattingForSymbol:symbol]; - } - else { - return YES; - } - } - - return NO; - } - - if (action == @selector(delete:)) { - return NO; - } - - if (action == NSSelectorFromString(@"_share:") || action == NSSelectorFromString(@"_define:") || action == NSSelectorFromString(@"_promptForReplace:")) { - return NO; - } - - if (action == @selector(slk_presentFormattingMenu:)) { - return self.selectedRange.length > 0 ? YES : NO; - } - - if (action == @selector(paste:) && [self slk_isPasteboardItemSupported]) { - return YES; - } - - if (action == @selector(paste:) && [self slk_isPasteboardItemSupported]) { - return YES; - } - - if (self.undoManagerEnabled) { - if (action == @selector(slk_undo:)) { - if (self.undoManager.undoActionIsDiscardable) { - return NO; - } - return [self.undoManager canUndo]; - } - if (action == @selector(slk_redo:)) { - if (self.undoManager.redoActionIsDiscardable) { - return NO; - } - return [self.undoManager canRedo]; - } - } - - return [super canPerformAction:action withSender:sender]; -} - -- (void)paste:(id)sender -{ - id pastedItem = [self slk_pastedItem]; - - if ([pastedItem isKindOfClass:[NSDictionary class]]) { - [[NSNotificationCenter defaultCenter] postNotificationName:SLKTextViewDidPasteItemNotification object:nil userInfo:pastedItem]; - } - else if ([pastedItem isKindOfClass:[NSString class]]) { - // Respect the delegate yo! - if (self.delegate && [self.delegate respondsToSelector:@selector(textView:shouldChangeTextInRange:replacementText:)]) { - if (![self.delegate textView:self shouldChangeTextInRange:self.selectedRange replacementText:pastedItem]) { - return; - } - } - - // Inserting the text fixes a UITextView bug whitch automatically scrolls to the bottom - // and beyond scroll content size sometimes when the text is too long - [self slk_insertTextAtCaretRange:pastedItem]; - } -} - - -#pragma mark - NSObject Overrides - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel -{ - if ([super methodSignatureForSelector:sel]) { - return [super methodSignatureForSelector:sel]; - } - return [super methodSignatureForSelector:@selector(slk_format:)]; -} - -- (void)forwardInvocation:(NSInvocation *)invocation -{ - NSString *title = [self slk_formattingTitleFromSelector:[invocation selector]]; - - if (title.length > 0) { - [self slk_format:title]; - } - else { - [super forwardInvocation:invocation]; - } -} - - -#pragma mark - Custom Actions - -- (void)slk_flashScrollIndicatorsIfNeeded -{ - if (self.numberOfLines == self.maxNumberOfLines+1) { - if (!_didFlashScrollIndicators) { - _didFlashScrollIndicators = YES; - [super flashScrollIndicators]; - } - } - else if (_didFlashScrollIndicators) { - _didFlashScrollIndicators = NO; - } -} - -- (void)refreshFirstResponder -{ - if (!self.isFirstResponder) { - return; - } - - _didNotResignFirstResponder = YES; - [self resignFirstResponder]; - - _didNotResignFirstResponder = NO; - [self becomeFirstResponder]; -} - -- (void)refreshInputViews -{ - _didNotResignFirstResponder = YES; - - [super reloadInputViews]; - - _didNotResignFirstResponder = NO; -} - -- (void)slk_addCustomMenuControllerItems -{ - UIMenuItem *undo = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Undo", nil) action:@selector(slk_undo:)]; - UIMenuItem *redo = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Redo", nil) action:@selector(slk_redo:)]; - UIMenuItem *format = [[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"Format", nil) action:@selector(slk_presentFormattingMenu:)]; - - [[UIMenuController sharedMenuController] setMenuItems:@[undo, redo, format]]; -} - -- (void)slk_undo:(id)sender -{ - [self.undoManager undo]; -} - -- (void)slk_redo:(id)sender -{ - [self.undoManager redo]; -} - -- (void)slk_presentFormattingMenu:(id)sender -{ - NSMutableArray *items = [NSMutableArray arrayWithCapacity:self.registeredFormattingTitles.count]; - - for (NSString *name in self.registeredFormattingTitles) { - - NSString *sel = [NSString stringWithFormat:@"%@%@", SLKTextViewGenericFormattingSelectorPrefix, name]; - - UIMenuItem *item = [[UIMenuItem alloc] initWithTitle:name action:NSSelectorFromString(sel)]; - [items addObject:item]; - } - - self.formatting = YES; - - UIMenuController *menu = [UIMenuController sharedMenuController]; - [menu setMenuItems:items]; - - NSLayoutManager *manager = self.layoutManager; - CGRect targetRect = [manager boundingRectForGlyphRange:self.selectedRange inTextContainer:self.textContainer]; - - [menu setTargetRect:targetRect inView:self]; - - [menu setMenuVisible:YES animated:YES]; -} - -- (NSString *)slk_formattingTitleFromSelector:(SEL)selector -{ - NSString *selectorString = NSStringFromSelector(selector); - NSRange match = [selectorString rangeOfString:SLKTextViewGenericFormattingSelectorPrefix]; - - if (match.location != NSNotFound) { - return [selectorString substringFromIndex:SLKTextViewGenericFormattingSelectorPrefix.length]; - } - - return nil; -} - -- (NSString *)slk_formattingSymbolWithTitle:(NSString *)title -{ - NSUInteger idx = [self.registeredFormattingTitles indexOfObject:title]; - - if (idx <= self.registeredFormattingSymbols.count -1) { - return self.registeredFormattingSymbols[idx]; - } - - return nil; -} - -- (void)slk_format:(NSString *)titles -{ - NSString *symbol = [self slk_formattingSymbolWithTitle:titles]; - - if (symbol.length > 0) { - NSRange selection = self.selectedRange; - - NSRange range = [self slk_insertText:symbol inRange:NSMakeRange(selection.location, 0)]; - range.location += selection.length; - range.length = 0; - - // The default behavior is to add a closure - BOOL addClosure = YES; - - if (self.delegate && [self.delegate respondsToSelector:@selector(textView:shouldInsertSuffixForFormattingWithSymbol:prefixRange:)]) { - addClosure = [self.delegate textView:self shouldInsertSuffixForFormattingWithSymbol:symbol prefixRange:selection]; - } - - if (addClosure) { - self.selectedRange = [self slk_insertText:symbol inRange:range]; - } - } -} - - -#pragma mark - Markdown Formatting - -- (void)registerMarkdownFormattingSymbol:(NSString *)symbol withTitle:(NSString *)title -{ - if (!symbol || !title) { - return; - } - - if (!_registeredFormattingTitles) { - _registeredFormattingTitles = [NSMutableArray new]; - _registeredFormattingSymbols = [NSMutableArray new]; - } - - // Adds the symbol if not contained already - if (![self.registeredSymbols containsObject:symbol]) { - [self.registeredFormattingTitles addObject:title]; - [self.registeredFormattingSymbols addObject:symbol]; - } -} - -- (NSArray *)registeredSymbols -{ - return self.registeredFormattingSymbols; -} - - -#pragma mark - Notification Events - -- (void)slk_didBeginEditing:(NSNotification *)notification -{ - if (![notification.object isEqual:self]) { - return; - } - - // Do something -} - -- (void)slk_didChangeText:(NSNotification *)notification -{ - if (![notification.object isEqual:self]) { - return; - } - - if (self.placeholderLabel.hidden != [self slk_shouldHidePlaceholder]) { - [self setNeedsLayout]; - } - - [self slk_flashScrollIndicatorsIfNeeded]; -} - -- (void)slk_didEndEditing:(NSNotification *)notification -{ - if (![notification.object isEqual:self]) { - return; - } - - // Do something -} - -- (void)slk_didChangeTextInputMode:(NSNotification *)notification -{ - // Do something -} - -- (void)slk_didChangeContentSizeCategory:(NSNotification *)notification -{ - if (!self.isDynamicTypeEnabled) { - return; - } - - NSString *contentSizeCategory = notification.userInfo[UIContentSizeCategoryNewValueKey]; - - [self setFontName:self.font.fontName pointSize:self.initialFontSize withContentSizeCategory:contentSizeCategory]; - - NSString *text = [self.text copy]; - - // Reloads the content size of the text view - [self setText:@" "]; - [self setText:text]; -} - -- (void)slk_willShowMenuController:(NSNotification *)notification -{ - -} - -- (void)slk_didHideMenuController:(NSNotification *)notification -{ - self.formatting = NO; - - [self slk_addCustomMenuControllerItems]; -} - - -#pragma mark - KVO Listener - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ - if ([object isEqual:self] && [keyPath isEqualToString:NSStringFromSelector(@selector(contentSize))]) { - [[NSNotificationCenter defaultCenter] postNotificationName:SLKTextViewContentSizeDidChangeNotification object:self userInfo:nil]; - } - else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - - -#pragma mark - Motion Events - -- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event -{ - if (event.type == UIEventTypeMotion && event.subtype == UIEventSubtypeMotionShake) { - [[NSNotificationCenter defaultCenter] postNotificationName:SLKTextViewDidShakeNotification object:self]; - } -} - - -#pragma mark - External Keyboard Support - -- (NSArray *)keyCommands -{ - if (_keyboardCommands) { - return _keyboardCommands; - } - - _keyboardCommands = @[ - // Return - [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:UIKeyModifierShift action:@selector(slk_didPressLineBreakKeys:)], - [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:UIKeyModifierAlternate action:@selector(slk_didPressLineBreakKeys:)], - [UIKeyCommand keyCommandWithInput:@"\r" modifierFlags:UIKeyModifierControl action:@selector(slk_didPressLineBreakKeys:)], - - // Undo/Redo - [UIKeyCommand keyCommandWithInput:@"z" modifierFlags:UIKeyModifierCommand action:@selector(slk_didPressCommandZKeys:)], - [UIKeyCommand keyCommandWithInput:@"z" modifierFlags:UIKeyModifierShift|UIKeyModifierCommand action:@selector(slk_didPressCommandZKeys:)], - ]; - - return _keyboardCommands; -} - - -#pragma mark Line Break - -- (void)slk_didPressLineBreakKeys:(id)sender -{ - [self slk_insertNewLineBreak]; -} - - -#pragma mark Undo/Redo Text - -- (void)slk_didPressCommandZKeys:(id)sender -{ - if (!self.undoManagerEnabled) { - return; - } - - UIKeyCommand *keyCommand = (UIKeyCommand *)sender; - - if ((keyCommand.modifierFlags & UIKeyModifierShift) > 0) { - - if ([self.undoManager canRedo]) { - [self.undoManager redo]; - } - } - else { - if ([self.undoManager canUndo]) { - [self.undoManager undo]; - } - } -} - -#pragma mark Up/Down Cursor Movement - -- (void)didPressAnyArrowKey:(id)sender -{ - if (self.text.length == 0 || self.numberOfLines < 2) { - return; - } - - UIKeyCommand *keyCommand = (UIKeyCommand *)sender; - - if ([keyCommand.input isEqualToString:UIKeyInputUpArrow]) { - [self slk_moveCursorTodirection:UITextLayoutDirectionUp]; - } - else if ([keyCommand.input isEqualToString:UIKeyInputDownArrow]) { - [self slk_moveCursorTodirection:UITextLayoutDirectionDown]; - } -} - -- (void)slk_moveCursorTodirection:(UITextLayoutDirection)direction -{ - UITextPosition *start = (direction == UITextLayoutDirectionUp) ? self.selectedTextRange.start : self.selectedTextRange.end; - - if ([self slk_isNewVerticalMovementForPosition:start inDirection:direction]) { - self.verticalMoveDirection = direction; - self.verticalMoveStartCaretRect = [self caretRectForPosition:start]; - } - - if (start) { - UITextPosition *end = [self slk_closestPositionToPosition:start inDirection:direction]; - - if (end) { - self.verticalMoveLastCaretRect = [self caretRectForPosition:end]; - self.selectedTextRange = [self textRangeFromPosition:end toPosition:end]; - - [self slk_scrollToCaretPositonAnimated:NO]; - } - } -} - -// Based on code from Ruben Cabaco -// https://gist.github.com/rcabaco/6765778 - -- (UITextPosition *)slk_closestPositionToPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction -{ - // Only up/down are implemented. No real need for left/right since that is native to UITextInput. - NSParameterAssert(direction == UITextLayoutDirectionUp || direction == UITextLayoutDirectionDown); - - // Translate the vertical direction to a horizontal direction. - UITextLayoutDirection lookupDirection = (direction == UITextLayoutDirectionUp) ? UITextLayoutDirectionLeft : UITextLayoutDirectionRight; - - // Walk one character at a time in `lookupDirection` until the next line is reached. - UITextPosition *checkPosition = position; - UITextPosition *closestPosition = position; - CGRect startingCaretRect = [self caretRectForPosition:position]; - CGRect nextLineCaretRect; - BOOL isInNextLine = NO; - - while (YES) { - UITextPosition *nextPosition = [self positionFromPosition:checkPosition inDirection:lookupDirection offset:1]; - - // End of line. - if (!nextPosition || [self comparePosition:checkPosition toPosition:nextPosition] == NSOrderedSame) { - break; - } - - checkPosition = nextPosition; - CGRect checkRect = [self caretRectForPosition:checkPosition]; - if (CGRectGetMidY(startingCaretRect) != CGRectGetMidY(checkRect)) { - // While on the next line stop just above/below the starting position. - if (lookupDirection == UITextLayoutDirectionLeft && CGRectGetMidX(checkRect) <= CGRectGetMidX(self.verticalMoveStartCaretRect)) { - closestPosition = checkPosition; - break; - } - if (lookupDirection == UITextLayoutDirectionRight && CGRectGetMidX(checkRect) >= CGRectGetMidX(self.verticalMoveStartCaretRect)) { - closestPosition = checkPosition; - break; - } - // But don't skip lines. - if (isInNextLine && CGRectGetMidY(checkRect) != CGRectGetMidY(nextLineCaretRect)) { - break; - } - - isInNextLine = YES; - nextLineCaretRect = checkRect; - closestPosition = checkPosition; - } - } - return closestPosition; -} - -- (BOOL)slk_isNewVerticalMovementForPosition:(UITextPosition *)position inDirection:(UITextLayoutDirection)direction -{ - CGRect caretRect = [self caretRectForPosition:position]; - BOOL noPreviousStartPosition = CGRectEqualToRect(self.verticalMoveStartCaretRect, CGRectZero); - BOOL caretMovedSinceLastPosition = !CGRectEqualToRect(caretRect, self.verticalMoveLastCaretRect); - BOOL directionChanged = self.verticalMoveDirection != direction; - - BOOL newMovement = noPreviousStartPosition || caretMovedSinceLastPosition || directionChanged; - return newMovement; -} - - -#pragma mark - NSNotificationCenter register/unregister - -- (void)slk_registerNotifications -{ - [self slk_unregisterNotifications]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didBeginEditing:) name:UITextViewTextDidBeginEditingNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didChangeText:) name:UITextViewTextDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didEndEditing:) name:UITextViewTextDidEndEditingNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didChangeTextInputMode:) name:UITextInputCurrentInputModeDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didChangeContentSizeCategory:) name:UIContentSizeCategoryDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_willShowMenuController:) name:UIMenuControllerWillShowMenuNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(slk_didHideMenuController:) name:UIMenuControllerDidHideMenuNotification object:nil]; -} - -- (void)slk_unregisterNotifications -{ - [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidBeginEditingNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextViewTextDidEndEditingNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UITextInputCurrentInputModeDidChangeNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIContentSizeCategoryDidChangeNotification object:nil]; -} - - -#pragma mark - Lifeterm - -- (void)dealloc -{ - [self slk_unregisterNotifications]; - - [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize))]; - - _placeholderLabel = nil; -} - -@end
http://git-wip-us.apache.org/repos/asf/usergrid/blob/c638c774/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextViewController.h ---------------------------------------------------------------------- diff --git a/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextViewController.h b/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextViewController.h deleted file mode 100644 index 1e429d3..0000000 --- a/sdks/swift/Samples/ActivityFeed/Pods/SlackTextViewController/Source/SLKTextViewController.h +++ /dev/null @@ -1,584 +0,0 @@ -// -// Copyright 2014 Slack Technologies, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#import <Foundation/Foundation.h> -#import <UIKit/UIKit.h> - -#import "SLKTextInputbar.h" -#import "SLKTextView.h" -#import "SLKTypingIndicatorView.h" -#import "SLKTypingIndicatorProtocol.h" - -#import "SLKTextView+SLKAdditions.h" -#import "UIScrollView+SLKAdditions.h" -#import "UIView+SLKAdditions.h" - -#import "SLKUIConstants.h" - -/** - UIKeyboard notification replacement, posting reliably only when showing/hiding the keyboard (not when resizing keyboard, or with inputAccessoryView reloads, etc). - Only triggered when using SLKTextViewController's text view. - */ -UIKIT_EXTERN NSString *const SLKKeyboardWillShowNotification; -UIKIT_EXTERN NSString *const SLKKeyboardDidShowNotification; -UIKIT_EXTERN NSString *const SLKKeyboardWillHideNotification; -UIKIT_EXTERN NSString *const SLKKeyboardDidHideNotification; - -/** - This feature doesn't work on iOS 9 due to no legit alternatives to detect the keyboard view. - Open Radar: http://openradar.appspot.com/radar?id=5021485877952512 - */ -UIKIT_EXTERN NSString *const SLKTextInputbarDidMoveNotification; - -typedef NS_ENUM(NSUInteger, SLKKeyboardStatus) { - SLKKeyboardStatusDidHide, - SLKKeyboardStatusWillShow, - SLKKeyboardStatusDidShow, - SLKKeyboardStatusWillHide -}; - -/** @name A drop-in UIViewController subclass with a growing text input view and other useful messaging features. */ -NS_CLASS_AVAILABLE_IOS(7_0) @interface SLKTextViewController : UIViewController <SLKTextViewDelegate, UITableViewDelegate, UITableViewDataSource, - UICollectionViewDelegate, UICollectionViewDataSource, - UIGestureRecognizerDelegate, UIAlertViewDelegate> - -/** The main table view managed by the controller object. Created by default initializing with -init or initWithNibName:bundle: */ -@property (nonatomic, readonly) UITableView *tableView; - -/** The main collection view managed by the controller object. Not nil if the controller is initialised with -initWithCollectionViewLayout: */ -@property (nonatomic, readonly) UICollectionView *collectionView; - -/** The main scroll view managed by the controller object. Not nil if the controller is initialised with -initWithScrollView: */ -@property (nonatomic, readonly) UIScrollView *scrollView; - -/** The bottom toolbar containing a text view and buttons. */ -@property (nonatomic, readonly) SLKTextInputbar *textInputbar; - -/** The default typing indicator used to display user names horizontally. */ -@property (nonatomic, readonly) SLKTypingIndicatorView *typingIndicatorView; - -/** - The custom typing indicator view. Default is kind of SLKTypingIndicatorView. - To customize the typing indicator view, you will need to call -registerClassForTypingIndicatorView: nside of any initialization method. - To interact with it directly, you will need to cast the return value of -typingIndicatorProxyView to the appropriate type. - */ -@property (nonatomic, readonly) UIView <SLKTypingIndicatorProtocol> *typingIndicatorProxyView; - -/** A single tap gesture used to dismiss the keyboard. SLKTextViewController is its delegate. */ -@property (nonatomic, readonly) UIGestureRecognizer *singleTapGesture; - -/** A vertical pan gesture used for bringing the keyboard from the bottom. SLKTextViewController is its delegate. */ -@property (nonatomic, readonly) UIPanGestureRecognizer *verticalPanGesture; - -/** YES if control's animation should have bouncy effects. Default is YES. */ -@property (nonatomic, assign) BOOL bounces; - -/** YES if text view's content can be cleaned with a shake gesture. Default is NO. */ -@property (nonatomic, assign) BOOL shakeToClearEnabled; - -/** - YES if keyboard can be dismissed gradually with a vertical panning gesture. Default is YES. - - This feature doesn't work on iOS 9 due to no legit alternatives to detect the keyboard view. - Open Radar: http://openradar.appspot.com/radar?id=5021485877952512 - */ -@property (nonatomic, assign, getter = isKeyboardPanningEnabled) BOOL keyboardPanningEnabled; - -/** YES if an external keyboard has been detected (this value updates only when the text view becomes first responder). */ -@property (nonatomic, readonly, getter=isExternalKeyboardDetected) BOOL externalKeyboardDetected; - -/** YES if the keyboard has been detected as undocked or split (iPad Only). */ -@property (nonatomic, readonly, getter=isKeyboardUndocked) BOOL keyboardUndocked; - -/** YES if after right button press, the text view is cleared out. Default is YES. */ -@property (nonatomic, assign) BOOL shouldClearTextAtRightButtonPress; - -/** YES if the scrollView should scroll to bottom when the keyboard is shown. Default is NO.*/ -@property (nonatomic, assign) BOOL shouldScrollToBottomAfterKeyboardShows; - -/** - YES if the main table view is inverted. Default is YES. - This allows the table view to start from the bottom like any typical messaging interface. - If inverted, you must assign the same transform property to your cells to match the orientation (ie: cell.transform = tableView.transform;) - Inverting the table view will enable some great features such as content offset corrections automatically when resizing the text input and/or showing autocompletion. - */ -@property (nonatomic, assign, getter = isInverted) BOOL inverted; - -/** YES if the view controller is presented inside of a popover controller. If YES, the keyboard won't move the text input bar and tapping on the tableView/collectionView will not cause the keyboard to be dismissed. This property is compatible only with iPad. */ -@property (nonatomic, assign, getter = isPresentedInPopover) BOOL presentedInPopover; - -/** Convenience accessors (accessed through the text input bar) */ -@property (nonatomic, readonly) SLKTextView *textView; -@property (nonatomic, readonly) UIButton *leftButton; -@property (nonatomic, readonly) UIButton *rightButton; - - -#pragma mark - Initialization -///------------------------------------------------ -/// @name Initialization -///------------------------------------------------ - -/** - Initializes a text view controller to manage a table view of a given style. - If you use the standard -init method, a table view with plain style will be created. - - @param style A constant that specifies the style of main table view that the controller object is to manage (UITableViewStylePlain or UITableViewStyleGrouped). - @return An initialized SLKTextViewController object or nil if the object could not be created. - */ -- (instancetype)initWithTableViewStyle:(UITableViewStyle)style SLK_DESIGNATED_INITIALIZER; - -/** - Initializes a collection view controller and configures the collection view with the provided layout. - If you use the standard -init method, a table view with plain style will be created. - - @param layout The layout object to associate with the collection view. The layout controls how the collection view presents its cells and supplementary views. - @return An initialized SLKTextViewController object or nil if the object could not be created. - */ -- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout SLK_DESIGNATED_INITIALIZER; - -/** - Initializes a text view controller to manage an arbitraty scroll view. The caller is responsible for configuration of the scroll view, including wiring the delegate. - - @param a UISCrollView to be used as the main content area. - @return An initialized SLKTextViewController object or nil if the object could not be created. - */ -- (instancetype)initWithScrollView:(UIScrollView *)scrollView SLK_DESIGNATED_INITIALIZER; - -/** - Initializes either a table or collection view controller. - You must override either +tableViewStyleForCoder: or +collectionViewLayoutForCoder: to define witch view to be layed out. - - @param decoder An unarchiver object. - @return An initialized SLKTextViewController object or nil if the object could not be created. - */ -- (instancetype)initWithCoder:(NSCoder *)decoder SLK_DESIGNATED_INITIALIZER; - -/** - Returns the tableView style to be configured when using Interface Builder. Default is UITableViewStylePlain. - You must override this method if you want to configure a tableView. - - @param decoder An unarchiver object. - @return The tableView style to be used in the new instantiated tableView. - */ -+ (UITableViewStyle)tableViewStyleForCoder:(NSCoder *)decoder; - -/** - Returns the tableView style to be configured when using Interface Builder. Default is nil. - You must override this method if you want to configure a collectionView. - - @param decoder An unarchiver object. - @return The collectionView style to be used in the new instantiated collectionView. - */ -+ (UICollectionViewLayout *)collectionViewLayoutForCoder:(NSCoder *)decoder; - - -#pragma mark - Keyboard Handling -///------------------------------------------------ -/// @name Keyboard Handling -///------------------------------------------------ - -/** - Presents the keyboard, if not already, animated. - You can override this method to perform additional tasks associated with presenting the keyboard. - You SHOULD call super to inherit some conditionals. - - @param animated YES if the keyboard should show using an animation. - */ -- (void)presentKeyboard:(BOOL)animated; - -/** - Dimisses the keyboard, if not already, animated. - You can override this method to perform additional tasks associated with dismissing the keyboard. - You SHOULD call super to inherit some conditionals. - - @param animated YES if the keyboard should be dismissed using an animation. - */ -- (void)dismissKeyboard:(BOOL)animated; - -/** - Verifies if the text input bar should still move up/down even if it is not first responder. Default is NO. - You can override this method to perform additional tasks associated with presenting the view. - You don't need call super since this method doesn't do anything. - - @param responder The current first responder object. - @return YES so the text input bar still move up/down. - */ -- (BOOL)forceTextInputbarAdjustmentForResponder:(UIResponder *)responder; - -/** - Verifies if the text input bar should still move up/down when it is first responder. Default is NO. - This is very useful when presenting the view controller in a custom modal presentation, when there keyboard events are being handled externally to reframe the presented view. - You SHOULD call super to inherit some conditionals. - */ -- (BOOL)ignoreTextInputbarAdjustment NS_REQUIRES_SUPER; - -/** - Notifies the view controller that the keyboard changed status. - You can override this method to perform additional tasks associated with presenting the view. - You don't need call super since this method doesn't do anything. - - @param status The new keyboard status. - */ -- (void)didChangeKeyboardStatus:(SLKKeyboardStatus)status; - - -#pragma mark - Interaction Notifications -///------------------------------------------------ -/// @name Interaction Notifications -///------------------------------------------------ - -/** - Notifies the view controller that the text will update. - You can override this method to perform additional tasks associated with text changes. - You MUST call super at some point in your implementation. - */ -- (void)textWillUpdate NS_REQUIRES_SUPER; - -/** - Notifies the view controller that the text did update. - You can override this method to perform additional tasks associated with text changes. - You MUST call super at some point in your implementation. - - @param If YES, the text input bar will be resized using an animation. - */ -- (void)textDidUpdate:(BOOL)animated NS_REQUIRES_SUPER; - -/** - Notifies the view controller that the text selection did change. - Use this method a replacement of UITextViewDelegate's -textViewDidChangeSelection: which is not reliable enough when using third-party keyboards (they don't forward events properly sometimes). - - You can override this method to perform additional tasks associated with text changes. - You MUST call super at some point in your implementation. - */ -- (void)textSelectionDidChange NS_REQUIRES_SUPER; - -/** - Notifies the view controller when the left button's action has been triggered, manually. - You can override this method to perform additional tasks associated with the left button. - You don't need call super since this method doesn't do anything. - - @param sender The object calling this method. - */ -- (void)didPressLeftButton:(id)sender; - -/** - Notifies the view controller when the right button's action has been triggered, manually or by using the keyboard return key. - You can override this method to perform additional tasks associated with the right button. - You MUST call super at some point in your implementation. - - @param sender The object calling this method. - */ -- (void)didPressRightButton:(id)sender NS_REQUIRES_SUPER; - -/** - Verifies if the right button can be pressed. If NO, the button is disabled. - You can override this method to perform additional tasks. You SHOULD call super to inherit some conditionals. - - @return YES if the right button can be pressed. - */ -- (BOOL)canPressRightButton; - -/** - Notifies the view controller when the user has pasted a supported media content (images and/or videos). - You can override this method to perform additional tasks associated with image/video pasting. You don't need to call super since this method doesn't do anything. - Only supported pastable medias configured in SLKTextView will be forwarded (take a look at SLKPastableMediaType). - - @para userInfo The payload containing the media data, content and media types. - */ -- (void)didPasteMediaContent:(NSDictionary *)userInfo; - -/** - Verifies that the typing indicator view should be shown. Default is YES, if meeting some requierements. - You can override this method to perform additional tasks. - You SHOULD call super to inherit some conditionals. - - @return YES if the typing indicator view should be presented. - */ -- (BOOL)canShowTypingIndicator; - -/** - Notifies the view controller when the user has shaked the device for undoing text typing. - You can override this method to perform additional tasks associated with the shake gesture. - Calling super will prompt a system alert view with undo option. This will not be called if 'undoShakingEnabled' is set to NO and/or if the text view's content is empty. - */ -- (void)willRequestUndo; - -/** - Notifies the view controller when the user has pressed the Return key (âµ) with an external keyboard. - You can override this method to perform additional tasks. - You MUST call super at some point in your implementation. - */ -- (void)didPressReturnKey:(id)sender NS_REQUIRES_SUPER; - -/** - Notifies the view controller when the user has pressed the Escape key (Esc) with an external keyboard. - You can override this method to perform additional tasks. - You MUST call super at some point in your implementation. - */ -- (void)didPressEscapeKey:(id)sender NS_REQUIRES_SUPER; - -/** - Notifies the view controller when the user has pressed the arrow key with an external keyboard. - You can override this method to perform additional tasks. - You MUST call super at some point in your implementation. - */ -- (void)didPressArrowKey:(id)sender NS_REQUIRES_SUPER; - - -#pragma mark - Text Input Bar Adjustment -///------------------------------------------------ -/// @name Text Input Bar Adjustment -///------------------------------------------------ - -/** YES if the text inputbar is hidden. Default is NO. */ -@property (nonatomic, getter=isTextInputbarHidden) BOOL textInputbarHidden; - -/** - Changes the visibility of the text input bar. - Calling this method with the animated parameter set to NO is equivalent to setting the value of the toolbarHidden property directly. - - @param hidden Specify YES to hide the toolbar or NO to show it. - @param animated Specify YES if you want the toolbar to be animated on or off the screen. - */ -- (void)setTextInputbarHidden:(BOOL)hidden animated:(BOOL)animated; - - -#pragma mark - Text Edition -///------------------------------------------------ -/// @name Text Edition -///------------------------------------------------ - -/** YES if the text editing mode is active. */ -@property (nonatomic, readonly, getter = isEditing) BOOL editing; - -/** - Re-uses the text layout for edition, displaying an accessory view on top of the text input bar with options (cancel & save). - You can override this method to perform additional tasks - You MUST call super at some point in your implementation. - - @param text The string text to edit. - */ -- (void)editText:(NSString *)text NS_REQUIRES_SUPER; - -/** - Notifies the view controller when the editing bar's right button's action has been triggered, manually or by using the external keyboard's Return key. - You can override this method to perform additional tasks associated with accepting changes. - You MUST call super at some point in your implementation. - - @param sender The object calling this method. - */ -- (void)didCommitTextEditing:(id)sender NS_REQUIRES_SUPER; - -/** - Notifies the view controller when the editing bar's right button's action has been triggered, manually or by using the external keyboard's Esc key. - You can override this method to perform additional tasks associated with accepting changes. - You MUST call super at some point in your implementation. - - @param sender The object calling this method. - */ -- (void)didCancelTextEditing:(id)sender NS_REQUIRES_SUPER; - - -#pragma mark - Text Auto-Completion -///------------------------------------------------ -/// @name Text Auto-Completion -///------------------------------------------------ - -/** The table view used to display autocompletion results. */ -@property (nonatomic, readonly) UITableView *autoCompletionView; - -/** YES if the autocompletion mode is active. */ -@property (nonatomic, readonly, getter = isAutoCompleting) BOOL autoCompleting; - -/** The recently found prefix symbol used as prefix for autocompletion mode. */ -@property (nonatomic, readonly, copy) NSString *foundPrefix; - -/** The range of the found prefix in the text view content. */ -@property (nonatomic, readonly) NSRange foundPrefixRange; - -/** The recently found word at the text view's caret position. */ -@property (nonatomic, readonly, copy) NSString *foundWord; - -/** An array containing all the registered prefix strings for autocompletion. */ -@property (nonatomic, readonly, copy) NSArray *registeredPrefixes; - -/** - Registers any string prefix for autocompletion detection, useful for user mentions and/or hashtags autocompletion. - The prefix must be valid string (i.e: '@', '#', '\', and so on). This also checks if no repeated prefix are inserted. - Prefixes can be of any length. - - @param prefixes An array of prefix strings. - */ -- (void)registerPrefixesForAutoCompletion:(NSArray *)prefixes; - -/** - Notifies the view controller either the autocompletion prefix or word have changed. - Use this method to modify your data source or fetch data asynchronously from an HTTP resource. - Once your data source is ready, make sure to call -showAutoCompletionView: to display the view accordingly. - You don't need call super since this method doesn't do anything. - - @param prefix The detected prefix. - @param word The derected word. - */ -- (void)didChangeAutoCompletionPrefix:(NSString *)prefix andWord:(NSString *)word; - -/** - Use this method to programatically show/hide the autocompletion view. - Right before the view is shown, -reloadData is called. So avoid calling it manually. - - @param show YES if the autocompletion view should be shown. - */ -- (void)showAutoCompletionView:(BOOL)show; - -/** - Verifies that the autocompletion view should be shown. Default is NO. - To enabled autocompletion, you MUST override this method to perform additional tasks, before the autocompletion view is shown (i.e. populating the data source). - - @return YES if the autocompletion view should be shown. - */ -- (BOOL)canShowAutoCompletion DEPRECATED_MSG_ATTRIBUTE("Override -didChangeAutoCompletionPrefix:andWord: instead"); - -/** - Returns a custom height for the autocompletion view. Default is 0.0. - You can override this method to return a custom height. - - @return The autocompletion view's height. - */ -- (CGFloat)heightForAutoCompletionView; - -/** - Returns the maximum height for the autocompletion view. Default is 140 pts. - You can override this method to return a custom max height. - - @return The autocompletion view's max height. - */ -- (CGFloat)maximumHeightForAutoCompletionView; - -/** - Cancels and hides the autocompletion view, animated. - */ -- (void)cancelAutoCompletion; - -/** - Accepts the autocompletion, replacing the detected word with a new string, keeping the prefix. - This method is a convinience of -acceptAutoCompletionWithString:keepPrefix: - - @param string The string to be used for replacing autocompletion placeholders. - */ -- (void)acceptAutoCompletionWithString:(NSString *)string; - -/** - Accepts the autocompletion, replacing the detected word with a new string, and optionally replacing the prefix too. - - @param string The string to be used for replacing autocompletion placeholders. - @param keepPrefix YES if the prefix shouldn't be overidden. - */ -- (void)acceptAutoCompletionWithString:(NSString *)string keepPrefix:(BOOL)keepPrefix; - - -#pragma mark - Text Caching -///------------------------------------------------ -/// @name Text Caching -///------------------------------------------------ - -/** - Returns the key to be associated with a given text to be cached. Default is nil. - To enable text caching, you must override this method to return valid key. - The text view will be populated automatically when the view controller is configured. - You don't need to call super since this method doesn't do anything. - - @return The string key for which to enable text caching. - */ -- (NSString *)keyForTextCaching; - -/** - Removes the current's vien controller cached text. - To enable this, you must return a valid key string in -keyForTextCaching. - */ -- (void)clearCachedText; - -/** - Removes all the cached text from disk. - */ -+ (void)clearAllCachedText; - - -#pragma mark - Customization -///------------------------------------------------ -/// @name Customization -///------------------------------------------------ - -/** - Registers a class for customizing the behavior and appearance of the text view. - You need to call this method inside of any initialization method. - - @param aClass A SLKTextView subclass. - */ -- (void)registerClassForTextView:(Class)aClass; - -/** - Registers a class for customizing the behavior and appearance of the typing indicator view. - You need to call this method inside of any initialization method. - Make sure to conform to SLKTypingIndicatorProtocol and implement the required methods. - - @param aClass A UIView subclass conforming to the SLKTypingIndicatorProtocol. - */ -- (void)registerClassForTypingIndicatorView:(Class)aClass; - - -#pragma mark - Delegate Methods Requiring Super -///------------------------------------------------ -/// @name Delegate Methods Requiring Super -///------------------------------------------------ - -/** UITextViewDelegate */ -- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text NS_REQUIRES_SUPER; - -/** SLKTextViewDelegate */ -- (BOOL)textView:(SLKTextView *)textView shouldInsertSuffixForFormattingWithSymbol:(NSString *)symbol prefixRange:(NSRange)prefixRange NS_REQUIRES_SUPER; - -/** UIScrollViewDelegate */ -- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView NS_REQUIRES_SUPER; -- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate NS_REQUIRES_SUPER; -- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView NS_REQUIRES_SUPER; -- (void)scrollViewDidScroll:(UIScrollView *)scrollView NS_REQUIRES_SUPER; - -/** UIGestureRecognizerDelegate */ -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer NS_REQUIRES_SUPER; - -/** UIAlertViewDelegate */ -#ifndef __IPHONE_8_0 -- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex NS_REQUIRES_SUPER; -#endif - -#pragma mark - Life Cycle Methods Requiring Super -///------------------------------------------------ -/// @name Life Cycle Methods Requiring Super -///------------------------------------------------ - -/** - Configures view hierarchy and layout constraints. If you override these methods, make sure to call super. - */ -- (void)loadView NS_REQUIRES_SUPER; -- (void)viewDidLoad NS_REQUIRES_SUPER; -- (void)viewWillAppear:(BOOL)animated NS_REQUIRES_SUPER; -- (void)viewDidAppear:(BOOL)animated NS_REQUIRES_SUPER; -- (void)viewWillDisappear:(BOOL)animated NS_REQUIRES_SUPER; -- (void)viewDidDisappear:(BOOL)animated NS_REQUIRES_SUPER; -- (void)viewWillLayoutSubviews NS_REQUIRES_SUPER; -- (void)viewDidLayoutSubviews NS_REQUIRES_SUPER; - -@end