Why in UITableView, cellForRowAtIndexPath is called before heightForRowAtIndexPath - ios

I have breakpoints in both the two methods. The cellForRowAtIndexPath is always called before heightForRowAtIndexPath.
The problem is I have a logic code in cellForRowAtIndexPath that depends on the row height.
Currently, the row height I get inside cellForRowAtIndexPath is always 0.
Is there a way to let heightForRowAtIndexPath to be called before cellForRowAtIndexPath?
If not, how to call heightForRowAtIndexPatch explicitly in my code?
EDIT:
Here is my code for cellForRowAtIndexPath:
let slideshowCell = tableView.dequeueReusableCell(withIdentifier: "SlideShowCell") as! SlideShowTableViewCell
slideshowCell.delegate = self
slideshowCell.news = featuredNews
return slideshowCell
and here is my code for heightForRowAtIndexPatch:
let filterApplied = categoryNews.count != filteredCategoryNews.count
if featuredNews.count == 0 || filterApplied
{
return 0
}
else
{
return 530
}
and when I set featuredNews to slideshowCell.news, I run this method in the slideshowCell.news's didSet property observer:
private func populateSlideshowScrollView()
{
let imagesCount = CGFloat(slideshowNews.count)
// set the scrollView's content size to the size of all the images
scrollView.contentSize = CGSize(width: scrollView.frame.width * imagesCount, height: scrollView.frame.height)
// Remove subviews of ScrollView before populating it with new images
for subview in scrollView.subviews
{
subview.removeFromSuperview()
}
// populate the scrollView with images form the 'slideshowNews' property
for i in 0..<slideshowNews.count
{
let imgView = UIImageView(frame: CGRect(x: scrollView.frame.width * CGFloat(i),
y: scrollView.bounds.origin.y,
width: scrollView.frame.width,
height: scrollView.frame.height))
imgView.contentMode = .scaleAspectFill
imgView.clipsToBounds = true
imgView.image = slideshowNews[i].image
scrollView.addSubview(imgView)
}
// set scrollview to the first page from the right, only the first two times this method called.
// After that the current page of page control should be in the correct position
if numberOfRefresh < 2
{
scrollView.setContentOffset(CGPoint(x: scrollView.frame.width * (imagesCount - 1), y: 0), animated: false)
newsTitleLabel.text = slideshowNews.last?.title
sourceLabel.text = slideshowNews.last?.source.name
numberOfRefresh += 1
}
scrollToPage(page: pageControl.currentPage, animated: false) // to update scrollView's contentOffset
}
The problem is that scrollView.frame.height will always return zero, because heightForRowAtIndexPath is not yet called at this point.

Related

Dequeue cells more than default UICollectionView dequeued cells

Is there a way to dequeue more cells than default UICollectionView dequeued cells? For example in the picture below UICollectionView dequeues showing cell, one before and one after. Is there a way to dequeue more than this three cells?func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { print("Prefetch: \(indexPaths)") }
only gives me one indexpath after. What I need is to create four or five cells after and before showing cells to Implement my functionality before cell is shown.
An official Apple sample code shows a technique that you might find useful. Instead of relying on UICollectionView to receive callbacks and load data as needed, you can observe scrolling and based on contentOffset value, you will know how much look ahead you need.
Copy pasting relevant parts here in case link isn't available for a future reader. All of this lives inside a UICollectionViewController subclass - it can be adapted to work with any UIScrollView in general.
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// This is your trigger point
updateCachedAssets()
}
var fetchResult: PHFetchResult<PHAsset>!
fileprivate let imageManager = PHCachingImageManager()
fileprivate let thumbnailSize: CGSize = CGSize(width: 100, height: 100)
fileprivate var previousPreheatRect = CGRect.zero
fileprivate func updateCachedAssets() {
// Update only if the view is visible.
guard isViewLoaded && view.window != nil else { return }
// The window you prepare ahead of time is twice the height of the visible rect.
let visibleRect = CGRect(origin: collectionView!.contentOffset, size: collectionView!.bounds.size)
let preheatRect = visibleRect.insetBy(dx: 0, dy: -0.5 * visibleRect.height)
// Update only if the visible area is significantly different from the last preheated area.
let delta = abs(preheatRect.midY - previousPreheatRect.midY)
guard delta > view.bounds.height / 3 else { return }
// Compute the assets to start and stop caching.
let (addedRects, removedRects) = differencesBetweenRects(previousPreheatRect, preheatRect)
let addedAssets = addedRects
.flatMap { rect in collectionView!.indexPathsForElements(in: rect) }
.map { indexPath in fetchResult.object(at: indexPath.item) }
let removedAssets = removedRects
.flatMap { rect in collectionView!.indexPathsForElements(in: rect) }
.map { indexPath in fetchResult.object(at: indexPath.item) }
// Update the assets the PHCachingImageManager is caching.
imageManager.startCachingImages(for: addedAssets,
targetSize: thumbnailSize, contentMode: .aspectFill, options: nil)
imageManager.stopCachingImages(for: removedAssets,
targetSize: thumbnailSize, contentMode: .aspectFill, options: nil)
// Store the computed rectangle for future comparison.
previousPreheatRect = preheatRect
}
fileprivate func differencesBetweenRects(_ old: CGRect, _ new: CGRect) -> (added: [CGRect], removed: [CGRect]) {
if old.intersects(new) {
var added = [CGRect]()
if new.maxY > old.maxY {
added += [CGRect(x: new.origin.x, y: old.maxY,
width: new.width, height: new.maxY - old.maxY)]
}
if old.minY > new.minY {
added += [CGRect(x: new.origin.x, y: new.minY,
width: new.width, height: old.minY - new.minY)]
}
var removed = [CGRect]()
if new.maxY < old.maxY {
removed += [CGRect(x: new.origin.x, y: new.maxY,
width: new.width, height: old.maxY - new.maxY)]
}
if old.minY < new.minY {
removed += [CGRect(x: new.origin.x, y: old.minY,
width: new.width, height: new.minY - old.minY)]
}
return (added, removed)
} else {
return ([new], [old])
}
}
Notes
The code is several years old and you will need to adapt this to your requirements.
You can adjust the preheatRect compute to be what fits your needs.
// The window you prepare ahead of time is twice the height of the visible rect.
let visibleRect = CGRect(origin: collectionView!.contentOffset, size: collectionView!.bounds.size)
let preheatRect = visibleRect.insetBy(dx: 0, dy: -0.5 * visibleRect.height)
The sample implements this preheatRect logic for preloading PHAsset thumbnails. You need to adapt your dataSource to a similar style and start/stop loading your resources.

Resizing UICollectionView with Custom Layout after deleting cells

I downloaded this Pintrest-esc Custom Layout for my CollectionView from : https://www.raywenderlich.com/164608/uicollectionview-custom-layout-tutorial-pinterest-2 (modified it a little bit to do with cache code)
So the layout works fine, i got it set up so when you scroll to the bottom, i make another API call, create and populate additional cells.
Problem: If a User scrolls down and loads some more cells (lets say 20 for example) and then uses the "Search Feature" i have implemented at the top, it will then filter some of the data via price from MinRange - MaxRange leaving you with (lets say 5 results), thus deleting some cells and repopulating those. BUT - All that space and scrollable space that existed for the first 20 cells still exists as blank white space.... How can i remove this space ? and why can it resize when adding more cells, but not when removing them ?
Code of my API Call:
DispatchQueue.global(qos: .background).async {
WebserviceController.GetSearchPage(parameters: params) { (success, data) in
if success
{
if let products = data!["MESSAGE"] as? [[String : AnyObject]]
{
self.productList = products
}
}
DispatchQueue.main.async(execute: { () -> Void in
self.pintrestCollectionView.reloadData()
self.pintrestCollectionView.collectionViewLayout.invalidateLayout()
self.pintrestCollectionView.layoutSubviews()
})
}
}
Code Of Custom Layout Class & protocol:
protocol PinterestLayoutDelegate: class {
func collectionView(_ collectionView:UICollectionView, heightForPhotoAtIndexPath indexPath:IndexPath) -> CGFloat
}
class PintrestLayout: UICollectionViewFlowLayout {
// 1
weak var delegate : PinterestLayoutDelegate!
// 2
fileprivate var numberOfColumns = 2
fileprivate var cellPadding: CGFloat = 10
// 3
fileprivate var cache = [UICollectionViewLayoutAttributes]()
// 4
fileprivate var contentHeight: CGFloat = 0
fileprivate var contentWidth: CGFloat {
guard let collectionView = collectionView else {
return 0
}
let insets = collectionView.contentInset
return collectionView.bounds.width - (insets.left + insets.right)
}
// 5
override var collectionViewContentSize: CGSize {
return CGSize(width: contentWidth, height: contentHeight)
}
override func prepare() {
// 1
//You only calculate the layout attributes if cache is empty and the collection view exists.
/*guard cache.isEmpty == true, let collectionView = collectionView else {
return
}*/
cache.removeAll()
guard cache.isEmpty == true || cache.isEmpty == false, let collectionView = collectionView else {
return
}
// 2
//This declares and fills the xOffset array with the x-coordinate for every column based on the column widths. The yOffset array tracks the y-position for every column.
let columnWidth = contentWidth / CGFloat(numberOfColumns)
var xOffset = [CGFloat]()
for column in 0 ..< numberOfColumns {
xOffset.append(CGFloat(column) * columnWidth)
}
var column = 0
var yOffset = [CGFloat](repeating: 0, count: numberOfColumns)
// 3
//This loops through all the items in the first section, as this particular layout has only one section.
for item in 0 ..< collectionView.numberOfItems(inSection: 0) {
if collectionView.numberOfItems(inSection: 0) < 3
{
collectionView.isScrollEnabled = false
} else {
collectionView.isScrollEnabled = true
}
let indexPath = IndexPath(item: item, section: 0)
// 4
//This is where you perform the frame calculation. width is the previously calculated cellWidth, with the padding between cells removed.
let photoHeight = delegate.collectionView(collectionView, heightForPhotoAtIndexPath: indexPath)
let height = cellPadding * 2 + photoHeight
let frame = CGRect(x: xOffset[column], y: yOffset[column], width: columnWidth, height: height)
let insetFrame = frame.insetBy(dx: 7, dy: 4)
collectionView.contentInset = UIEdgeInsets.init(top: 15, left: 12, bottom: 0, right: 12)
// 5
//This creates an instance of UICollectionViewLayoutAttribute, sets its frame using insetFrame and appends the attributes to cache.
let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
attributes.frame = insetFrame
cache.append(attributes)
// 6
//This expands contentHeight to account for the frame of the newly calculated item.
contentHeight = max(contentHeight, frame.maxY)
yOffset[column] = yOffset[column] + height
column = column < (numberOfColumns - 1) ? (column + 1) : 0
}
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]?
{
var visibleLayoutAttributes = [UICollectionViewLayoutAttributes]()
// Loop through the cache and look for items in the rect
for attributes in cache {
if attributes.frame.intersects(rect) {
visibleLayoutAttributes.append(attributes)
}
}
return visibleLayoutAttributes
}
FYI: In MainStoryboard, i disabled "Adjust Scroll View Insets" as many of other threads and forums have suggested...
I'm guessing you've already found the answer, but I'm posting here for the next person since I ran into this issue.
The trick here is contentHeight actually never gets smaller.
contentHeight = max(contentHeight, frame.maxY)
This is a nondecreasing function.
To fix it, just set contentHeight to 0 if prepare is called:
guard cache.isEmpty == true || cache.isEmpty == false, let
collectionView = collectionView else {
return
}
contentHeight = 0

How to set UICollectionView bottom padding and scrolling size

Hello I have working uicollectionview custom layout and i have issuesfor bottom padding and scrolling sizes. Under below picture you can see;
Also top side first cell always stays on top when scrolling ( Left side cell must be always stay right now no problem there , but top side cell must be scroll when scrolling )
I try to set in viewDidLoad under below codes but dont work
self.automaticallyAdjustsScrollViewInsets = false
self.collectionView.contentInset = UIEdgeInsetsMake(20, 20, 120, 100);
My custom collectionview layout file
import UIKit
public var CELL_HEIGHT = CGFloat(22)
protocol CustomCollectionViewDelegateLayout: NSObjectProtocol {
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, widthForItemAtIndexPath indexPath: NSIndexPath) -> CGFloat
}
class CustomCollectionViewLayout: UICollectionViewLayout {
// Used for calculating each cells CGRect on screen.
// CGRect will define the Origin and Size of the cell.
let STATUS_BAR = UIApplication.sharedApplication().statusBarFrame.height
// Dictionary to hold the UICollectionViewLayoutAttributes for
// each cell. The layout attribtues will define the cell's size
// and position (x, y, and z index). I have found this process
// to be one of the heavier parts of the layout. I recommend
// holding onto this data after it has been calculated in either
// a dictionary or data store of some kind for a smooth performance.
var cellAttrsDictionary = Dictionary<NSIndexPath, UICollectionViewLayoutAttributes>()
// Defines the size of the area the user can move around in
// within the collection view.
var contentSize = CGSize.zero
// Used to determine if a data source update has occured.
// Note: The data source would be responsible for updating
// this value if an update was performed.
var dataSourceDidUpdate = true
weak var delegate: CustomCollectionViewDelegateLayout?
override func collectionViewContentSize() -> CGSize {
return self.contentSize
}
override func prepareLayout() {
// Only update header cells.
if !dataSourceDidUpdate {
// Determine current content offsets.
let xOffset = collectionView!.contentOffset.x
let yOffset = collectionView!.contentOffset.y
if collectionView?.numberOfSections() > 0 {
for section in 0...collectionView!.numberOfSections()-1 {
// Confirm the section has items.
if collectionView?.numberOfItemsInSection(section) > 0 {
// Update all items in the first row.
if section == 0 {
for item in 0...collectionView!.numberOfItemsInSection(section)-1 {
// Build indexPath to get attributes from dictionary.
let indexPath = NSIndexPath(forItem: item, inSection: section)
// Update y-position to follow user.
if let attrs = cellAttrsDictionary[indexPath] {
var frame = attrs.frame
// Also update x-position for corner cell.
if item == 0 {
frame.origin.x = xOffset
}
frame.origin.y = yOffset
attrs.frame = frame
}
}
// For all other sections, we only need to update
// the x-position for the fist item.
} else {
// Build indexPath to get attributes from dictionary.
let indexPath = NSIndexPath(forItem: 0, inSection: section)
// Update y-position to follow user.
if let attrs = cellAttrsDictionary[indexPath] {
var frame = attrs.frame
frame.origin.x = xOffset
attrs.frame = frame
}
}
}
}
}
// Do not run attribute generation code
// unless data source has been updated.
return
}
// Acknowledge data source change, and disable for next time.
dataSourceDidUpdate = false
var maxWidthInASection = CGFloat(0)
// Cycle through each section of the data source.
if collectionView?.numberOfSections() > 0 {
for section in 0...collectionView!.numberOfSections()-1 {
// Cycle through each item in the section.
if collectionView?.numberOfItemsInSection(section) > 0 {
var prevCellAttributes: UICollectionViewLayoutAttributes?
for item in 0...collectionView!.numberOfItemsInSection(section)-1 {
let cellIndex = NSIndexPath(forItem: item, inSection: section)
guard let width = delegate?.collectionView(collectionView!, layout: self, widthForItemAtIndexPath: cellIndex) else {
print("Please comform to CustomCollectionViewDelegateLayout protocol")
return
}
// Build the UICollectionVieLayoutAttributes for the cell.
var xPos = CGFloat(0)
let yPos = CGFloat(section) * CELL_HEIGHT
if let prevCellAttributes = prevCellAttributes {
xPos = CGRectGetMaxX(prevCellAttributes.frame)
}
let cellAttributes = UICollectionViewLayoutAttributes(forCellWithIndexPath: cellIndex)
cellAttributes.frame = CGRect(x: xPos, y: yPos, width: width, height: CELL_HEIGHT)
// Determine zIndex based on cell type.
if section == 0 && item == 0 {
cellAttributes.zIndex = 4
} else if section == 0 {
cellAttributes.zIndex = 3
} else if item == 0 {
cellAttributes.zIndex = 2
} else {
cellAttributes.zIndex = 1
}
// Save the attributes.
cellAttrsDictionary[cellIndex] = cellAttributes
prevCellAttributes = cellAttributes
let maxX = CGRectGetMaxX(cellAttributes.frame)
if maxWidthInASection < maxX {
maxWidthInASection = maxX
}
}
}
}
}
// Update content size.
let contentWidth = maxWidthInASection
let contentHeight = Double(collectionView!.numberOfSections())
self.contentSize = CGSize(width: Double(contentWidth), height: contentHeight)
self.contentSize.height = CGFloat(Double(collectionView!.numberOfSections()))
}
override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
// Create an array to hold all elements found in our current view.
var attributesInRect = [UICollectionViewLayoutAttributes]()
// Check each element to see if it should be returned.
for cellAttributes in cellAttrsDictionary.values.elements {
if CGRectIntersectsRect(rect, cellAttributes.frame) {
attributesInRect.append(cellAttributes)
}
}
// Return list of elements.
return attributesInRect
}
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes? {
return cellAttrsDictionary[indexPath]!
}
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
return true
}
}
I try change collecionview properties in storyboard but doesnt works also i attached current collectionview object properties picture under below
Also i selected zoom 4 but zoom feature doesnt work ? why ? it must be work also zoom feature.
I know this is too late to answer, but this could be useful to other users.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 50, right: 0)
}
This what worked for me:
messagesCollectionView.contentInset.top = 100
messagesCollectionView.contentInset.bottom = 80
This can be also done on IB under section insets...

Image and scrollView rendering making my tableview choppy

There may be no good solution for my problem, but I want to ask just in case.
I have a tableview in which each cell contains a horizontal scrollview of variable width. The width of each cell's scrollview depends on the number and sizes of the images for that cell. Everything works pretty well, but the tableview scrolls less smoothly than it could. I'm using Parse to retrieve the images (and pfquertableviewcontroller), but this question should apply to tableviews in general.
Here is my tableview code:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject?) -> PFTableViewCell? {
if var cell:MainFeedTableViewCell? = tableView.dequeueReusableCellWithIdentifier(self.cellIdentifier) as? MainFeedTableViewCell{
if(cell == nil) {
cell = NSBundle.mainBundle().loadNibNamed("MainFeedTableViewCell", owner: self, options: nil)[0] as? MainFeedTableViewCell
}
cell?.parseObject = object
return cell
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if let c = (cell as? MainFeedTableViewCell){
c.setUpObject()//this is where images are set
}
}
override func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if let c = (cell as? MainFeedTableViewCell){
c.resetObject() //this sets most of the properties to nil
}
}
And here is the function in my cell where images are set
func setUpObject(){
//I left out several lines of code where label text is set from the parseObject that is set when the cell is created
//setting images **problems here**
if let numImages = self.parseObject?["numImages"] as? Int{
self.newWidth1 = self.parseObject?["width1"] as? CGFloat
self.newWidth2 = self.parseObject?["width2"] as? CGFloat
self.newWidth3 = self.parseObject?["width3"] as? CGFloat
self.newWidth4 = self.parseObject?["width4"] as? CGFloat
self.newWidth5 = self.parseObject?["width5"] as? CGFloat
if numImages == 1{
self.containerView = UIView(frame: CGRect(x: self.scrollView.frame.minX, y: self.scrollView.bounds.minY - 90, width: self.scrollView.frame.width, height: self.scrollView.frame.height))
self.image1 = PFImageView(frame: CGRect(x: self.scrollView.frame.minX , y: self.scrollView.frame.minY, width: self.scrollView.frame.width, height: self.scrollView.frame.height))
self.image1?.contentMode = UIViewContentMode.ScaleAspectFit
self.image1!.file = self.parseObject?["image"] as? PFFile
self.image1!.loadInBackground()
self.containerView!.addSubview(self.image1!)
self.scrollView.contentSize = self.containerView!.bounds.size
self.scrollView.addSubview(self.containerView!)
}
else if numImages == 2{
if self.newWidth1 + self.newWidth2 < self.scrollView.frame.width{
self.containerView = UIView(frame: CGRect(x: self.scrollView.frame.midX - (self.newWidth1 + self.newWidth2)/2, y: self.scrollView.bounds.minY - 90, width: (self.newWidth1 + self.newWidth2), height: self.scrollView.frame.height))
}
else{
self.containerView = UIView(frame: CGRect(x: self.scrollView.frame.minX, y: self.scrollView.bounds.minY - 90, width: (self.newWidth1 + self.newWidth2), height: self.scrollView.frame.height))
}
self.image1 = PFImageView(frame: CGRect(x: self.scrollView.frame.minX , y: self.scrollView.frame.minY, width: self.newWidth1, height: self.scrollView.frame.height))
self.image1!.file = self.parseObject?["image"] as? PFFile
self.image1!.loadInBackground()
self.containerView!.addSubview(self.image1!)
self.image2 = PFImageView(frame: CGRect(x: (self.scrollView.frame.minX + self.newWidth1), y: self.scrollView.frame.minY, width: self.newWidth2, height: self.scrollView.frame.height))
self.image2!.file = self.parseObject?["image2"] as? PFFile
self.image2!.loadInBackground()
self.containerView!.addSubview(self.image2!)
self.subLayer = CALayer()
self.subLayer.backgroundColor = UIColor.whiteColor().CGColor
self.subLayer.frame = CGRect(x: self.newWidth1, y: self.scrollView.frame.minY, width: 1, height: self.scrollView.frame.height)
self.containerView!.layer.addSublayer(self.subLayer)
self.scrollView.contentSize = self.containerView!.bounds.size
self.scrollView.addSubview(self.containerView!)
}
//repeat similar code for cases where there are 3, 4, or 5 images
There might be a fundamental issue with dynamically adjusting the size of the scrollview and adding it to superview just in time, but I'm trying to follow the design mockup that my designer gave me.
Here is what the scrollview on the cell looks like (with each image in the scrollview separated by a thin white line)
Remove your willDisplayCell and didEndDisplayingCell. That will fire as you scroll and your setUpObject code, while not huge, will block the main thread slightly. Instead move setUpObject() to right before returning the cell in cellForRowAtIndexPath.
Depending on how many rows you have and performance requirements you could also adjust the viewController to download all of the images ahead of time and pass them to the cell instead of loading them inside the cell.

Where to call the reloadData when updating tableview?

I am very new to swift programming so probably asking you a basic question but something I need to know.
I have an implementation where I am chatting with a bot so to speak. So the control flow is this:
I say "hi" this has to be reflected in the "chat" box and then the response that comes back from the web service also has to become a chat message.
Obviously, my messages and the other response from the web service should be of different colours and styles and I am doing that in my tableView function.
Here is my tableView code
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:tblCell = tblCell()
let font = UIFont(name:"Helvetica" , size: 14)
if(tableView.isEqual(messageTableView)) {
var chatMessage:ChatMessage = self.messageArray[indexPath.row]
cell=self.messageTableView.dequeueReusableCellWithIdentifier("MessageCell") as! tblCell
dispatch_async(dispatch_get_main_queue()) {
//Determining the size of the chat box
cell.messageText.sizeToFit()
cell.messageText.text = chatMessage.message
cell.messageText.numberOfLines = 0
cell.messageText.font = font
var frame: CGRect = cell.messageText.frame
cell.messageText.layer.cornerRadius = 10
cell.messageText.layer.masksToBounds = true
//if it is a user input message use this
if(chatMessage.messageType == "user") {
cell.messageText.textAlignment = NSTextAlignment.Right
cell.messageText.backgroundColor = self.UIColorFromRGB(0x0099FF)
cell.messageText.textColor = UIColor.whiteColor()
//code to right align the label
if(frame.width <= 148) {
frame.origin.x = 148 - frame.width
}
else {
frame.origin.x = 0
}
cell.messageText.frame = frame
} else if(chatMessage.messageType == “bot”) {
cell.messageText.textAlignment = NSTextAlignment.Left
cell.messageText.backgroundColor = UIColor.lightGrayColor()
}
var size:CGSize = CGSize(width: frame.width + 20, height: frame.height + 20)
cell.messageText.sizeThatFits(size)
if tableView.contentSize.height > tableView.frame.size.height && self.shouldScrollToLastRow {
let offset = CGPoint(x: 0, y: tableView.contentSize.height - tableView.frame.size.height)
tableView.setContentOffset(offset, animated: false)
self.shouldScrollToLastRow = false
}
}
return cell
}
return cell
}
Now I am experiencing trouble with the size of the message as it doesn't return the right size all the time. Meaning, as I scroll up and down, the size of the boxes keep changing.
I am thinking the problem is with reloadData() and I am not sure where I should be calling it.
Please note that I have an asynchronous request parse code written down and updating my chat from the response of the request.
What am I doing wrong?
Please help
Nikhil

Resources