danielsaidi / RichTextKit

RichTextKit is a Swift SDK that helps you use rich text in Swift and SwiftUI.
MIT License
824 stars 99 forks source link

Add support for links #24

Open danielsaidi opened 1 year ago

danielsaidi commented 1 year ago

It should be possible to add a link to the current selection, and remote the link if there is already one.

DavidAlvarezDev commented 1 year ago

Maybe this will give you a little head start 👍 It's what I'm using in my project right now to insert an autogenerated link.

    func insertLinkToBibleVerse() {

        let bibleBookFormatted = "\(currentBibleBookName()) \(bibleBook.chapter.sU):\(bibleBook.verse.sU)" // The name of the bible book to insert
        cursorPosition = context.selectedRange.location // Get the current position of the cursor for restoration as the last step
        let fontSize : [ NSAttributedString.Key : Any ] = [ .font : UIFont.systemFont(ofSize: 16.0 )  ]
        let oldNSAS = noteBlock.attributedNote  // Store the old string
        var linkAttribute : [ NSAttributedString.Key : Any ] = [ .link : NSURL(string: makeLinkToBibleVerse() )! ] //Create the new string to insert // Changed type to Any so that it could be merged to with other dictionary
        linkAttribute.merge( dict:  fontSize )

        let blankSpacesToInsert = NSAttributedString( string: " ", attributes: fontSize ) // Inserts a default context so that link does not expand after typing 
        let NSMSLink = NSMutableAttributedString( string: bibleBookFormatted, attributes: linkAttribute ) // Book string with link to insert into note..
        NSMSLink.append( blankSpacesToInsert )

        let combinedNSMAS = NSMutableAttributedString(attributedString: oldNSAS) // Add strings together
        combinedNSMAS.insert( NSMSLink, at: context.selectedRange.location )

        let spaceAfterScriptureIndex = cursorPosition + NSMSLink.string.count
        context.shouldSetAttributedString = combinedNSMAS // cannot use context.setAttributedString( to: ), will set font to context size..
        context.isEditingText = true

        if combinedNSMAS.length > spaceAfterScriptureIndex {
            context.pasteText("", at: spaceAfterScriptureIndex, moveCursorToPastedContent: true)
        }

    }

    func removeLink() {

        guard context.hasSelectedRange else { return }

        cursorPosition = context.selectedRange.location // Get the current position of the cursor for restoration as the last step
        let spaceAfterRangeIndex = cursorPosition  + 1
        let fontSize : [ NSAttributedString.Key : Any ] = [ .font : UIFont.systemFont(ofSize: 16.0 )  ]
        let blankSpacesToInsert = NSAttributedString( string: "   ", attributes: fontSize )

        let oldNSAS = noteBlock.attributedNote  // Store the old string
        let newNSMAS = NSMutableAttributedString(attributedString: oldNSAS) // Add strings together
        newNSMAS.append( blankSpacesToInsert )
        newNSMAS.removeAttribute(.link, range: context.selectedRange)

        context.shouldSetAttributedString = newNSMAS // cannot use context.setAttributedString( to: ), will set font to context size..
        context.isEditingText = true

        if newNSMAS.length > spaceAfterRangeIndex {
            context.pasteText("", at: spaceAfterRangeIndex, moveCursorToPastedContent: true) // blankSpacesToInsert is three spaces long, so this should never crash - Moves cursor position to one space after link
        }

    }
danielsaidi commented 1 year ago

Hi @DavidAlvarezDev

That's perfect, thank you! It would be amazing to add link support to the library. 👍