Skip to content

Commit a19a521

Browse files
committed
added swift example with custom cell
1 parent df31517 commit a19a521

18 files changed

Lines changed: 1077 additions & 84 deletions

File tree

ChatExample/ChatExample.xcodeproj/project.pbxproj

Lines changed: 434 additions & 0 deletions
Large diffs are not rendered by default.

ChatExample/ChatExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ChatExample/ChatExample.xcworkspace/contents.xcworkspacedata

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//
2+
// AppDelegate.swift
3+
// ChatExample
4+
//
5+
// Created by Andrey Ivanov on 23/03/2018.
6+
// Copyright © 2018 Andrey Ivanov. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
@UIApplicationMain
12+
class AppDelegate: UIResponder, UIApplicationDelegate {
13+
var window: UIWindow?
14+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
15+
// Override point for customization after application launch.
16+
self.window?.backgroundColor = UIColor.white
17+
return true
18+
}
19+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
{
2+
"images" : [
3+
{
4+
"idiom" : "iphone",
5+
"size" : "20x20",
6+
"scale" : "2x"
7+
},
8+
{
9+
"idiom" : "iphone",
10+
"size" : "20x20",
11+
"scale" : "3x"
12+
},
13+
{
14+
"idiom" : "iphone",
15+
"size" : "29x29",
16+
"scale" : "2x"
17+
},
18+
{
19+
"idiom" : "iphone",
20+
"size" : "29x29",
21+
"scale" : "3x"
22+
},
23+
{
24+
"idiom" : "iphone",
25+
"size" : "40x40",
26+
"scale" : "2x"
27+
},
28+
{
29+
"idiom" : "iphone",
30+
"size" : "40x40",
31+
"scale" : "3x"
32+
},
33+
{
34+
"idiom" : "iphone",
35+
"size" : "60x60",
36+
"scale" : "2x"
37+
},
38+
{
39+
"idiom" : "iphone",
40+
"size" : "60x60",
41+
"scale" : "3x"
42+
},
43+
{
44+
"idiom" : "ipad",
45+
"size" : "20x20",
46+
"scale" : "1x"
47+
},
48+
{
49+
"idiom" : "ipad",
50+
"size" : "20x20",
51+
"scale" : "2x"
52+
},
53+
{
54+
"idiom" : "ipad",
55+
"size" : "29x29",
56+
"scale" : "1x"
57+
},
58+
{
59+
"idiom" : "ipad",
60+
"size" : "29x29",
61+
"scale" : "2x"
62+
},
63+
{
64+
"idiom" : "ipad",
65+
"size" : "40x40",
66+
"scale" : "1x"
67+
},
68+
{
69+
"idiom" : "ipad",
70+
"size" : "40x40",
71+
"scale" : "2x"
72+
},
73+
{
74+
"idiom" : "ipad",
75+
"size" : "76x76",
76+
"scale" : "1x"
77+
},
78+
{
79+
"idiom" : "ipad",
80+
"size" : "76x76",
81+
"scale" : "2x"
82+
},
83+
{
84+
"idiom" : "ipad",
85+
"size" : "83.5x83.5",
86+
"scale" : "2x"
87+
}
88+
],
89+
"info" : {
90+
"version" : 1,
91+
"author" : "xcode"
92+
}
93+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" systemVersion="17A277" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
3+
<dependencies>
4+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
5+
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
6+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
7+
</dependencies>
8+
<scenes>
9+
<!--View Controller-->
10+
<scene sceneID="EHf-IW-A2E">
11+
<objects>
12+
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
13+
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
14+
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
15+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
16+
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
17+
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
18+
</view>
19+
</viewController>
20+
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
21+
</objects>
22+
<point key="canvasLocation" x="53" y="375"/>
23+
</scene>
24+
</scenes>
25+
</document>
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="taU-GF-uub">
3+
<device id="retina4_7" orientation="portrait">
4+
<adaptation id="fullscreen"/>
5+
</device>
6+
<dependencies>
7+
<deployment identifier="iOS"/>
8+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
9+
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
10+
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
11+
</dependencies>
12+
<scenes>
13+
<!--Example-->
14+
<scene sceneID="QX5-Re-Uxc">
15+
<objects>
16+
<tableViewController id="miQ-1k-v67" sceneMemberID="viewController">
17+
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="Cne-pU-m1K">
18+
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
19+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
20+
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
21+
<sections>
22+
<tableViewSection id="wQu-O8-7mX">
23+
<cells>
24+
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" textLabel="htk-xu-e49" style="IBUITableViewCellStyleDefault" id="fSg-ba-ECA">
25+
<rect key="frame" x="0.0" y="35" width="375" height="44"/>
26+
<autoresizingMask key="autoresizingMask"/>
27+
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fSg-ba-ECA" id="bMV-y1-ezr">
28+
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
29+
<autoresizingMask key="autoresizingMask"/>
30+
<subviews>
31+
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Push" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="htk-xu-e49">
32+
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
33+
<autoresizingMask key="autoresizingMask"/>
34+
<fontDescription key="fontDescription" type="system" pointSize="17"/>
35+
<nil key="textColor"/>
36+
<nil key="highlightedColor"/>
37+
</label>
38+
</subviews>
39+
</tableViewCellContentView>
40+
<connections>
41+
<segue destination="Sj9-Ac-pHW" kind="show" id="wfj-uG-yjb"/>
42+
</connections>
43+
</tableViewCell>
44+
</cells>
45+
</tableViewSection>
46+
</sections>
47+
<connections>
48+
<outlet property="dataSource" destination="miQ-1k-v67" id="l2a-4l-vBh"/>
49+
<outlet property="delegate" destination="miQ-1k-v67" id="yBt-69-tse"/>
50+
</connections>
51+
</tableView>
52+
<navigationItem key="navigationItem" title="Example" id="HCF-UM-yeV"/>
53+
</tableViewController>
54+
<placeholder placeholderIdentifier="IBFirstResponder" id="eHd-Zj-EHx" userLabel="First Responder" sceneMemberID="firstResponder"/>
55+
</objects>
56+
<point key="canvasLocation" x="743" y="184"/>
57+
</scene>
58+
<!--Chat View Controller-->
59+
<scene sceneID="gjs-cb-kls">
60+
<objects>
61+
<viewController id="Sj9-Ac-pHW" customClass="ChatViewController" customModule="ChatExample" customModuleProvider="target" sceneMemberID="viewController">
62+
<view key="view" contentMode="scaleToFill" id="phq-JM-P46">
63+
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
64+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
65+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
66+
<viewLayoutGuide key="safeArea" id="HM3-CI-svk"/>
67+
</view>
68+
</viewController>
69+
<placeholder placeholderIdentifier="IBFirstResponder" id="hBk-YS-k5X" userLabel="First Responder" sceneMemberID="firstResponder"/>
70+
</objects>
71+
<point key="canvasLocation" x="1466" y="172"/>
72+
</scene>
73+
<!--Navigation Controller-->
74+
<scene sceneID="loI-pp-4ro">
75+
<objects>
76+
<navigationController id="taU-GF-uub" sceneMemberID="viewController">
77+
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="fMH-bU-UYd">
78+
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
79+
<autoresizingMask key="autoresizingMask"/>
80+
</navigationBar>
81+
<connections>
82+
<segue destination="miQ-1k-v67" kind="relationship" relationship="rootViewController" id="Oem-Sy-Ypj"/>
83+
</connections>
84+
</navigationController>
85+
<placeholder placeholderIdentifier="IBFirstResponder" id="4ks-oV-igL" userLabel="First Responder" sceneMemberID="firstResponder"/>
86+
</objects>
87+
<point key="canvasLocation" x="-209" y="184"/>
88+
</scene>
89+
</scenes>
90+
</document>
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//
2+
// ViewController.swift
3+
// ChatExample
4+
//
5+
// Created by Andrey Ivanov on 23/03/2018.
6+
// Copyright © 2018 Andrey Ivanov. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import QMChatViewController
11+
12+
class ChatViewController: QMChatViewController {
13+
14+
override func viewDidLoad() {
15+
super.viewDidLoad()
16+
self.senderID = 1300340;
17+
self.senderDisplayName = "Sender name"
18+
self.view.backgroundColor = UIColor.white
19+
20+
self.inputToolbar?.audioRecordingEnabled = false
21+
22+
let msg = QBChatMessage()
23+
msg.text = "QuickBlox - Communication & cloud backend platform which brings superpowers to your mobile apps. QuickBlox is a suite of communication features & data services (APIs, SDKs, code samples, admin panel, tutorials) which help digital agencies, mobile developers and publishers to add great functionality to smartphone applications. Please read full iOS SDK documentation on the"
24+
msg.senderID = self.senderID
25+
msg.dateSent = Date()
26+
self.chatDataSource.add(msg)
27+
28+
let msg2 = QBChatMessage()
29+
msg2.text = "QuickBlox"
30+
msg2.senderID = self.senderID
31+
msg2.dateSent = Date()
32+
33+
self.chatDataSource.add(msg2)
34+
CustomCell.registerForReuse(inView: self.collectionView)
35+
}
36+
37+
override func didPressSend(_ button: UIButton,
38+
withMessageText text: String,
39+
senderId: UInt,
40+
senderDisplayName: String,
41+
date: Date) {
42+
43+
let msg = QBChatMessage()
44+
msg.text = text
45+
msg.senderID = senderId
46+
msg.dateSent = Date()
47+
self.chatDataSource.add(msg)
48+
self.finishSendingMessage(animated: true)
49+
}
50+
51+
override func viewClass(forItem item: QBChatMessage) -> AnyClass {
52+
53+
if item.isDateDividerMessage {
54+
return QMChatNotificationCell.self
55+
}
56+
else {
57+
return CustomCell.self
58+
}
59+
}
60+
61+
override func collectionView(_ collectionView: QMChatCollectionView!, dynamicSizeAt indexPath: IndexPath!, maxWidth: CGFloat) -> CGSize {
62+
63+
let size = TTTAttributedLabel.sizeThatFitsAttributedString(self.attributedString(forItem: self.chatDataSource.message(for: indexPath)),
64+
withConstraints: CGSize(width:maxWidth, height:1000),
65+
limitedToNumberOfLines: 0)
66+
return size
67+
}
68+
69+
override func collectionView(_ collectionView: QMChatCollectionView!, minWidthAt indexPath: IndexPath!) -> CGFloat {
70+
71+
let msg = self.chatDataSource.message(for: indexPath)
72+
let viewClass: AnyClass = self.viewClass(forItem: msg!)
73+
if viewClass == QMChatNotificationCell.self {
74+
return 60
75+
}
76+
return TTTAttributedLabel.sizeThatFitsAttributedString(self.attributedString(forItem: msg!),
77+
withConstraints: CGSize(width:100, height:1000),
78+
limitedToNumberOfLines: 0).width
79+
}
80+
81+
override func topLabelAttributedString(forItem messageItem: QBChatMessage) -> NSAttributedString? {
82+
return nil
83+
}
84+
85+
override func attributedString(forItem messageItem: QBChatMessage) -> NSAttributedString? {
86+
return NSAttributedString(string: messageItem.text!)
87+
}
88+
89+
override func bottomLabelAttributedString(forItem messageItem: QBChatMessage) -> NSAttributedString? {
90+
return NSAttributedString(string: "sent")
91+
}
92+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//
2+
// CustomCell.swift
3+
// ChatExample
4+
//
5+
// Created by Andrey Ivanov on 23/03/2018.
6+
// Copyright © 2018 Andrey Ivanov. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import QMChatViewController.QMChatCell
11+
12+
class CustomCell: QMChatCell {
13+
14+
static override func nib() -> UINib {
15+
return UINib(nibName: String(describing: self), bundle: nil)
16+
}
17+
18+
static override func cellReuseIdentifier() -> String {
19+
return String(describing: self)
20+
}
21+
22+
static override func layoutModel() -> QMChatCellLayoutModel {
23+
var model = super.layoutModel()
24+
model.avatarSize = .zero
25+
model.containerInsets = UIEdgeInsetsMake(8, 10, 8, 18)
26+
model.topLabelHeight = 0
27+
model.spaceBetweenTextViewAndBottomLabel = 0
28+
model.bottomLabelHeight = 14
29+
return model;
30+
}
31+
}

0 commit comments

Comments
 (0)