SZMentionsSwift is a lightweight mentions library for iOS.

Overview

Carthage compatible codecov Donate Build Status CocoaPods Compatible Platform Twitter

SZMentionsSwift is a lightweight mentions library for iOS. This library was built to assist with the adding, removing and editing of a mention within a textview.

What can it do

Add mentions

You can easily add mentions by typing the trigger (default: @) followed by text to filter your list by. Tapping the name will insert the mention into the textView.

Insert mentions

Any text, including mentions, that are inserted before other mentions will automatically adjust the ranges for all existing mentions.

Delete mentions

If at any point text is changed within an existing mention that mention will be removed from the mentions array and any remaining text associated with that mention will revert to default styling.

For more technical details on usage you can check here

How To Get Started

Communication

  • If you need help, feel free to tweet @StevenZweier
  • If you found a bug, have a feature request, or have a general question open an issue.
  • If you want to contribute, submit a pull request.

Installation with Carthage

Carthage

Cartfile

To integrate SZMentionsSwift into your Xcode project using CocoaPods, specify it in your Cartfile:

github "szweier/SZMentionsSwift"

Then, run the following command:

$ carthage update

More Info Here

Installation with CocoaPods

CocoaPods

Podfile

To integrate SZMentionsSwift into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

pod 'SZMentionsSwift'

Then, run the following command:

$ pod install

Usage

Below is a quick run through of the objects used in this library but as always the best place to get an understanding of the current implementation of the SZMentionsSwift library is in the example code.

MentionsSwiftListener

This class manages the mention interaction.

Setup

Use one of the many initializers to setup your mentions listener. Parameters explained below:

mentionsTextView : required The text view we are applying the mentions listener to. Note: it's delegate must be the mentions manager.

delegate : optional If you would like to receive UITextView delegate methods set this and it will be passed through after processing view the mentions listener.

mentionTextAttributes : Attributes (see: AttributeContainer) to apply to the textview for all mentions

defaultTextAttributes : Attributes (see: AttributeContainer) to apply to the textview for all text that is not a mention.

spaceAfterMention : optional Whether or not you would like a space to be added to the end of your mentions. Default is NO

trigger : The string used to start a mention. Default is @

cooldownInterval : optional The amount of time to wait between calling showMentionsList. Default is 0.5

searchSpaces : optional Mention searches can / cannot contain spaces

hideMentions : required Block of code that is run when the mentions view is to be hidden

didHandleMentionOnReturn: required Block of code that is run when enter is hit while in the midst of editing a mention. Use this block to either: - 1. add the mention and return true stating that the mention was handled on your end (this will tell the listener to hide the view) - 2. return false stating that the mention was NOT handled on your end (this will allow the listener to input a line break).

showMentionsListWithString: required Block of code that is run when the mentions list is to be shown

Properties

mentions : readonly Array of all mentions currently applied to the text view.

Methods

public func reset() : Call this method to reset your textView's text to an empty string and also remove any existing mentions.

@discardableResult public func addMention(_ mention: CreateMention) -> Bool : Call this method while adding a mention to apply the mention to the current text.

public func insertExistingMentions(_ existingMentions: [CreateMention]): Insert mentions into an existing textview. This is provided assuming you are given text along with a list of users mentioned in that text and want to prep the textview in advance.

CreateMention (Protocol)

This protocol contains the required properties for a mention being sent to the mentions listener

AttributeContainer (Protocol)

This protocol contains the required properties for attributes to be applied to attributed text

Mention

This struct is returned via the mentions method, it includes the range of the mention as well as object containing the object sent to the mentions listener via the addMention(_ mention: CreateMention) method.

Unit Tests

SZMentionsSwift includes unit tests which can be run on the SZMentionsSwift framework.

Credits

SZMentionsSwift was originally created by Steven Zweier

Comments
  • Exception 'NSRangeException' for searchSpaces feature

    Exception 'NSRangeException' for searchSpaces feature

    First of all, thank you for the great library that you have written. I have discovered an issue that could be reproduce as following:

    1. Enable searchSpaces in SZMentionsListener
    2. Type Any String "@tag String" Any String in text view.
    3. Randomly keep changing cursor (Select text position) position (In quick manner) in text view.

    It will throw the Range out of bounds issue.

    Example of error message: *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range {72, 18} out of bounds; string length 86'

    invalid 
    opened by wonderhero 9
  • Mention show

    Mention show

    how to add "@" become @steven on textView when selected list of mention steven? and also how to get text (String) on text View ? thanks anyway.

    enhancement question 
    opened by devlixz 9
  • Different styles for different kind of mentions

    Different styles for different kind of mentions

    Hey,

    Thanks for the lib! In my case I need to manage 2 different kinds of mentions: some mentions should appear in blue, some others should appear in gray. But currently it seems you can only have them all blue, or all gray.

    Do you think we could add this feature to the lib? I could help if needed.

    enhancement 
    opened by Footjy 8
  • textView(_:shouldChangeTextIn:replacementString:) not been called

    textView(_:shouldChangeTextIn:replacementString:) not been called

    Hi szweier,

    I have added SZMentionsListener in my code. I also implemented textView(_:shouldChangeTextIn:replacementString:) in my controller. I realised that if I paste string from external app into the textview that has implemented this library. My callback not getting called. I have stepped into the library code.

    else if text.count > 1 {
                //Pasting
                if let editedMention = mentions.mentionBeingEdited(atRange: range) {
                    clearMention(editedMention)
                }
    
                textView.delegate = nil
                if let mutableAttributedString = textView.attributedText.mutableCopy() as? NSMutableAttributedString {
                    mutableAttributedString.replaceCharacters(in: range, with: NSAttributedString(string: text))
                    mutableAttributedString.apply(defaultTextAttributes, range: NSRange(location: range.location, length: text.count))
                    mentionsTextView.selectedRange = NSRange(location: 0, length: 0)
                    textView.attributedText = mutableAttributedString
                    mentionsTextView.selectedRange = NSRange(location: range.location + text.count, length: 0)
                }
                
                mentions.adjustMentions(forTextChangeAtRange: range, text: text)
                textView.delegate = self
                
                return false
            }
            _ = delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: text)
    

    The delegate callback will not get called if it fulfilling the text pasting action. However, I need to do some adjustment to my UITextView (To resize the UI) if received the callback.

    Is there any way I can get my delegate get called in the event of pasting text?

    bug 
    opened by wonderhero 8
  • `spaceAfterMention` add space but leaves the cursor (carriage) in its original position

    `spaceAfterMention` add space but leaves the cursor (carriage) in its original position

    The problem in NSRange extension as I could find:

    if spaceAfterMention = true then when user tap on mention func addMention then called add(createMention, spaceAfterMention: spaceAfterMention, at: currentMentionRange, with: mentionTextAttributes) then called replace(charactersIn: range, with: mention.mentionName(with: spaceAfterMention)), but in this place we use the selectedRange value obtained without taking into account the parameter spaceAfterMention and do not change it and that's why a space was added to the final line, but the cursor remained in the same place.

    Well, after changing this

    internal extension NSRange {
        func adjustLength(for text: String, with spaceAfterMention: Bool) -> NSRange {
            return NSRange(location: location, length: text.utf16.count)
        }
    }
    

    to this

    internal extension NSRange {
        func adjustLength(for text: String, with spaceAfterMention: Bool) -> NSRange {
            let lenght = spaceAfterMention ? text.utf16.count + 1 : text.utf16.count
            return NSRange(location: location, length: lenght)
        }
    }
    

    I fixed the problem, but I'm not sure about the side effects of this fix. Can you check it? Should I submit a pull request?

    opened by aleksandrshoshiashvili 6
  • Exception 'NSRangeException' for searchSpaces feature

    Exception 'NSRangeException' for searchSpaces feature

    @szweier I able to reproduce this issue again. It is just a bit tricky.

    Step to reproduce:

    1. Enable searchSpaces in SZMentionsListener
    2. Type Hello this is example of @mention @this_is_false_mention in text view.
    3. Randomly keep changing cursor (Select text position) position (In quick manner) in text view.

    @mention is actual mention @this_is_false_mention is a random string that having starting character same as triggers. Example: "@" symbol.

    I able to reproduce the issue in the project example as well.

    It will throw the Range out of bounds issue.

    Example of error message: *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range {72, 18} out of bounds; string length 86'

    bug 
    opened by wonderhero 6
  • Resigning first responder causes textview to lose attributes for mentions

    Resigning first responder causes textview to lose attributes for mentions

    If I take the focus off of my textview by using it's resignFirstResponder function, all of the attributes disappear from my text view while the mentions still exist.

    I think this may be a bug outside of this library, possibly in iOS frameworks itself?

    invalid question 
    opened by danielchristopher1 5
  • Deleting all the text causes a crash

    Deleting all the text causes a crash

    When you have more than one mention and try to select all the text and delete it causes a crash. The problem occurs in shouldAdjust, specifically in forceDefaultAttributes when trying to do this:

    mutableAttributedString.mutableString.replaceCharacters(in: range, with: text)

    In handleEditingMention you are handling only one mention(the last you find) and deleting all the text from de textView but the range that you pass to forceDefaultAttributes is still the older one, so you get an out of bounds when you try to replace text in an empty string.

    bug 
    opened by jrodriguezbebee 5
  • How to cancel search?

    How to cancel search?

    Is there a way to cancel searching and not resign the textView's firstResponder? I want to allow users to cancel searching by tapping a button or the textView.

    My mentions listener has spaceAfterMention, addMentionOnReturnKey, and searchSpaces all set to true.

    invalid question 
    opened by camdengaba 4
  • Should insertExistingMentions be made public?

    Should insertExistingMentions be made public?

    I'm trying to initialise the SZMentionsListener with a preexisting list of mentions. I found the insertExistingMentions method which seems to do what I want but the method is inaccessible from outside of the framework. Is this by design or should this method be made public?

    bug 
    opened by raphaelcruzeiro 4
  • UITextView autoCapitalizationType is always Words

    UITextView autoCapitalizationType is always Words

    Hi szweier,

    The mentions library has overwritten my UITextView autoCapitalizationType type. It always capitalizes Words even though I have set my UITextView to Sentences. [For the auto-suggestion words]

    I have tested with the sample in this project.

    Screenshot 2019-10-24 at 4 22 49 PM

    Could you please assist?

    Thank you.

    opened by wonderhero 3
  • How can we trigger the mention list with @ Sign with System Emojis

    How can we trigger the mention list with @ Sign with System Emojis

    Hi @szweier , Hope you are doing great. Is there a way in library to handle mention list along the system emoji/custom emoji without using any extra empty space {" " } before system emoji or custom emojis, and we will be able to show the mention list on @Sign with them.

    Waiting for your quick reply?

    Regards, Mohsin

    opened by hafiz-mohsin-confiz 0
  • How can we trigger the mention list with @ Sign with System Emojis

    How can we trigger the mention list with @ Sign with System Emojis

    Hi @szweier , Hope you are doing great. Is there a way in library to handle mention list along the system emoji/custom emoji without using any extra empty space {" " } before system emoji or custom emojis, and we will be able to show the mention list on @Sign with them.

    Waiting for your quick reply?

    Regards, Mohsin

    opened by hafiz-mohsin-confiz 0
  • AttributeContainer protocol conflicts with XCode 13's new AttributeContainer struct

    AttributeContainer protocol conflicts with XCode 13's new AttributeContainer struct

    I'm getting an "'AttributeContainer' is ambiguous for type lookup in this context" error when I try to build with XCode 13. This is because XCode added a new AttributeContainer struct to Foundation, so now it's unclear which one my code refers to. Is there a simple way to resolve this ambiguity?

    opened by apollopattern 1
  • The issue with adding mention while editing the text

    The issue with adding mention while editing the text

    I have added 1 user to mention on textview, After that continue with adding text and its mention color resets. Please check the screenshots for that.

    Screenshot 2021-03-03 at 1 57 44 PM Screenshot 2021-03-03 at 1 57 59 PM

    The first screen indicates that mention added while in the 2nd screen shows color of tagged user resets.

    Please guide me on this. Facing the issue.

    opened by jadavbk 0
  • Is it possible to use without triggers?

    Is it possible to use without triggers?

    I'm using this library with '#' and '@' as triggers flawlessly, but I'm wondering if it's possible to also use it without triggers? i.e. it would display the mentions list as soon as user starts typing anything

    My use case is that I'm building a sort of search textfield, so the user is not typing a comment, but rather searching something to select

    opened by alezoffoli 0
Owner
Steven Zweier
Swift
Steven Zweier
Convert text with HTML tags, links, hashtags, mentions into NSAttributedString. Make them clickable with UILabel drop-in replacement.

Atributika is an easy and painless way to build NSAttributedString. It is able to detect HTML-like tags, links, phone numbers, hashtags, any regex or

Pavel Sharanda 1.1k Jan 8, 2023
Lightweight library to set an Image as text background. Written in swift.

![](https://img.shields.io/badge/Swift 2-compatible-4BC51D.svg?style=flat-square) Simple and light weight UIView that animate text with an image. Demo

Lucas Ortis 552 Sep 9, 2022
A lightweight fuzzy-search library, with zero dependencies

Fuse What is Fuse? Fuse is a super lightweight library which provides a simple way to do fuzzy searching. Usage Example 1 let fuse = Fuse() let result

Kiro Risk 864 Dec 29, 2022
CodeMirror-Swift is a lightweight wrapper of CodeMirror for macOS and iOS

CodeMirror-Swift is a lightweight wrapper of CodeMirror for macOS and iOS. Features ?? Lightweight CodeMirror wrapper (build 5.52.2) ✅ 100% Native Swi

Proxyman 86 Dec 30, 2022
VEditorKit - Lightweight and Powerful Editor Kit built on Texture(AsyncDisplayKit)

VEditorKit provides the most core functionality needed for the editor. Unfortunately, When combined words are entered then UITextView selectedRange will changed and typingAttribute will cleared. So, In combined words case, Users can't continue typing the style they want.

David Ha 471 Dec 27, 2022
A comprehensive, lightweight string extension for Swift

SwiftString SwiftString is a lightweight string extension for Swift. This library was motivated by having to search StackOverflow for common string op

Andrew Mayne 1.6k Dec 30, 2022
🎗 Super lightweight ISO8601 Date Formatter in Swift

ISO8601 ❤️ Support my apps ❤️ Push Hero - pure Swift native macOS application to test push notifications PastePal - Pasteboard, note and shortcut mana

Khoa 19 May 12, 2020
A library for formatting strings on iOS and macOS

Sprinter Introduction What? Why? How? Usage Installation Integration Localization Thread Safety Advanced Usage Introduction What? Sprinter is a librar

Nick Lockwood 168 Feb 6, 2022
iOS port from libphonenumber (Google's phone number handling library)

libPhoneNumber for iOS NBPhoneNumberUtil NBAsYouTypeFormatter ARC only Update Log https://github.com/iziz/libPhoneNumber-iOS/wiki/Update-Log Issue You

iziz 2.3k Jan 3, 2023
BonMot is a Swift attributed string library

BonMot (pronounced Bon Mo, French for good word) is a Swift attributed string library. It abstracts away the complexities of the iOS, macOS, tvOS, and

Rightpoint 3.4k Dec 30, 2022
Croc is a swift emoji string parsing library

Croc is a library for parsing emojis on iOS. It provides a simple and lightweight interface for detecting, generating, categorizing and managing emoji characters, making emoji-powered features an easy task for developers.

Joe Kalash 127 Nov 20, 2022
SwiftVerbalExpressions is a Swift library that helps to construct difficult regular expressions

SwiftVerbalExpressions Swift Regular Expressions made easy SwiftVerbalExpressions is a Swift library that helps to construct difficult regular express

null 582 Jun 29, 2022
🌭 Mustard is a Swift library for tokenizing strings when splitting by whitespace doesn't cut it.

Mustard ?? Mustard is a Swift library for tokenizing strings when splitting by whitespace doesn't cut it. Quick start using character sets Foundation

Mathew Sanders 695 Nov 11, 2022
Swift markdown library

Markdown ![Swift version](https://img.shields.io/badge/Swift-2.1 | 2.2-blue.svg) ![GitHub license](https://img.shields.io/badge/license-LGPL v3-green.

Crossroad Labs 79 Oct 9, 2022
A simple library for building attributed strings, for a more civilized age.

Veneer A simple library for building attributed strings, for a more civilized age. Veneer was created to make creating attributed strings easier to re

Wess Cope 26 Dec 27, 2022
A simple library that provides standard Unicode emoji support across all platforms

Twitter Emoji (Twemoji) A simple library that provides standard Unicode emoji support across all platforms. Twemoji v13.1 adheres to the Unicode 13.0

Twitter 15k Jan 8, 2023
User input masking library repo.

Migration Guide: v.6 This update brings breaking changes. Namely, the autocomplete flag is now a part of the CaretGravity enum, thus the Mask::apply c

red_mad_robot 548 Dec 20, 2022
A Cross-Platform String and Regular Expression Library written in Swift.

Guitar ?? A Cross-Platform String and Regular Expression Library written in Swift. About This library seeks to add common string manipulation function

Arthur Ariel Sabintsev 659 Dec 27, 2022
Swift emoji string parsing library

Croc is a library for parsing emojis on iOS. It provides a simple and lightweight interface for detecting, generating, categorizing and managing emoji

Joe Kalash 125 Sep 27, 2021