Giter VIP home page Giter VIP logo

cltokeninputview's Introduction

CLTokenInputView

Image Screencap GFY

About

CLTokenInputView is an almost pixel perfect replica of the input portion iOS's native contacts picker, used in Mail.app and Messages.app when composing a new message.

Check out the sample view controller which uses CLTokenInputView to see how to incorporate it into your UI. We use this in our apps at Cluster Labs, Inc..

Check out a Swift port of this library by @rlaferla.

Note

It does not provide the autocomplete drop down and matching; you must provide that yourself, so that CLTokenInputView can remain very generic and flexible. You can copy what the sample app is doing to show an autocompleting table view and maintain a list of the selected "tokens".

Usage

To run the example project, clone the repo, and open the Xcode project. You should use this on iOS 7 and up.

To use this in your code, you should add an instance of CLTokenInputView to your view hierarchy. Typically it should be anchored to the top of your UI and to the sides. Using Autolayout CLTokenInputView can grow by itself, but if you need to control it manually, you can use the delegate.

You should implement:

- (void)tokenInputView:(CLTokenInputView *)view didChangeText:(NSString *)text 
{
	// Update your autocompletion table results with the text
}

When the user taps on one of your autocomplete items, you should call: -addToken: on token input view. Example:

NSString *name = self.filteredNames[indexPath.row];
CLToken *token = [[CLToken alloc] initWithDisplayText:name context:nil];
[self.tokenInputView addToken:token];

Be sure to listen for:

- (void)tokenInputView:(CLTokenInputView *)view didAddToken:(CLToken *)token;
- (void)tokenInputView:(CLTokenInputView *)view didRemoveToken:(CLToken *)token;

...and update your local data model of selected items.

Lastly, you can implement:

- (CLToken *)tokenInputView:(CLTokenInputView *)view tokenForText:(NSString *)text 
{
	// Return a CLToken instance that matches the text that has been entered.
	// Return nil if nothing matches
}

... so that a user can typically select the first result in your autocomplete.

Customization

CLTokenInputView is customizable using:

  • tintColor — Adjust the selection and text colors.
  • fieldView — (Optional) View to show to the top left of the tokens.
  • fieldName — (Optional, but recommended) Text to show before the token list (e.g. "To:")
  • placeholderText — (Optional, but recommended) Text to show as a hint for the text field.
  • accessoryView — (Optional) View to show on the top right. (Often to launch a contact picker, like in Mail.app).
  • keyboardType — Adjust the keyboard type (UIKeyboardType).
  • autocapitalizationType — Adjust the capitalization behavior (UITextAutocapitalizationType).
  • autocorrectionType — Adjust the autocorrection behavior (UITextAutocorrectionType).
  • drawBottomBorder — Set to YES if CLTokenInputView should draw a native-style border below itself.

Things I'd Like To Do:

  • Build the "collapsed" mode like in Mail.app which replaces the token UI with "[first-item] and N more"
  • Call search about 150ms after pausing typing
  • Scroll text field into position after typing
  • (Maybe?) Look into adding a very generic, flexible autocomplete UI?

Installation

CLTokenInputView is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "CLTokenInputView"

Or, you can take all the .h and .m files from CLTokenInputView/CLTokenInputView.

Author

Cluster Labs, Inc., [email protected]

License

CLTokenInputView is available under the MIT license. See the LICENSE file for more info.

cltokeninputview's People

Contributors

ali-mir avatar grantjbutler avatar rsattar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cltokeninputview's Issues

Crash when hitting backspace

Hi guys,

I'm having a weird crash, when hitting backspace and having at least one token view.

Here's the crash.

*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x7f9241d61490> should have parent view controller:<ContactsSelectionViewController: 0x7f9241cbbc80> but requested parent is:<UIInputWindowController: 0x7f924201ac00>'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010b538f45 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x000000010af89deb objc_exception_throw + 48
    2   CoreFoundation                      0x000000010b538e7d +[NSException raise:format:] + 205
    3   UIKit                               0x0000000109760f50 -[UIViewController _addChildViewController:performHierarchyCheck:notifyWillMove:] + 321
    4   UIKit                               0x0000000109f17845 -[UIInputWindowController changeToInputViewSet:] + 473
    5   UIKit                               0x0000000109f18ad8 __43-[UIInputWindowController setInputViewSet:]_block_invoke_21239 + 39
    6   UIKit                               0x0000000109f10806 -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] + 369
    7   UIKit                               0x0000000109f18aab __43-[UIInputWindowController setInputViewSet:]_block_invoke1238 + 98
    8   UIKit                               0x0000000109f0c968 -[UIInputWindowController performOperations:withTemplateNotificationInfo:] + 42
    9   UIKit                               0x0000000109f18765 -[UIInputWindowController setInputViewSet:] + 1194
    10  UIKit                               0x0000000109f1048e -[UIInputWindowController performOperations:withAnimationStyle:] + 50
    11  UIKit                               0x0000000109c1ad85 -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] + 1179
    12  UIKit                               0x00000001097d6bc1 -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] + 81
    13  UIKit                               0x00000001097d3bea -[UIResponder becomeFirstResponder] + 617
    14  UIKit                               0x000000010966da1b -[UIView(Hierarchy) becomeFirstResponder] + 138
    15  hyp                                 0x00000001054d0ded -[CLTokenView setSelected:animated:] + 125
    16  hyp                                 0x00000001054ce33e -[CLTokenInputView selectTokenView:animated:] + 142
    17  hyp                                 0x00000001054cd920 __48-[CLTokenInputView textFieldDidDeleteBackwards:]_block_invoke + 240

Basically it's triggered at [self becomeFirstResponder]; in

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    if (_selected == selected) {
        return;
    }
    _selected = selected;

    if (selected) {
        [self becomeFirstResponder];
    }
    CGFloat selectedAlpha = (_selected ? 1.0 : 0.0);
    if (animated) {
        if (_selected) {
            self.selectedBackgroundView.alpha = 0.0;
            self.selectedBackgroundView.hidden = NO;
            self.selectedLabel.alpha = 0.0;
            self.selectedLabel.hidden = NO;
        }
        [UIView animateWithDuration:0.25 animations:^{
            self.selectedBackgroundView.alpha = selectedAlpha;
            self.selectedLabel.alpha = selectedAlpha;
        } completion:^(BOOL finished) {
            if (!_selected) {
                self.selectedBackgroundView.hidden = YES;
                self.selectedLabel.hidden = YES;
            }
        }];
    } else {
        self.selectedBackgroundView.hidden = !_selected;
        self.selectedLabel.hidden = !_selected;
    }
}

Any ideas?
thanks !

Detect return key

How can I detect the return key being pressed? I want to add a token when user hits return

Decoration image

I expect the primary purpose of this widget is to provide as close to a 1:1 match with the native widget, but it would be nice to allow for a decoration item on a token.

In the case of using this for addressees it would be nice for the following purposes:

  1. distinguish between users and groups
  2. potentially load small thumbnail (such as gravitar)
  3. distinguish between states/statuses/etc

how do you use removeTokenAtIndex

im doing something like:

//remove all tokens
let tokens = searchTypeView.tokens

    print("total tokens \(tokens.count)")

    for (i, v) in searchTypeView.tokens.enumerate() {
        print("remove toen \(i)")

        print(v)

        searchTypeView.removeToken(v)

    }

why does it crash?

Separate enter & backspace behavior when highlighted

When a token is highlighted is it possible to have different behavior when the return key is pressed as opposed to the backspace key? I don't want the return key to delete the token, just to resign the keyboard.

Backspace in a token Deletes two characters

Pressing backspace will deletes two characters at same time. I using it as single & multiple tokens, and as normal textField and all are separate instances for my usecase. I am working for iOS 8 and above.

Thank You.

Active text input overlaps previous token

Hi there, thank you very much for this library.

I'm wondering how to deal with this behavior:

demo

Ideally the text field should grow instead of going behind the previous token. I was noticing that func tokenInputView(_ view: CLTokenInputView, didChangeHeightTo height: CGFloat) is not called when the text could wrap to the next line.

Is this a bug, intended behavior, and/or has someone found a way to address this?

Right To Left language issues

Hi,

There are some issues related to RTL languages such as Arabic.

  1. The tokens are laid out from left to right.
  2. While deleting arabic tokens, there shows a slight visual glitch in selected token.

Is there a way to fix these? Can you guide me where to look into?

simulator screen shot jul 18 2016 6 34 15 pm

height problem when token removed

Not every time, but sometimes removing token generates problem with it's height.
When there are two tokens are removing first one generating problem.
I've added background of CLTokenInputView, so can track height of same.
Also blinking cursor's position is not correct. Please see attached screenshot.
image

Select previous token when remove all inserted letters

I create an token and then i insert one letter. After that when i delete the letter the previous token is automatically selected, and after that when i want to insert some tex, the selected previous token is replaced with the text. How can i avoid to automatically selecting previous token when delete all input text?

`fieldLabel` Font Size Issue

I'm attempting to find a good solution for customizing the font of the fieldName label (fieldLabel). With #9 implemented (thank you), I'm able to customize the font of the tokens and input text as follows:

[UITextField appearanceWhenContainedIn:[CLTokenInputView class], nil].font = [UIFont italicSystemFontOfSize:20];

I hoped to be able to do the same for the label using the following:

[UILabel appearanceWhenContainedIn:[CLTokenInputView class], nil].font = [UIFont italicSystemFontOfSize:20];

But this produces the following results in your sample application (notice the truncated labels):

simulator screen shot oct 21 2015 6 22 58 pm

I've added those two lines to the beginning of -viewDidLoad in CLTokenInputViewController.m.

I've added a temporary work around to my app by setting fieldName to nil and back to it's intended value on the next run loop cycle inside of [[NSOperationQueue mainQueue] addOperationWithBlock:...], but this solution is less than ideal, and leads to further layout issues with the text insertion point after rotating the interface.

Do you have any recommendations for a solution or a fix in mind? I'd like to support dynamic type, and allow the field label to grow and shrink like the tokens and input text.

Also, thank you very much for the hard work on CLTokenInputView!

Incorrect height of TokenInputView

In few cases (like the one in attached screenshot) the height for particular TokenInputView is incorrect. Can anyone tell me whats wrong and how can I fix this?
This screenshot is taken from same this very project.
simulator screen shot 17-apr-2017 12 12 40 pm

Supporting accessibility - Larger text in ios

When we entered a number in the input field and pressed return key in the keyboard the added number font is not increasing to the current font size.

When using a large font size, the message entry text box itself keeps the default font. In the native, the message composer also switches to a large font.

Similarly, when using a large font size, the whole "new message" composer and the add participants screen do not follow the larger font size and remain on default - screenshots below are taking with the largest font size setting but look as if I was on the default size (only the "New Message" header appears to have taken a larger font size).

MicrosoftTeams-image (40)
MicrosoftTeams-image (41) (1)
MicrosoftTeams-image (41)

Request to support the accessibility.
I am waiting for the response .

change delimiter (feature request)

Hi, it would be super handy to be able to specify the token delimiter. IN my personal use case, being able to suppress it all together (or set it to ' ') would make the one instance where people can only add a single item much tidier.

Limit height or change direction scroll???

Hello, I am using tokenInputView but I have a question: How can I limit the height of tokenView when I add so many CLToken into it, or I want change direction scoll when available?? Please help me

Cocoapods and use_frameworks

Hi. Great job with this library. I've used it before on other projects. However now I'm having a little problem when using it with swift.

I installed the library using cocoapods and imported the framework in my bridge file as #import <CLTokenInputView/CLTokenInputView.h> (I need to use the use_frameworks flag for other frameworks I'm using in my project). Even though the bridge file is not complaining, I can't see CLTokenInputView from my swift classes.

What am I doing wrong?

Thanks for your help in advance.

[Feature] Coloring each token and get focus

I thought this would be an excellent welcome to the party like how the messages app separates text message contacts as green and iMessage contacts as blue. I've made a pull request #35 that adds this functionality.

Cheers
Tim

An optional forwarding Delegate for return key

@rsattar
I've modified the code inside CLTokenInputView.m to resign keyboard like below.

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self endEditing:YES];
    return YES;
}

To end editing when user taps on Return key..

But isn't it grateful if we have an optional delegate.!!

Separate by comma

If I type jeff,, it'd be great if CLTokenInputView had the option to separate on that delimiter, not just return. Otherwise, people type jeff, and hit enter, and are left with jeff, in the token view.

A way to make CLTokenInputView scroll?

Hi there, really enjoying the library, but was wondering about a feature. My view is constrained to a cell, so it has a fixed height which it will never grow past. Is there a way that it can be made to scroll, if the content size is greater than the view's bounds?

I didn't see a clear way to implement it the demo, nor when reading through the code.

Thanks a lot!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.