An iOS text field that represents tags, hashtags, tokens in general.

Overview

WSTagsField

Carthage Compatible SwiftPM Compatible CocoaPods Compatible Swift 5.1 Platforms iOS Build Status License MIT

An iOS text field that represents tags, hashtags, tokens in general.

WSTagsField

Usage

let tagsField = WSTagsField()
tagsField.layoutMargins = UIEdgeInsets(top: 2, left: 6, bottom: 2, right: 6)
tagsField.contentInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
tagsField.spaceBetweenLines = 5.0
tagsField.spaceBetweenTags = 10.0
tagsField.font = .systemFont(ofSize: 12.0)
tagsField.backgroundColor = .white
tagsField.tintColor = .green
tagsField.textColor = .black
tagsField.fieldTextColor = .blue
tagsField.selectedColor = .black
tagsField.selectedTextColor = .red
tagsField.delimiter = ","
tagsField.isDelimiterVisible = true
tagsField.placeholderColor = .green
tagsField.placeholderAlwaysVisible = true
tagsField.keyboardAppearance = .dark
tagsField.returnKeyType = .next
tagsField.acceptTagOption = .space
tagsField.shouldTokenizeAfterResigningFirstResponder = true

// Events
tagsField.onDidAddTag = { field, tag in
    print("DidAddTag", tag.text)
}

tagsField.onDidRemoveTag = { field, tag in
    print("DidRemoveTag", tag.text)
}

tagsField.onDidChangeText = { _, text in
    print("DidChangeText")
}

tagsField.onDidChangeHeightTo = { _, height in
    print("HeightTo", height)
}

tagsField.onValidateTag = { tag, tags in
    // custom validations, called before tag is added to tags list
    return tag.text != "#" && !tags.contains(where: { $0.text.uppercased() == tag.text.uppercased() })
}

print("List of Tags Strings:", tagsField.tags.map({$0.text}))

Installation

Carthage

To install it, simply add the following line to your Cartfile:

github "whitesmith/WSTagsField"

Then run carthage update.

Follow the current instructions in Carthage's README for up to date installation instructions.

CocoaPods

To install it, simply add the following line to your Podfile:

pod "WSTagsField"

Then run pod install with CocoaPods 1.8.0 or newer.

Swift Package Manager

Using Xcode 11, just go to "File" > "Swift Packages" > "Add Package Dependency..." and use this repository: https://github.com/whitesmith/WSTagsField.

Manually

Download all the source files and drop them into your project.

Requirements

  • iOS 9.0+
  • Xcode 11 (Swift 5.1)

Contributing

The best way to contribute is by submitting a pull request. We'll do our best to respond to your patch as soon as possible. You can also submit a new GitHub issue if you find bugs or have questions. :octocat:

Credits

Whitesmith

This project was inspired by CLTokenInputView.

Comments
  • Not working in static TableViewController Cell

    Not working in static TableViewController Cell

    It freezes my TableViewController when i subclass the TextField to WSTagsField in the Storyboard, and i get the below error after the app stops

    Discarding message for event 1 because of too many unprocessed messages 2017-03-13 16:56:26.713355 LocationApp[46653:475740] [Client] Discarding message for event 27 because of too many unprocessed messages (lldb)

    i try subclassing in my TableViewController class only, like this @IBOutlet weak var tagsTextField: WSTagsField! But its not putting the text in tags, treating it like normal TextField

    bug 
    opened by moderateepheezy 16
  • does not work auto-increment cell

    does not work auto-increment cell

    `

    tableviewcell:
     @IBOutlet weak var tagsView: UIView!
    
    tableviewcontroller:
    
            cell = tableView.dequeueReusableCell(withIdentifier: "tagField", for: indexPath) as! AddManuallyRecipeTableViewCell
    
            let tagsView = cell.tagsView!
            let tagsField = WSTagsField()
            
            tagsField.frame = tagsView.bounds
            tagsView.addSubview(tagsField)
            
            tagsField.layer.cornerRadius = 3.0
            tagsField.font = .systemFont(ofSize: 14.0)
            tagsField.placeholder = "Добавить тэг ..."
            tagsField.returnKeyType = .next
            tagsField.delimiter = " "
    
            tagsField.onDidChangeHeightTo = { _, height in
                print("HeightTo \(height)")
                
                tableView.beginUpdates()
                tableView.endUpdates()
                
            }
    

    `

    2018-02-21 14 02 11

    how to fix?

    opened by aleksandr-govorukhin 12
  • Keyboard Appearance reverting to default on delete

    Keyboard Appearance reverting to default on delete

    Which version of the WSTagsField are you using?

    E.g. 1.0.11

    On which platform does the issue happen?

    iOS11

    Are you using Cocoapods?

    Yes, up to date version

    Which version of Xcode are you using?

    Xcode 11.0

    What did you expect to happen?

    I expect the keyboard to stay what Ive set it to. ie, maintain .dark appearance

    What happened instead?

    When deleting a WSTagField the keyboard reverts to default keyboard.

    opened by tristanmellett 8
  • Use Cases When Integrating WSTagsField In Search Bar

    Use Cases When Integrating WSTagsField In Search Bar

    I have a few questions about how to correctly integrate WSTagsField as a search field:

    1. If backspace is pressed for a partially entered text, a tag with that partial text will be added automatically. Can I disable this feature? Is editing allowed when inputing the tag?
    2. Is there any way to access the index of a specific that is generated?
    opened by justinguo 8
  • How to add observer for the WSTagsField

    How to add observer for the WSTagsField

    I created ViewController including WSTagsFields. When I dismiss the current ViewController, it shows Error related to the observer for the WSTagsFields. How can I fix this? Please have a look at the attachments. image_2019_10_30T16_42_47_267Z

    opened by alexander1031 7
  • Crashes occur in iOS versions except for iOS13

    Crashes occur in iOS versions except for iOS13

    Which version of the WSTagsField are you using?

    5.1.0

    On which platform does the issue happen?

    Except for iOS13

    Are you using Carthage?

    ❯ carthage version
    0.33.0
    

    Which version of Xcode are you using?

    ❯ xcodebuild -version
    Xcode 11.0
    Build version 11A420a
    

    What did you do?

    I had observed that WSTagsField 4.x.x crashes in iOS13. I replace its version to latest one, then crashes disappear in iOS13, but on the other hand crashes occur in iOS versions except for iOS13. It seems to crash when OS recycle the cells which use WSTagsField.

    opened by Masaokb 7
  • If select tag and pickker image

    If select tag and pickker image

    What did you do?

    When i choose image from library wstagfield is cach.

    open var selected: Bool = false {
            didSet {
                if selected && !isFirstResponder {
                    _ = becomeFirstResponder()
                } else
                if !selected && isFirstResponder {
                    _ = resignFirstResponder()
                }
                updateContent(animated: true)
            }
        }
    

    What did you expect to happen?

    don't cach when pickker image **If i want select tag is delete tag. Did you know

    What happened instead?

    error cach

    opened by Skyzwing 6
  • It's not removing the `layerBoundsObserver` correctly in iOS 11

    It's not removing the `layerBoundsObserver` correctly in iOS 11

    Which version of the WSTagsField are you using?

    3.1

    On which platform does the issue happen?

    iOS11

    Are you using Carthage?

    no

    Are you using Cocoapods?

    1.5.3

    Which version of Xcode are you using?

    Xcode 9.4.1 Build version 9F2000

    What did you do?

    its good idea to remove Observer in ios 11 , please check . https://stackoverflow.com/questions/46782372/ios-11-what-the-kvo-is-retaining-all-observers-of-this-object-if-it-crashes-an

    code :
    deinit {
            if ProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11,let observer = layerBoundsObserver {
                print("removeObserver")
                removeObserver(observer, forKeyPath: "layer.bounds")
            }
    
    we need to remove Observer in ios 11 ,so i change the code to 
    
    deinit {
            if let observer = layerBoundsObserver {
                print("removeObserver")
                removeObserver(observer, forKeyPath: "layer.bounds")
            }
    
    thank  you
    bug 
    opened by abufaeys 6
  • Base class changed to `UIScrollView`, animate selection, detect tags automatically by delimiter, etc.

    Base class changed to `UIScrollView`, animate selection, detect tags automatically by delimiter, etc.

    • code style fixes, configured to work with SwiftLint;
    • animation of tag selection;
    • base class changed from UIView to UIScrollView and added maxHeight parameter - if tags height more than this value scrolling will appear;
    • detect automatically tags by specified delimiter + bool value to show/hide delimiter;
    • fixed sample application (need to be improved in the future);
    opened by krezzoid 6
  • inputFieldAccessoryView with ContainerView (with UIViewController)  problem

    inputFieldAccessoryView with ContainerView (with UIViewController) problem

    Hi, You can download example project here: https://goo.gl/iLtxY5 Issue reproduce steps; 1- Run project 2- Add one or more tag 3- Select one tag and delete it.

    Error; 'UIViewControllerHierarchyInconsistency', reason: 'child view controller should have parent view controller:<UICompatibilityInputViewController: 0x7fc56dd4eca0> but actual parent is...

    I read a lot of documents but i can't find solution.

    awaiting input 
    opened by hamzauzumcu 6
  • Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <_NSKeyValueObservation 0x600001be8150> for the key path because it is not registered as an observer.'">

    Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <_NSKeyValueObservation 0x600001be8150> for the key path "layer.bounds" from because it is not registered as an observer.'

    iOS 13 beta 3 Xcode Version 11.0 beta (11M336w)

    Looks like this issue happens during removeObserver into deist of class WSTagsField deinit { if let observer = layerBoundsObserver { removeObserver(observer, forKeyPath: "layer.bounds") observer.invalidate() } }

    Screen Shot 2019-07-16 at 3 21 31 PM
    opened by mroffmix 5
  • Give developer chance to deal with pasted content

    Give developer chance to deal with pasted content

    I want to allow users to paste bunch of tags into a WSTagsField in my project, like "Apple Pear Banana". onDidChangeText isn't enough to check if the content is coming from pasteboard or not for this use case.

    opened by porter-liu 0
  • MemoryLeak

    MemoryLeak

    On which platform does the issue happen?

    E.g. iOS15

    Are you using Cocoapods?

    Yes, Updated version

    Which version of Xcode are you using?

    Xcode 14

    What did you do?

    I am getting memory leak in WSTagsFields init layerBoundsObserver = self.observe(.layer.bounds, options: [.old, .new]) { [weak self] sender, change in guard change.oldValue?.size.width != change.newValue?.size.width else { return } self?.repositionViews() }

    opened by mazzharr 0
  • App stucks when the text field is tapped and the keyboard appears (iOS 15 - iPhone 7)

    App stucks when the text field is tapped and the keyboard appears (iOS 15 - iPhone 7)

    I tried to make a demo app with WSTagsField. However when the app launches and the field is tapped and the keyboard appears, memory taken by the app start increasing by leaps and bounds without stopping and the app stucks - i.e. stops responding. I found out that the repositionViews is being called again and again endlessly. Can you fix this asap please?

    opened by mibrahim025 7
  • Change color of Pointer and tags background color.

    Change color of Pointer and tags background color.

    Currently, when we change the tint color, the color of the pointer and tags background changed. I want to show different pointer and tags background colors.

    opened by m-junaid-butt 1
  • SwiftUI app crash on invalidateIntrinsicContentSize()

    SwiftUI app crash on invalidateIntrinsicContentSize()

    Which version of the WSTagsField are you using?

    SPM 5.4.0

    On which platform does the issue happen?

    iOS 14.5

    Are you using Carthage?

    No

    Are you using Cocoapods?

    No

    Which version of Xcode are you using?

    Version 12.5.1 (12E507)

    What did you do?

    I created WSTagsField asUIViewRepresentable in its simplest form and put it in the Form in Section shown by .fullscreenCover() from the parent view.

    struct HashtagsTextField: UIViewRepresentable {
        
        private enum Constants {
            static let layoutMargins = UIEdgeInsets(top: 2, left: 6, bottom: 2, right: 6)
            static let contentInstet = UIEdgeInsets(top: 10, left: 0, bottom: 10, right: 16)
            static let spaceBetweenLines: CGFloat = 5.0
            static let spaceBetweenTags: CGFloat = 10.0
        }
        
        // MARK: - Stored Properties
        
        @Binding private(set) var text: String
        let placeholder: String
        
        private let tagsField = WSTagsField()
        
        // MARK: - Methods
        
        func makeUIView(context: Context) -> WSTagsField {
            tagsField.layoutMargins = Constants.layoutMargins
            tagsField.contentInset = Constants.contentInstet
            tagsField.spaceBetweenLines = Constants.spaceBetweenLines
            tagsField.spaceBetweenTags = Constants.spaceBetweenTags
            tagsField.font = .systemFont(ofSize: 17.0)
            tagsField.backgroundColor = .clear
            tagsField.tintColor = UIColor(named: "darkBrown")
            tagsField.textColor = .white
            tagsField.selectedColor = UIColor(named: "darkBrown")
            tagsField.selectedTextColor = .white
            tagsField.isDelimiterVisible = true
            tagsField.placeholderColor = UIColor(named: "text")
            tagsField.placeholderAlwaysVisible = false
            tagsField.acceptTagOption = .space
            tagsField.shouldTokenizeAfterResigningFirstResponder = true
            return tagsField
        }
        
        func updateUIView(_ uiView: WSTagsField, context: Context) {
            uiView.text = text
        }
        
    }
    

    What did you expect to happen?

    App doesn't crash when fullScreenCover disappears (maybe it's time to make SwiftUI version of this field?).

    What happened instead?

    When WSTagsField (as UIViewRepresentable) is in the Section in Form as the content of the .fullScreenCover() and the view disappears (via presentationMode environment), the app crashes every time.

    opened by tryboxx 0
Releases(5.4.0)
  • 5.4.0(Jul 31, 2020)

    Changes included:

    • Changed access to tagViews to open to allow manipulation of specific tags views, i.e. tintColor (#143). Thanks @cdf1982.
    • Added shouldTokenizeAfterResigningFirstResponder flag (#141). Thanks @rizwan95.
    • Add prebuilt binaries for Xcode 11.6.

    CocoaPods

    pod 'WSTagsField', '~> 5.4'
    

    Carthage

    github "whitesmith/WSTagsField" ~> 5.4
    
    Source code(tar.gz)
    Source code(zip)
    WSTagsField.framework.zip(3.64 MB)
  • 5.3.1(May 1, 2020)

  • 5.3.0(May 1, 2020)

  • 5.2.0(Nov 5, 2019)

  • 5.1.1(Oct 3, 2019)

  • 5.1.0(Sep 18, 2019)

    Changes included:

    • Added support for Swift Package Manager 🎉
    • Added compatibility with iOS 13 (Xcode 11).
    • Improved compatibility with textFieldShouldReturn delegate method.
    • Removed deprecated properties.
    • Fixed keyboard appearance reverting to default when TagView is selected (#121)

    CocoaPods

    pod 'WSTagsField', '~> 5.1'
    

    Carthage

    github "whitesmith/WSTagsField" ~> 5.1
    
    Source code(tar.gz)
    Source code(zip)
    WSTagsField.framework.zip(3.54 MB)
  • 5.0.0(May 7, 2019)

  • 4.1.0(Feb 21, 2019)

  • 4.0.0(Sep 14, 2018)

  • 3.2.0(Sep 14, 2018)

    Changes

    • Fix of KVO_IS_RETAINING_ALL_OBSERVERS_OF_THIS_OBJECT_IF_IT_CRASHES_AN_OBSERVER_WAS_OVERRELEASED_OR_SMASHED crash #103 & #101
    • #99 Add an option to stop WSTagsField from becoming scrollable (ty @bellebethcooper)
    • #95 Make keyboard appearance type open (ty @tim289)
    Source code(tar.gz)
    Source code(zip)
  • 3.1.0(Apr 9, 2018)

    Changes

    • By default, the return key is used to create a tag in the field. Now, you can change it and use the comma or the space key instead: tagsField.acceptTagOption = .space.
    • onDidEndEditing and onDidBeginEditing events were removed in favor of UITextFieldDelegate methods (textFieldDidBeginEditing(textField:) and textFieldDidEndEditing(textField:)). The delegate should be assigned to the textDelegate property and it's related with the input text field. It's also a nice way to have access to textFieldShouldReturn(textField:) where it's possible to change the first responder when the return key is free (i.e.: tagsField.acceptTagOption = .comma is set).
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Apr 9, 2018)

    Breaking changes

    • padding property is now using the standard contentInset property of UIView. So, padding has been deprecated.
    • displayDelimiter has been renamed to isDelimiterVisible.
    • tagCornerRadius has been renamed to cornerRadius.
    • placeholderAlwayVisible has been renamed to placeholderAlwaysVisible.

    Changes

    • You can now define the size of the TagView by defining a margin of type UIEdgeInsets to layoutMargins property.
    • You can now define a max number of lines by using the numberOfLines property.
    • You can now define the space between lines using the spaceBetweenLines property.

    Fixes

    • #65 layout issues in an UITableView.

    Thanks 🎉💪🙌

    @billzhou0223, @griffinmacias, @matsune, @nicol3a and @CharlesAbouYakzan for the amazing API improvements and fixes. @krezzoid for the conversion and improvements for Swift 4.0.

    Source code(tar.gz)
    Source code(zip)
  • 2.1.2(Jul 7, 2017)

  • 2.1.1(Apr 7, 2017)

  • 1.3.0(Apr 9, 2018)

    Please use the swift2.3 branch for now.

    CocoaPods

    pod 'WSTagsField', :git => 'https://github.com/whitesmith/WSTagsField.git', :branch => 'swift2.3'
    

    or just add swift_version = '2.3' to your Podfile:

    target 'AmazingProject' do
      swift_version = '2.3'
      pod 'WSTagsField', '~>1.2.0'
    end
    

    Carthage

    github "whitesmith/WSTagsField" "swift2.3"
    

    or just run carthage with Swift 2.3 toolchain:

    carthage update WSTagsField --no-use-binaries --platform iOS --toolchain
    com.apple.dt.toolchain.Swift_2_3
    
    Source code(tar.gz)
    Source code(zip)
  • 1.2.5(Apr 7, 2017)

  • 1.2.4(Apr 7, 2017)

  • 2.1.0(Jan 6, 2017)

  • 2.0.1(Jan 6, 2017)

    ⚠️ Missed CocoaPod update.

    • Fix #30: add keyboard return key type (ty @ShiWeiCN)
    • Fix #29: switching readonly on and off (ty @treyrich)
    • Fix #25: add inputFieldAccessoryView property
    • Fix #24: add onDidSelectTagView and onDidUnselectTagView event
    • Enhancement: add selectNextTag and selectPrevTag methods
    Source code(tar.gz)
    Source code(zip)
    WSTagsField.framework.zip(1.68 MB)
  • 2.0.0(Sep 30, 2016)

  • 2.0.0.beta.1(Aug 26, 2016)

    Features

    • Adds Swift 3.0 compatibility.

    Instructions

    Carthage

    github "whitesmith/WSTagsField" "2.0.0.beta.1"
    

    CocoaPods

    pod "WSTagsField", :git => 'https://github.com/whitesmith/WSTagsField.git', :tag => '2.0.0.beta.1'
    

    Note: Ready for CocoaPods 1.1.0.beta.1 version (gem install cocoapods --pre).

    For more information please see the updated README.

    Source code(tar.gz)
    Source code(zip)
  • 1.2.3(Aug 18, 2016)

  • 1.2.2(Jul 29, 2016)

  • 1.2.1(Jul 15, 2016)

  • 1.2(Jul 15, 2016)

  • 1.1.1(Jul 4, 2016)

  • 1.1(Jul 4, 2016)

  • 1.0(Jul 4, 2016)

Owner
Whitesmith
Digital Product and Innovation Studio
Whitesmith
DGFadingLabel - A custom UILabel that fades away the end of your text when text is too large to fit within the label's frame

A custom UILabel that fades away the end of your text when text is too large to fit within the label's frame.

donggyu 4 Jun 10, 2022
UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images.

MultiSelectSegmentedControl UISegmentedControl remake that supports selecting multiple segments, vertical stacking, combining text and images. Feature

Yonat Sharon 286 Dec 15, 2022
Compose views using enums swiftly: `let label: UILabel = [.text("Hello"), .textColor(.red)]`

ViewComposer Style views using an enum array with its attributes: let label: UILabel = [.text("Hello World"), .textColor(.red)] Table of Contents Inst

Alexander Cyon 28 Jul 5, 2022
Growing text view in SwiftUI

Growing text view in SwiftUI If you are planning to write a messaging feature or you are just a SwiftUI enthusiast, this repository can be interesting

Maciej Gomółka 60 Jan 8, 2023
UIStackView replica for iOS 7.x and iOS 8.x

TZStackView A wonderful layout component called the UIStackView was introduced with iOS 9. With this component it is really easy to layout components

Tom van Zummeren 1.2k Oct 10, 2022
Super awesome Swift minion for Core Data (iOS, macOS, tvOS)

⚠️ Since this repository is going to be archived soon, I suggest migrating to NSPersistentContainer instead (available since iOS 10). For other conven

Marko Tadić 306 Sep 23, 2022
A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView and iPhone X safe area support for content reloading. Built for iOS 10 and later.

Arale A custom stretchable header view for UIScrollView or any its subclasses with UIActivityIndicatorView support for reloading your content. Built f

Putra Z. 43 Feb 4, 2022
BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen

BulletinBoard is an iOS library that generates and manages contextual cards displayed at the bottom of the screen. It is especially well

Alexis (Aubry) Akers 5.3k Jan 2, 2023
💾 A collection of classic-style UI components for iOS

A collection of classic-style UI components for UIKit, influenced by Windows 95 Introduction This is a little exploration into applying '90s-era desig

Blake Tsuzaki 2.2k Dec 22, 2022
A simple, customizable view for efficiently collecting country information in iOS apps.

CountryPickerView CountryPickerView is a simple, customizable view for selecting countries in iOS apps. You can clone/download the repository and run

Kizito Nwose 459 Dec 27, 2022
A library to recreate the iOS Apple Music now playing transition

DeckTransition DeckTransition is an attempt to recreate the card-like transition found in the iOS 10 Apple Music and iMessage apps. Hereʼs a GIF showi

Harshil Shah 2.2k Dec 15, 2022
A message bar for iOS written in Swift.

Dodo, a message bar for iOS / Swift This is a UI widget for showing text messages in iOS apps. It is useful for showing short messages to the user, so

Evgenii Neumerzhitckii 874 Dec 13, 2022
Protocol oriented, type safe, scalable design system foundation swift framework for iOS.

Doric: Design System Foundation Design System foundation written in Swift. Protocol oriented, type safe, scalable framework for iOS. Features Requirem

Jay 93 Dec 6, 2022
A Material Design drop down for iOS

A Material Design drop down for iOS written in Swift. Demo Do pod try DropDown in your console and run the project to try a demo. To install CocoaPods

AssistoLab 2.3k Dec 20, 2022
An easy to use FAQ view for iOS written in Swift

FAQView An easy to use FAQ view for iOS written in Swift. This view is a subclass of UIView. Setup with CocoaPods If you are using CocoaPods add this

Mukesh Thawani 467 Dec 5, 2022
A custom reusable circular / progress slider control for iOS application.

HGCircularSlider Example To run the example project, clone the repo, and run pod install from the Example directory first. You also may like HGPlaceho

Hamza Ghazouani 2.4k Jan 6, 2023
A customizable color picker for iOS in Swift

IGColorPicker is a fantastic color picker ?? written in Swift. Table of Contents Documentation Colors Style Other features Installation Example Gettin

iGenius 272 Dec 17, 2022
⚡️ A library of widgets and helpers to build instant-search applications on iOS.

By Algolia. InstantSearch family: InstantSearch iOS | InstantSearch Android | React InstantSearch | InstantSearch.js | Angular InstantSearch | Vue Ins

Algolia 567 Dec 20, 2022
An iOS picker view to serve all your "picking" needs

Mandoline The PickerView is a UICollectionView that provides a smooth "picking" interface. In order to get the most out of it, a consuming view contro

Blue Apron 883 Nov 28, 2022