Skip to content

Commit 495c4a6

Browse files
committed
Merge pull request slackhq#284 from slackhq/asynch-auto-completion
Allows asynch auto-completion. Closes slackhq#278
2 parents db7301a + 2b72e2b commit 495c4a6

File tree

3 files changed

+120
-91
lines changed

3 files changed

+120
-91
lines changed

Examples/Messenger-Shared/MessageViewController.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -452,11 +452,9 @@ - (BOOL)canShowTypingIndicator
452452
#endif
453453
}
454454

455-
- (BOOL)canShowAutoCompletion
455+
- (void)didChangeAutoCompletionPrefix:(NSString *)prefix andWord:(NSString *)word
456456
{
457457
NSArray *array = nil;
458-
NSString *prefix = self.foundPrefix;
459-
NSString *word = self.foundWord;
460458

461459
self.searchResult = nil;
462460

@@ -481,7 +479,9 @@ - (BOOL)canShowAutoCompletion
481479

482480
self.searchResult = [[NSMutableArray alloc] initWithArray:array];
483481

484-
return self.searchResult.count > 0;
482+
BOOL show = (self.searchResult.count > 0);
483+
484+
[self showAutoCompletionView:show];
485485
}
486486

487487
- (CGFloat)heightForAutoCompletionView

Source/Classes/SLKTextViewController.h

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,9 @@ NS_CLASS_AVAILABLE_IOS(7_0) @interface SLKTextViewController : UIViewController
372372
/** The table view used to display autocompletion results. */
373373
@property (nonatomic, readonly) UITableView *autoCompletionView;
374374

375+
/** YES if the autocompletion mode is active. */
376+
@property (nonatomic, readonly, getter = isAutoCompleting) BOOL autoCompleting;
377+
375378
/** The recently found prefix symbol used as prefix for autocompletion mode. */
376379
@property (nonatomic, readonly, copy) NSString *foundPrefix;
377380

@@ -381,27 +384,44 @@ NS_CLASS_AVAILABLE_IOS(7_0) @interface SLKTextViewController : UIViewController
381384
/** The recently found word at the text view's caret position. */
382385
@property (nonatomic, readonly, copy) NSString *foundWord;
383386

384-
/** YES if the autocompletion mode is active. */
385-
@property (nonatomic, readonly, getter = isAutoCompleting) BOOL autoCompleting;
386-
387387
/** An array containing all the registered prefix strings for autocompletion. */
388388
@property (nonatomic, readonly, copy) NSArray *registeredPrefixes;
389389

390390
/**
391391
Registers any string prefix for autocompletion detection, useful for user mentions and/or hashtags autocompletion.
392392
The prefix must be valid NSString (i.e: '@', '#', '\', and so on). This also checks if no repeated prefix is inserted.
393+
You can also use longer prefixes.
393394
394395
@param prefixes An array of prefix strings.
395396
*/
396397
- (void)registerPrefixesForAutoCompletion:(NSArray *)prefixes;
397398

399+
/**
400+
Notifies the view controller either the autocompletion prefix or word have changed.
401+
Use this method to modify your data source or fetch data asynchronously from an HTTP resource.
402+
Once your data source is ready, make sure to call -showAutoCompletionView: to display the view accordingly.
403+
You don't need call super since this method doesn't do anything.
404+
405+
@param prefix The detected prefix.
406+
@param word The derected word.
407+
*/
408+
- (void)didChangeAutoCompletionPrefix:(NSString *)prefix andWord:(NSString *)word;
409+
410+
/**
411+
Use this method to programatically show/hide the autocompletion view.
412+
Right before the view is shown, -reloadData is called. So avoid calling it manually.
413+
414+
@param show YES if the autocompletion view should be shown.
415+
*/
416+
- (void)showAutoCompletionView:(BOOL)show;
417+
398418
/**
399419
Verifies that the autocompletion view should be shown. Default is NO.
400420
To enabled autocompletion, you MUST override this method to perform additional tasks, before the autocompletion view is shown (i.e. populating the data source).
401421
402422
@return YES if the autocompletion view should be shown.
403423
*/
404-
- (BOOL)canShowAutoCompletion;
424+
- (BOOL)canShowAutoCompletion DEPRECATED_MSG_ATTRIBUTE("Override -didChangeAutoCompletionPrefix:andWord: instead");
405425

406426
/**
407427
Returns a custom height for the autocompletion view. Default is 0.0.

Source/Classes/SLKTextViewController.m

Lines changed: 92 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,7 @@ - (void)editText:(NSString *)text
718718
// Brings up the keyboard if needed
719719
[self presentKeyboard:YES];
720720
}
721+
721722
- (void)didCommitTextEditing:(id)sender
722723
{
723724
if (!self.textInputbar.isEditing) {
@@ -760,11 +761,6 @@ - (BOOL)canShowTypingIndicator
760761
return YES;
761762
}
762763

763-
- (BOOL)canShowAutoCompletion
764-
{
765-
return NO;
766-
}
767-
768764
- (CGFloat)heightForAutoCompletionView
769765
{
770766
return 0.0;
@@ -1549,6 +1545,95 @@ - (void)registerPrefixesForAutoCompletion:(NSArray *)prefixes
15491545
_registeredPrefixes = [[NSArray alloc] initWithArray:array];
15501546
}
15511547

1548+
- (void)didChangeAutoCompletionPrefix:(NSString *)prefix andWord:(NSString *)word
1549+
{
1550+
// No implementation here. Meant to be overriden in subclass.
1551+
}
1552+
1553+
- (BOOL)canShowAutoCompletion
1554+
{
1555+
// Let's keep this around for a bit, for backwards compatibility.
1556+
return NO;
1557+
}
1558+
1559+
- (void)showAutoCompletionView:(BOOL)show
1560+
{
1561+
// Reloads the tableview before showing/hiding
1562+
if (show) {
1563+
[self.autoCompletionView reloadData];
1564+
}
1565+
1566+
self.autoCompleting = show;
1567+
1568+
// Toggles auto-correction if requiered
1569+
[self slk_enableTypingSuggestionIfNeeded];
1570+
1571+
CGFloat viewHeight = show ? [self heightForAutoCompletionView] : 0.0;
1572+
1573+
if (self.autoCompletionViewHC.constant == viewHeight) {
1574+
return;
1575+
}
1576+
1577+
// If the auto-completion view height is bigger than the maximum height allows, it is reduce to that size. Default 140 pts.
1578+
CGFloat maximumHeight = [self maximumHeightForAutoCompletionView];
1579+
1580+
if (viewHeight > maximumHeight) {
1581+
viewHeight = maximumHeight;
1582+
}
1583+
1584+
CGFloat contentViewHeight = self.scrollViewHC.constant + self.autoCompletionViewHC.constant;
1585+
1586+
// On iPhone, the auto-completion view can't extend beyond the content view height
1587+
if (SLK_IS_IPHONE && viewHeight > contentViewHeight) {
1588+
viewHeight = contentViewHeight;
1589+
}
1590+
1591+
self.autoCompletionViewHC.constant = viewHeight;
1592+
1593+
[self.view slk_animateLayoutIfNeededWithBounce:self.bounces
1594+
options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionLayoutSubviews|UIViewAnimationOptionBeginFromCurrentState
1595+
animations:NULL];
1596+
}
1597+
1598+
- (void)acceptAutoCompletionWithString:(NSString *)string
1599+
{
1600+
[self acceptAutoCompletionWithString:string keepPrefix:YES];
1601+
}
1602+
1603+
- (void)acceptAutoCompletionWithString:(NSString *)string keepPrefix:(BOOL)keepPrefix
1604+
{
1605+
if (string.length == 0) {
1606+
return;
1607+
}
1608+
1609+
SLKTextView *textView = self.textView;
1610+
1611+
NSUInteger location = self.foundPrefixRange.location;
1612+
if (keepPrefix) {
1613+
location += self.foundPrefixRange.length;
1614+
}
1615+
1616+
NSUInteger length = self.foundWord.length;
1617+
if (!keepPrefix) {
1618+
length += self.foundPrefixRange.length;
1619+
}
1620+
1621+
NSRange range = NSMakeRange(location, length);
1622+
NSRange insertionRange = [textView slk_insertText:string inRange:range];
1623+
1624+
textView.selectedRange = NSMakeRange(insertionRange.location, 0);
1625+
1626+
[self cancelAutoCompletion];
1627+
1628+
[textView slk_scrollToCaretPositonAnimated:NO];
1629+
}
1630+
1631+
- (void)cancelAutoCompletion
1632+
{
1633+
[self slk_invalidateAutoCompletion];
1634+
[self slk_hideAutoCompletionViewIfNeeded];
1635+
}
1636+
15521637
- (void)slk_processTextForAutoCompletion
15531638
{
15541639
if (self.isTransitioning) {
@@ -1617,13 +1702,7 @@ - (void)slk_handleProcessedWord:(NSString *)word range:(NSRange)range
16171702
return [self cancelAutoCompletion];
16181703
}
16191704

1620-
[self slk_showAutoCompletionView:[self canShowAutoCompletion]];
1621-
}
1622-
1623-
- (void)cancelAutoCompletion
1624-
{
1625-
[self slk_invalidateAutoCompletion];
1626-
[self slk_hideAutoCompletionViewIfNeeded];
1705+
[self didChangeAutoCompletionPrefix:self.foundPrefix andWord:self.foundWord];
16271706
}
16281707

16291708
- (void)slk_invalidateAutoCompletion
@@ -1635,81 +1714,11 @@ - (void)slk_invalidateAutoCompletion
16351714
[self.autoCompletionView setContentOffset:CGPointZero];
16361715
}
16371716

1638-
- (void)acceptAutoCompletionWithString:(NSString *)string
1639-
{
1640-
[self acceptAutoCompletionWithString:string keepPrefix:YES];
1641-
}
1642-
1643-
- (void)acceptAutoCompletionWithString:(NSString *)string keepPrefix:(BOOL)keepPrefix
1644-
{
1645-
if (string.length == 0) {
1646-
return;
1647-
}
1648-
1649-
SLKTextView *textView = self.textView;
1650-
1651-
NSUInteger location = self.foundPrefixRange.location;
1652-
if (keepPrefix) {
1653-
location += self.foundPrefixRange.length;
1654-
}
1655-
1656-
NSUInteger length = self.foundWord.length;
1657-
if (!keepPrefix) {
1658-
length += self.foundPrefixRange.length;
1659-
}
1660-
1661-
NSRange range = NSMakeRange(location, length);
1662-
NSRange insertionRange = [textView slk_insertText:string inRange:range];
1663-
1664-
textView.selectedRange = NSMakeRange(insertionRange.location, 0);
1665-
1666-
[self cancelAutoCompletion];
1667-
1668-
[textView slk_scrollToCaretPositonAnimated:NO];
1669-
}
1670-
16711717
- (void)slk_hideAutoCompletionViewIfNeeded
16721718
{
16731719
if (self.isAutoCompleting) {
1674-
[self slk_showAutoCompletionView:NO];
1675-
}
1676-
}
1677-
1678-
- (void)slk_showAutoCompletionView:(BOOL)show
1679-
{
1680-
// Reloads the tableview before showing/hiding
1681-
[self.autoCompletionView reloadData];
1682-
1683-
self.autoCompleting = show;
1684-
1685-
// Toggles auto-correction if requiered
1686-
[self slk_enableTypingSuggestionIfNeeded];
1687-
1688-
CGFloat viewHeight = show ? [self heightForAutoCompletionView] : 0.0;
1689-
1690-
if (self.autoCompletionViewHC.constant == viewHeight) {
1691-
return;
1720+
[self showAutoCompletionView:NO];
16921721
}
1693-
1694-
// If the auto-completion view height is bigger than the maximum height allows, it is reduce to that size. Default 140 pts.
1695-
CGFloat maximumHeight = [self maximumHeightForAutoCompletionView];
1696-
1697-
if (viewHeight > maximumHeight) {
1698-
viewHeight = maximumHeight;
1699-
}
1700-
1701-
CGFloat contentViewHeight = self.scrollViewHC.constant + self.autoCompletionViewHC.constant;
1702-
1703-
// On iPhone, the auto-completion view can't extend beyond the content view height
1704-
if (SLK_IS_IPHONE && viewHeight > contentViewHeight) {
1705-
viewHeight = contentViewHeight;
1706-
}
1707-
1708-
self.autoCompletionViewHC.constant = viewHeight;
1709-
1710-
[self.view slk_animateLayoutIfNeededWithBounce:self.bounces
1711-
options:UIViewAnimationOptionCurveEaseInOut|UIViewAnimationOptionLayoutSubviews|UIViewAnimationOptionBeginFromCurrentState
1712-
animations:NULL];
17131722
}
17141723

17151724

0 commit comments

Comments
 (0)