0

I want to customise the JSQMessagesCollectionView. I want to add some padding in bottom view so that scroll view starts from some bottom margin.

I need this because my view is overlapping. Here the screenshot:

enter image description here

The second thing I want to customise the time stamp. I want to add a functionality just like Facebook. Here is the scenario:

  1. Show date and time. For messages sent in under a minute, use "Just Now" instead of the actual timestamp.
  2. For messages sent on the same day, use Today, time. For example: Today, 4:47 PM.
  3. For messages sent yesterday, use Yesterday, Time. For example: Yesterday, 5:01 AM.
  4. For everything else, use standard format: Date, Time. For example: April 12, 2017, 4:01 PM.

I want to customise the timestamp label and I want to add the "just now" text there. is it possible?

Can I change the time place in view? I want to show the time stamp below the bubble?

Thanks in advance. Please help if you can?

Community
  • 1
  • 1
Muhammad Umair
  • 583
  • 11
  • 32

2 Answers2

2

Timestamp issue was solved in above answer. I have just added this code:

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = super.collectionView(collectionView, cellForItemAt: indexPath) as! JSQMessagesCollectionViewCell
        cell.textView.delegate = self
        let message = messages[indexPath.item]

       // let formatter = DateFormatter()
         // time zone if needed

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        formatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone!
    let now = formatter.string(from: message.date as Date)

    let messageUTCDate = formatter.date(from: now)

    cell.cellBottomLabel.text =  formatter.timeAgoSinceDate(messageUTCDate!)
    return cell
}

I am also able to solve the above issue, here is the solution given below:

To add buttons in collection view I have used the following code it will be added into ChatViewController.swift:

 func addSocialPagesButtonsToView()
    {
        var scrollView : UIScrollView!

        let pageNames = NSArray(objects: "Open My Facebook Page","Open My TripAdvisor Page")
        scrollView = UIScrollView(frame:CGRect(x:0, y:10, width:Int(collectionView.frame.width+100), height:50))
        scrollView.sizeToFit()
      //  scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)
        for i in 0..<2 {

           // let catogry = categoryList[i] as! CategoryModel
            defaultSocialMediaButtonsScrollContentSize = defaultSocialMediaButtonsScrollContentSize + 200
            scrollView.addSubview(self.createViewForSocialPagesButtons(name: pageNames[i] as! String, heightOfParent: Int(scrollView.frame.size.height), tag: i))
            scrollView.contentSize = CGSize(width: defaultSocialMediaButtonsScrollContentSize, height:40)

        }
        defaultSocialMediaButtonsScrollContentSize = defaultSocialMediaButtonsScrollContentSize + 40
        scrollView.contentSize = CGSize(width: defaultSocialMediaButtonsScrollContentSize, height:40)
        scrollView.showsHorizontalScrollIndicator = true
        scrollView.showsVerticalScrollIndicator = false

        socialbuttonsScrollView.addSubview(scrollView)
    }
    func createViewForSocialPagesButtons(name: String, heightOfParent: Int, tag: Int) -> UIButton {

        let button = UIButton(frame: CGRect(x:defaultXValueforView , y: 0, width: 220, height: 40))
        button.backgroundColor = UIColor.clear
        button.setTitle(name, for: .normal)
        button.tag = tag
        button.setTitleColor(UIColor.blue, for: .normal)
        button.layer.cornerRadius = 2;
        button.layer.borderWidth = 1;
        button.layer.borderColor = UIColor.blue.cgColor
        button.titleLabel?.textAlignment = NSTextAlignment.center
        let font = UIFont(name: "Rubik", size: 17)
        button.titleLabel?.font = font
        button.addTarget(self, action: #selector(openPageButtonTapped(_:)), for: .touchUpInside)

        defaultXValueforView = defaultXValueforView + 225;
        return button
    }

    func openPageButtonTapped(_ sender : UIButton){
        let buttonTapped = sender.tag
        if(Commons.connectedToNetwork())
        {
            let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)
            let nextViewController = storyBoard.instantiateViewController(withIdentifier: "webVC") as! WebPageViewController
            if(buttonTapped==0)
            {
                nextViewController.pageUrlAdress = "https://www.facebook.com/TripAdvisor/"
            }
            else if(buttonTapped==1)
            {
              nextViewController.pageUrlAdress = "https://www.tripadvisor.com.ph/Restaurant_Review-g298460-d10229090-Reviews-Vikings_SM_City_Cebu_Restaurant-Cebu_City_Cebu_Island_Visayas.html"
            }

            self.navigationController?.pushViewController(nextViewController, animated:true)

        }
        else
        {
            Commons.showAlert("Please check your connection", VC: self)
        }
    }

Call addSocialPagesButtonsToView() method in viewdidload.

For reducing the Collectionview scroll area, you have to open the pod code files. Open JSQMessagesViewController.m files and go to the following method:

- (void)jsq_setCollectionViewInsetsTopValue:(CGFloat)top bottomValue:(CGFloat)bottom
{
    UIEdgeInsets insets = UIEdgeInsetsMake(top, 0.0f, bottom+60, 0.0f);
    self.collectionView.contentInset = insets;
    self.collectionView.scrollIndicatorInsets = insets;
}

Just add the constant value (how much you want to reduce the area) bottom+your-value. For example: bottom+60.

I hope it will help all the visitors who want to do that. If any one have question please let me know.

Thanks.

Muhammad Umair
  • 583
  • 11
  • 32
1

To show time stamp below the bubble you can use cellBottomLabel label of Cell in cellForItemAt indexPath method

cell1.cellBottomLabel.text = "just now"

You will aslo need to provide height for that label as following

override func collectionView(_ collectionView: JSQMessagesCollectionView!, layout collectionViewLayout: JSQMessagesCollectionViewFlowLayout!, heightForCellBottomLabelAt indexPath: IndexPath!) -> CGFloat {
    return 20.0
}

Further to customize time stamp you can always use date formatter extension. in my case i have used following.(https://gist.github.com/minorbug/468790060810e0d29545)

extension DateFormatter {
/**
 Formats a date as the time since that date (e.g., “Last week, yesterday, etc.”).

 - Parameter from: The date to process.
 - Parameter numericDates: Determines if we should return a numeric variant, e.g. "1 month ago" vs. "Last month".

 - Returns: A string with formatted `date`.
 */

func timeAgoSinceDate(_ date:Date, numericDates:Bool = false) -> String {
    let calendar = NSCalendar.current
    let unitFlags: Set<Calendar.Component> = [.minute, .hour, .day, .weekOfYear, .month, .year, .second]
    let now = Date()
    let earliest = now < date ? now : date
    let latest = (earliest == now) ? date : now
    let components = calendar.dateComponents(unitFlags, from: earliest,  to: latest)

    if (components.year! >= 2) {
        return "\(components.year!) years ago"
    } else if (components.year! >= 1){
        if (numericDates){
            return "1 year ago"
        } else {
            return "Last year"
        }
    } else if (components.month! >= 2) {
        return "\(components.month!) months ago"
    } else if (components.month! >= 1){
        if (numericDates){
            return "1 month ago"
        } else {
            return "Last month"
        }
    } else if (components.weekOfYear! >= 2) {
        return "\(components.weekOfYear!) weeks ago"
    } else if (components.weekOfYear! >= 1){
        if (numericDates){
            return "1 week ago"
        } else {
            return "Last week"
        }
    } else if (components.day! >= 2) {
        return "\(components.day!) days ago"
    } else if (components.day! >= 1){
        if (numericDates){
            return "1 day ago"
        } else {
            return "Yesterday"
        }
    } else if (components.hour! >= 2) {
        return "\(components.hour!) hours ago"
    } else if (components.hour! >= 1){
        if (numericDates){
            return "1 hour ago"
        } else {
            return "An hour ago"
        }
    } else if (components.minute! >= 2) {
        return "\(components.minute!) minutes ago"
    } else if (components.minute! >= 1){
        if (numericDates){
            return "1 minute ago"
        } else {
            return "A minute ago"
        }
    } else if (components.second! >= 3) {
        return "\(components.second!) seconds ago"
    } else {
        return "Just now"
    }

}  }

to use this

let formatter = DateFormatter()
        formatter.dateFormat = "Your Format"
        formatter.timeZone = NSTimeZone(abbreviation: "UTC") as TimeZone! // time zone if needed 
        let messageUTCDate = formatter.date(from: "your date in string")
        return formatter.timeAgoSinceDate(messageUTCDate!)

or you can use other date format like answered here Getting the difference between two NSDates in (months/days/hours/minutes/seconds)

Finally, for button you can show them in top bar if you want.

Hope it helps

Community
  • 1
  • 1
Wasim Malek
  • 123
  • 7
  • thanks for the help dude. please tell me one more thing can we give margin to bottom label from left and right? @wasim-malek – Muhammad Umair May 02 '17 at 07:13
  • you need to modify the .XIB files of JSQ library as per your requirement. you can find all the xib in resource folder – Wasim Malek May 02 '17 at 07:36
  • bro I am using pods.. can i still modify the xib files? – Muhammad Umair May 02 '17 at 07:54
  • I am still stuck on 2nd part (buttons overlapping with collection view), do you have any solution for it? – Muhammad Umair May 02 '17 at 09:41
  • you can remove button from there and add it to navigation bar on top with `UIAlertController` will do it. I have no idea if you can move the collection view as it is embedded in `JSQMessagesViewController`. – Wasim Malek May 02 '17 at 10:20