Platformsios 9.0

GTChatKit: iOS ChatKit built on Texture

Travis CI

GTChatKit is build on Texture for easy building iOS Message Application.
Also it support Bi-directional Paging CollectionView

Why? Texture
Texture is an iOS framework built on top of UIKit that keeps even the most complex user interfaces smooth and responsive. more information Here

Pagination Example


Message Input Box Example



example source

1. Create GTChatNodeController subclass

class ChatNodeController: GTChatNodeController { ... }

and you can create subclass instance

let viewController = ChatNodeController()

if you want custom collection flow layout follow it

let customFlowLayout = YOURCUSTOMCollectionFlowLayout()
let viewController = GTChatNodeController(layout: customFlowLayout)

you can access chatNode and node(backgroundNode)

class ChatNodeController: GTChatNodeController {

func foo() {

    let collectionView = self.chatNode // chatNode is equal to UICollectionView
    let backgroundView = self.node // self.node is equal to backgroundView(UIView)


### 2. GTChatNodeDelegate implementation
extension ChatNodeController: GTChatNodeDelegate {
    func shouldAppendBatchFetch(for chatNode: ASCollectionNode) -> Bool {
        // Should Append Batch Fetch
        return true

    func shouldPrependBatchFetch(for chatNode: ASCollectionNode) -> Bool {
        // Should Prepend Batch Fetch
        return true

    func chatNode(_ chatNode: ASCollectionNode, willBeginAppendBatchFetchWith context: ASBatchContext) {
        // Network Call Handling
        // If Network Call Completed then context should be completed
        // required example
        // eg) self.completeBatchFetching(true, endDirection: .none)

    func chatNode(_ chatNode: ASCollectionNode, willBeginPrependBatchFetchWith context: ASBatchContext) {

3. completeBatchFetching

    func completeBatchFetching(_ complated: Bool, endDirection: BatchFetchDirection) { ... }

    endDirection: automatically block append or prepend batch fetching
    self.completeBatchFetching(true, endDirection: .append) -> no more append doesn't work
    self.completeBatchFetching(true, endDirection: .prepend) -> no more prepend doesn't work

4. pagingStatus property

you can see 4 steps paging status

  1. initial
  2. appending
  3. prepending
  4. some

(2), (3) is Loading status
(4: some) is means networking is finished and got new items
you do not need to be aware of (1: initial status) existence

5. If you need attach message input node then override layoutSpecThatFits method on subclass

Also, when keyboard is activated, you can get keyboard height from keyboardVisibleHeight property

override func layoutSpecThatFits(_ constrainedSize: ASSizeRange, chatNode: ASCollectionNode) -> ASLayoutSpec {
let messageInsets: UIEdgeInsets = .init(top: .infinity,
left: 0.0,
bottom: self.keyboardVisibleHeight,
right: 0.0)
    let messageLayout = ASInsetLayoutSpec(insets: messageInsets,
                                          child: self.messageNode)

    // overlay message input box onto chatNode
    let messageOverlayedLayout = ASOverlayLayoutSpec(child: chatNode,
                                                     overlay: messageLayout)

    return ASInsetLayoutSpec(insets: .zero, child: messageOverlayedLayout)

### 6. overriding setupChatRangeTuningParameters method
> If you deal with the tuning parameters for range type on your scrolling node 
> More Information [Here](

``` swift
    // default
    open func setupChatRangeTuningParameters() {
        self.chatNode.setTuningParameters(ASRangeTuningParameters(leadingBufferScreenfuls: 1.5,
                                                              trailingBufferScreenfuls: 1.5),
                                      for: .full,
                                      rangeType: .display)
        self.chatNode.setTuningParameters(ASRangeTuningParameters(leadingBufferScreenfuls: 2,
                                                              trailingBufferScreenfuls: 2),
                                      for: .full,
                                      rangeType: .preload)

7. GTChatKit System Message Input Box

        let node = GTChatMessageBoxNode()

        // Create ChatMessageButtonNode
        let cameraButton = GTChatMessageButtonNode()
            .setButtonSize(.init(width: 24.0, height: 24.0))
            .setButtonImage(#imageLiteral(resourceName: "photo"), color: .white, for: .normal)
            .setButtonImage(#imageLiteral(resourceName: "photo"), color: UIColor.white.withAlphaComponent(0.5), for: .disabled)

        let sendButton = GTChatMessageButtonNode()
            .setButtonSize(.init(width: 24.0, height: 24.0))
            .setButtonImage(#imageLiteral(resourceName: "send"), color: .white, for: .normal)
            .setButtonImage(#imageLiteral(resourceName: "send"), color: UIColor.white.withAlphaComponent(0.5), for: .disabled)

        node.messageNode.setMessageContainerInsets(UIEdgeInsetsMake(5.0, 10.0, 5.0, 10.0))

        // apply Message Box Attributes
        node.setLeftButtons([cameraButton], spacing: 10.0) // attach left button items
            .setRightButtons([sendButton], spacing: 10.0) // attach right button items
            .setMessageBoxHeight(50.0, maxiumNumberOfLine: 6, isRounded: true) // set message input box size


  • Xcode <~ 9.0
  • iOS <~ 9.x
  • Swift <~ 3.x, 4.0


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

pod 'GTChatKit'


Geektree0101, [email protected]


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

Latest podspec

    "name": "GTChatKit",
    "version": "4.2.0",
    "summary": "iOS ChatKit built on Texture(AsyncDisplayKit) and written in Swift",
    "description": "iOS ChatKit built on Texture(AsyncDisplayKit) and written in Swift",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Geektree0101": "[email protected]"
    "source": {
        "git": "",
        "tag": "4.2.0"
    "platforms": {
        "ios": "9.0"
    "source_files": "GTChatKit/Classes/**/*",
    "dependencies": {
        "Texture": [
            "~> 2.5"
    "pushed_with_swift_version": "4.0"

Pin It on Pinterest

Share This