When Using JSQMessagesViewController the UI does not appear - ios

I am trying to implement JSQMessagesViewController, and I am following the Ray Wenderlich tutorial(https://www.raywenderlich.com/122148/firebase-tutorial-real-time-chat), but the UI is not appearing on my view controller, it is just blank.
This is my pod file.
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!
target "Sell Goods" do
pod 'Firebase'
pod 'Firebase/Storage'
pod 'Firebase/Database'
pod 'Google/SignIn'
pod 'JSQMessagesViewController'
end
I have tried using a bridging header but that did not work, and I followed the tutorial step by step.
Segue to ChatViewController
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
guard let editingVC = segue.destinationViewController as? ChatsViewController
else {
preconditionFailure("Bad")
}
editingVC.senderId = userID
editingVC.senderDisplayName = userName
}
ChatViewController
import Firebase
import JSQMessagesViewController
class ChatsViewController: JSQMessagesViewController {
var messages = [JSQMessage]()
var outgoingBubbleImageView: JSQMessagesBubbleImage!
var incomingBubbleImageView: JSQMessagesBubbleImage!
override func viewDidLoad() {
title = "ChatChat"
setupBubbles()
//collectionView!.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
//collectionView!.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
resetScreen = true
}
private func setupBubbles() {
let factory = JSQMessagesBubbleImageFactory()
outgoingBubbleImageView = factory.outgoingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleBlueColor())
incomingBubbleImageView = factory.incomingMessagesBubbleImageWithColor(
UIColor.jsq_messageBubbleLightGrayColor())
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let message = messages[indexPath.item]
if message.senderId == senderId {
return outgoingBubbleImageView
} else {
return incomingBubbleImageView
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
return messages[indexPath.item]
}
override func collectionView(collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!,
avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
}

You must call super.viewDidLoad & super.viewDidDisappear

Related

Error passing data to tableViewController

I have a problem. I'm making an app that consumes an API from themoviedb and saves the movies in the Realm. On the main screen I am using the CollectionViewController, and when I touch the movie it will go to details. However when it goes to details nothing appears and when I select another film it brings the previous film.
Home:
import UIKit
import RealmSwift
class HomeViewController: UIViewController,UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout, UISearchBarDelegate {
#IBOutlet weak var searchbar: UISearchBar!
#IBOutlet weak var ListOfMovies: UICollectionView!
var movies : Results<Moviess>!
let realm = try! Realm()
var detailsMovies = Moviess()
override func viewDidLoad() {
super.viewDidLoad()
print(Realm.Configuration.defaultConfiguration.fileURL!)
ListOfMovies.delegate = self
ListOfMovies.dataSource = self
searchbar.delegate = self
movies = realm.objects(Moviess.self)
getRequest()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
func getObjects(filter: String) -> Results<Moviess>{
movies = realm.objects(Moviess.self).filter("title CONTAINS[cd] %#",filter)
return movies
}
func getRequest(){
print(movies.count)
if movies.count < 1 {
RequestData.requisicao { (result) in
switch(result){
case .success(let detalhe):
self.ListOfMovies.reloadData()
print(detalhe)
case .failure(let error):
print(error)
}
}
}}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return movies.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "listOfMovies", for: indexPath) as! HomeCollectionViewCell
let infos = movies[indexPath.item]
cell.configurationMovie(movie: infos)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
detailsMovies = movies[indexPath.row]
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return UIDevice.current.userInterfaceIdiom == .phone ? CGSize(width: collectionView.bounds.width/2-20, height: 200) : CGSize(width: collectionView.bounds.width/3-20, height: 250)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
print(searchText)
if !searchText.isEmpty{
let filtro = getObjects(filter: searchText)
print(filtro)
ListOfMovies.reloadData()
}else{
movies = realm.objects(Moviess.self)
ListOfMovies.reloadData()
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "details")
{
let viewController = segue.destination as! DetailViewController
print(detailsMovies)
viewController.conta = detailsMovies
}
}
}
Details:
import UIKit
import RealmSwift
class DetailViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
var conta: Moviess!
let realm = try! Realm()
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return [conta].count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "details", for: indexPath) as! DetailsTableViewCell
let infos = [conta][indexPath.item]
cell.prepare(movie: infos!)
return cell
}
}
Moviess
import RealmSwift
import UIKit
class Moviess: Object{
#objc dynamic var id = 0
#objc dynamic var title = ""
#objc dynamic var overview = ""
#objc dynamic var poster = ""
#objc dynamic var isFavorites = false
override class func primaryKey() -> String? {
return "id"
}
convenience init (id: Int){
self.init()
self.id = id
}
override class func indexedProperties() -> [String] {
return ["isFavorites"]
}
func insertMovieData(list: Moviess){
do {
let realm = try! Realm()
try! realm.write({ () -> Void in
realm.add(list)
})
} catch let error as NSError{
print("insert error : \(error)")
}
}
func togleFavorite(){
try? realm?.write{
isFavorites = !isFavorites
}
}
}
I have no idea where I might be giving this "bug". If someone can help and explain what is going on it will be very useful.
Your problem is that prepare(for:sender:) is called before collectionView(_:, didSelectItemAt:). prepare(for:sender:) should not rely on collectionView(_:, didSelectItemAt:).
Your prepare(for:sender:) method should look like this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let cell = sender as? UICollectionViewCell,
let indexPath = ListOfMovies.indexPath(for: cell) else { return }
if (segue.identifier == "details") {
let viewController = segue.destination as! DetailViewController
viewController.conta = movies[indexPath.item]
}
}

UiTableView to UiTableView to UiViewcontroller swift

I am new here and to coding and I need some help with a project that I'm currently stuck on.
I have built an app containing UITableView the first displays body areas (Gastro, cardio, respiratory, etc), the second displays more detailed features on the first (in gastro the table will display stomach, small intestine, colon, etc) and then the the UIViewController will have the more detailed info on the stomach etc.
I have this working all ok but one problem has arose. The UIViewController, regardless of which option is selected in the first table, displays the same info, i.e I get results for gastro even after selecting cardio etc.
Below is my code. I hope someone could help with this. I would really appreciate it!
import UIKit
class Chapters: UITableViewController {
var ChaptersArray = [String]()
var SubchaptersArray = [secondTable]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// chapter names
ChaptersArray = ["Gastrointestinal","Cardiovascular","Respiratory","Central Nervous System", "Infections"]
// subcharpter names
SubchaptersArray = [secondTable(SecondTitle: ["Gas1", "Gas2", "Gas3", "Gas4"]),
secondTable(SecondTitle: ["Card1", "Card2", "Card3", "Card4"]),
secondTable(SecondTitle: ["Res1", "Res2", "Res3", "Res4"])]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell!
cell.textLabel?.text = ChaptersArray[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return ChaptersArray.count
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
let destViewController = segue.destinationViewController as! Subchapters
var secondTableArrayTwo : secondTable
secondTableArrayTwo = SubchaptersArray[indexPath.row]
destViewController.SubChaptersArray = secondTableArrayTwo.SecondTitle
}
}
import UIKit
class Subchapters: UITableViewController {
var SubChaptersArray = [String]()
var identities = [String]()
var data = [String]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
identities = ["G1","G2","G3","G4"]
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SubChaptersArray.count
}
override func tableView(tableview: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableview.dequeueReusableCellWithIdentifier("SecondCell") as UITableViewCell!
cell.textLabel?.text = SubChaptersArray[indexPath.row]
return cell
}
// ignore
// override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// let destViewController = segue.destinationViewController as! DrugNotes
// destViewController.FirstString = "drug data: need to seperate out to seperate pages" }
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let vcName = identities[indexPath.row]
let viewcontroller = storyboard?.instantiateViewControllerWithIdentifier(vcName)
self.navigationController?.pushViewController(viewcontroller!, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

Swift 2.2, RealmSwift - Retrieval of data not working

I am using realm for my notepad app to store the array noteTitles, which is of a custom class Note. The app works fine, but when it is supposed to save, it doesn't pass through. When I restart the app, the notes are gone. I will give code to all of the files. Also, I want the user to add notes and I need the ObjectForPrimaryKey to update everytime so a new id is created for each note.
Note Class Code:
import Foundation
import RealmSwift
class Note: Object {
dynamic var title = ""
var content = ""
var id = 0
override class func primaryKey() -> String? {
print("id generated")
return "id"
}
}
ViewController(Where I write the notes) Code:
import UIKit
import RealmSwift
var note2 = Note()
var note: Note!
let realm = try! Realm()
class ViewController3: UIViewController, UITextViewDelegate {
var note: Note!
#IBOutlet var noteText: UITextView!
#IBOutlet var noteTitle: UITextField!
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
noteTitle.text = note.title
noteText.text = note.content
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
note.title = noteTitle.text!
note.content = noteText.text
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func textViewDidEndEditing(textView: UITextView) {
func noteEnded(note2: Note) {
note2.title = note.title
note2.content = note.content
note2.id = note.id
do {
try realm.write {
realm.add(noteTitles, update: true)
print("added")
}
} catch {
print("There was a problem")
}
}
print("editing ended")
}
override func viewDidLoad() {
super.viewDidLoad()
print(note2.id)
self.noteText.delegate = self
// Do any additional setup after loading the view.
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
noteTitle.resignFirstResponder()
noteText.resignFirstResponder()
}
}
TableViewController(Note List) Code:
import UIKit
import RealmSwift
var noteTitles:[Note] = []
class TableViewController: UITableViewController {
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return noteTitles.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel!.text = noteTitles[indexPath.row].title // error here
// Configure the cell...
return cell
}
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
sleep(2)
if realm.objectForPrimaryKey(Note.self, key: 0) != nil {
realm.objectForPrimaryKey(Note.self, key: 0)
}
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == UITableViewCellEditingStyle.Delete {
noteTitles.removeAtIndex(indexPath.row)
tableView.reloadData()
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier! == "editNote" {
let noteDetailViewController = segue.destinationViewController as! ViewController3
let selectedIndexPath = tableView.indexPathForSelectedRow
noteDetailViewController.note = noteTitles[selectedIndexPath!.row]
} else if segue.identifier! == "addNote" {
let note = Note()
noteTitles.append(note)
let noteDetailViewController = segue.destinationViewController as! ViewController3
noteDetailViewController.note = note
}
}
}
Thanks in advance!
The function noteEnded should not inside the textViewDidEndEditing and it is not being called.
Try this
func noteEnded(note2: Note) {
do {
try realm.write {
realm.add(note2, update: true)
print("added")
}
} catch {
print("There was a problem")
}
}
func textViewDidEndEditing(textView: UITextView) {
note2.title = note.title
note2.content = note.content
note2.id = note.id
noteEnded(note2)
print("editing ended")
}
It is also better to have "Done" button to save the note. Easy to handle the input and save.

NSInvalidArgumentException with using JSQMessagesViewController

I'm new to swift :D, and developing a simple chatting application using the JSQMessagesViewController. I read & followed JSQMessagesViewController sample project (https://www.syncano.io/blog/create-ios-chat-app-part1/) but my code occurs an error.
class ChatRoomViewController: JSQMessagesViewController {
let incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor(red: 10/255, green: 180/255, blue: 230/255, alpha: 1.0))
let outgoingBubble = JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
var messages = [JSQMessage]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.setup()
self.addDemoMessages()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func reloadMessagesView() {
self.collectionView?.reloadData()
}
func gotoReserve() {
let nextViewController = ReserveViewController(nibName: "ReserveViewController", bundle: nil)
self.navigationController!.pushViewController(nextViewController, animated: true)
}
}
//MARK - Setup
extension ChatRoomViewController {
func addDemoMessages() {
let message = JSQMessage(senderId: "zzz", displayName: "aaa", text: "asasd")
self.messages.append(message)
self.reloadMessagesView()
}
func setup() {
self.senderId = "user"
self.senderDisplayName = "user"
}
}
//MARK - Data Source
extension ChatRoomViewController {
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.messages.count
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
let data = self.messages[indexPath.row]
return data
}
override func collectionView(collectionView: JSQMessagesCollectionView!, didDeleteMessageAtIndexPath indexPath: NSIndexPath!) {
self.messages.removeAtIndex(indexPath.row)
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let data = messages[indexPath.row]
switch(data.senderId) {
case self.senderId:
return self.outgoingBubble
default:
return self.incomingBubble
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
}
//MARK - Toolbar
extension ChatRoomViewController {
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
let message = JSQMessage(senderId: senderId, senderDisplayName: senderDisplayName, date: date, text: text)
self.messages += [message]
self.finishSendingMessage()
}
override func didPressAccessoryButton(sender: UIButton!) {
}
}
When I run it,
the error message say
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[JSQMessage messageHash]: unrecognized selector sent to instance 0x7fdf0a6e1f60'
and the app is terminated.
But it runs well after erasing
self.addDemoMessages()
code in viewDidLoad(). So I guess this code occurs error, but I don't know how to fix :( How can I fix it?
I had a similar problem with this when I subclassed the JSQMessage object. If you are doing that you just need to make sure that you implement the has for the message data. I just had to add this method to my message object
func messageHash() -> UInt {
return UInt(self.hash)
}
Hope that helps 👻
Here is my case,
to solve it by
Add -all_load to the other linker flags in your build settings.
-all_load forces the linker to load all object files from every archive it sees, even those without Objective-C code.
and
-force_load is available in Xcode 3.2 and later. It allows finer grain control of archive loading.
Each -force_load option must be followed by a path to an archive, and every object file in that archive will be loaded.

JSQMessagesViewController message bubbles are aligning irregular

I am developing an app using JSQMessagesViewController. But there is problem that message bubbles are aligning irregular order in collectionView.
Here is a Screenshot
Here is the code:
import UIKit
class mDetailContainerViewController: JSQMessagesViewController, JSQMessagesCollectionViewDelegateFlowLayout{
var userName = ""
var messages = [JSQMessage]()
let incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
let outgoingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor.greenColor())
override func viewDidLoad() {
super.viewDidLoad()
self.userName = "iPhone"
for i in 1...10{
var sender = (i%2 == 0) ? "Syncano" : self.userName
var message = JSQMessage(senderId: sender, displayName: sender, text: "Text")
self.messages += [message]
}
self.collectionView.reloadData()
self.senderDisplayName = self.userName
self.senderId = self.userName
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageData! {
var data = self.messages[indexPath.row]
return data
}
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
var data = self.messages[indexPath.row]
if (data.senderId == self.senderId){
return self.outgoingBubble
}else{
return self.incomingBubble
}
}
override func collectionView(collectionView: JSQMessagesCollectionView!, avatarImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageAvatarImageDataSource! {
return nil
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return self.messages.count
}
override func didPressSendButton(button: UIButton!, withMessageText text: String!, senderId: String!, senderDisplayName: String!, date: NSDate!) {
var message = JSQMessage(senderId: senderId, displayName: senderDisplayName, text: text)
messages += [message]
self.finishSendingMessage()
}
override func didPressAccessoryButton(sender: UIButton!) {
}
I searched the solution a bit on the internet, but all the instructions are just complicated. I did not figure out anything. Besides, I am not sure that I found a solution. If someone will explain the solution simply, I will be pleased.
Note: JSQMessagesViewController is shown in container view.
Lastly, how can I change the send button title and text field placeholder with using localizations.
Thanks.
I am not familiar with this SDK but I think it is because both of these lines
let incomingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor.lightGrayColor())
let outgoingBubble = JSQMessagesBubbleImageFactory().incomingMessagesBubbleImageWithColor(UIColor.greenColor())
are incomingMessagesBubbleImageWithColor. Set outgoingBubble to JSQMessagesBubbleImageFactory().outgoingMessagesBubbleImageWithColor (if that exists)
And I've never used this message class before but I believe your alignment issue with the green text might be solved with something like...
outgoingBubble.textLabel.textAlignment = NSTextAlignment.Center
To fix the bubble locations, remove the avatar images with this code;
self.collectionView.collectionViewLayout.incomingAvatarViewSize = CGSizeZero
self.collectionView.collectionViewLayout.outgoingAvatarViewSize = CGSizeZero
For anybody having troubles with this in the future check that your code doesnt look like this:
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let data = messages[indexPath.row]
if data.senderId == currentUser.objectId! {
return incomingBubble
} else {
return outgoingBubble
}
}
it should look like this:
override func collectionView(collectionView: JSQMessagesCollectionView!, messageBubbleImageDataForItemAtIndexPath indexPath: NSIndexPath!) -> JSQMessageBubbleImageDataSource! {
let data = messages[indexPath.row]
if data.senderId == PFUser.currentUser()!.objectId! {
return outgoingBubble
} else {
return incomingBubble
}
}
that fixed it for me!
in Swift 3:
For your specific problem that's centering the text inside the bubble:
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
cell.textView.textAlignment = .center
return cell
}

Resources