UITableCell Swipe/Slide Two or Multiple Cell - ios

I want to ask how could I have done this feature you can see in this image:
I know the editActionsForRowAt but I think it's not the solution for the things I need to do, so I added UISwipeGestureRecognizer and my code look like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellId", for: indexPath) as! ConnectionTableCell
let users = self.users[indexPath.section]
let user = users.userInfo[indexPath.row]
cell.userImage.image = UIImage(named: user.imageUrl)
cell.name.text = user.name
cell.work.text = user.work
cell.selectionStyle = .none
cell.addGestureRecognizer(UISwipeGestureRecognizer(target: self, action: #selector(didSwipeForRow)))
return cell
}
func didSwipeForRow(recognizer: UIGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.ended {
let swipeLocation = recognizer.location(in: self.tableView)
if let swipedIndexPath = tableView.indexPathForRow(at: swipeLocation) {
let textConstant = tableView.frame.width + 10
let imageConstant = tableView.frame.width - 20
let swipeView = UIView()
swipeView.backgroundColor = UIColor.themeColor(color: .green)
let cell = tableView.cellForRow(at: swipedIndexPath) as! ConnectionTableCell
let height = cell.frame.height
let users = self.users[swipedIndexPath.section]
let user = users.userInfo[swipedIndexPath.row]
cell.addSubview(swipeView)
swipeView.frame = CGRect(x: 0, y: 0, width: imageConstant - 60, height: height)
cell.name.leftAnchor.constraint(equalTo: self.tableView.rightAnchor, constant: textConstant).isActive = true
cell.work.leftAnchor.constraint(equalTo: self.tableView.rightAnchor, constant: textConstant).isActive = true
cell.userImage.rightAnchor.constraint(equalTo: self.tableView.rightAnchor, constant: imageConstant).isActive = true
}
}
}
But the problem is when I swipe a cell its also affecting the reused cell as you can see in this image :
Any suggestions on how to solve this issue? Thanks in advance guys.

Related

Can't remove view from superview on reusable tableview cell

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: EventCommentsCustom = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! EventCommentsCustom
guard let release = array[exist: indexPath.section] else { return cell }
if release.user == "condition" {
let image = UIImage()
let imageView = UIImageView(image: image)
imageView.sd_setImage(with: URL(string: "https://example.com/" + TegKeychain.get("profile_pic")!))
imageView.frame = CGRect(x: 20, y: 10, width: 50, height:50)
imageView.layer.borderWidth = 0.4
imageView.layer.masksToBounds = false
imageView.layer.borderColor = UIColor.gray.cgColor
imageView.layer.cornerRadius = 25
imageView.clipsToBounds = true
imageView.tag = 3
cell.addSubview(imageView)
let button = UIButton(frame: CGRect(x: 90, y: 10, width: 200, height: 50))
button.contentHorizontalAlignment = .left
button.setTitleColor(UIColor.lightGray, for: .normal)
button.setTitle(NSLocalizedString("Say something...", comment: ""), for: .normal)
button.addTarget(self, action: #selector(EventComments.openInput), for: .touchUpInside)
button.tag = 3
cell.addSubview(button)
} else {
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIImageView {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIButton {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
}
return cell
}
I am trying to remove views that I created with a tag in a reusable tableview cell.
However, I still can see UIButton and UIImageview when first reused (5. section of tableview), then It starts to remove properly
Why don't they get removed at the first reuse?
I guess that reusing in your case could mean that the image view and button get added twice for a cell. You only remove one of them though. I think you should take a different approach (like different prototype cells as #vadian stated) into consideration but for now (assuming my assumption is correct) you could try this to fix your problem:
Replace ...
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIImageView {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
if let viewWithTag = cell.viewWithTag(3) {
if viewWithTag is UIButton {
print("DONE")
viewWithTag.removeFromSuperview()
}
}
With ...
while let viewToRemove = cell.viewWithTag(3) {
if viewToRemove is UIImageView || viewToRemove is UIButton {
viewToRemove.removeFromSuperview()
}
}
Update -
The approach with different cell types would look something like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let release = array[exist: indexPath.section] else { return cell }
if release.user == "condition" {
let cell = tableView.dequeueReusableCell(withIdentifier: "OneIdentifier", for: indexPath) as! OneCustomCellType
// configure your cell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "AnotherIdentifier", for: indexPath) as! AnotherCustomCellType
// configure your cell
return cell
}
}

View reappears in UITableViewCell after scrolling off and on

I have a UITableView with 2 sections. In the first section I do not want the UIView I have created to appear on the left. It works fine when it initially loads but when it goes off screen and back on again it reappears.
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier") as! ATableCell;
cell.delegate = self;
if (indexPath.section == 1)
{
// let height = cell.bounds.size.height;
let height = 100;
let turnsView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: height));
turnsView.backgroundColor = UIColor.purple;
cell.addSubview(turnsView);
}
else
{
let height = 100;
let turnsView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: height));
turnsView.backgroundColor = UIColor.clear;
cell.addSubview(turnsView);
}
// Configure the cell...
cell.backgroundColor = UIColor.clear;
cell.textLabel?.text = "texting";
cell.detailTextLabel?.text = "testing";
}
I don't want the purple view appearing in the first section at any point.
When using
tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
You should use Every "if" condition with its "else" clause as when you scroll on off it reuses the cell that cause it to reappear. So if you not write else condition and if condition become false it will use old cell data.
Always avoid adding subviews to cell in cellForRow. You need to understand that the cells are reused and when you add the subView in cellForRow, the subView is not removed each time. So if the cell appears for 10 times due to scrolling on and off, 10 subViews would be added to the reused cell.
In your case same thing is happening. I would suggest you to add the view in XIB/Prototype cell. Give it a reference and change its backgroundColor property in cellForRow.
Or if you are not using XIB or prototype cell, add subview in init method in your cell class.
var turnsView = UIView()
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
turnsView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: 100))
self.contentView.addSubview(turnsView)
}
This should work for you:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier") as! ATableCell;
cell.delegate = self;
//Remove subviews before adding again
if let purpleV = cell.viewWithTag(1) {
purpleV.removeFromSuperview()
}
if let purpleV = cell.viewWithTag(2) {
purpleV.removeFromSuperview()
}
if (indexPath.section == 1)
{
// let height = cell.bounds.size.height;
let height = 100;
let turnsView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: height));
turnsView.tag = 1
turnsView.backgroundColor = UIColor.purple;
cell.addSubview(turnsView);
}
else
{
let height = 100;
let turnsView = UIView(frame: CGRect(x: 0, y: 0, width: 10, height: height));
turnsView.tag = 2
turnsView.backgroundColor = UIColor.clear;
cell.addSubview(turnsView);
}
// Configure the cell...
cell.backgroundColor = UIColor.clear;
cell.textLabel?.text = "texting";
cell.detailTextLabel?.text = "testing";
}
Read the documentation for dequeuereusablecell method to clarify.
This will be good to do as:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
// Config the cell...
if let turnsCell as? ATableCell {
turnsCell.turnsColor = (indexPath.section == 1 ? UIColor.purple : UIColor.clear)
}
cell.textLabel?.text = "texting"
cell.detailTextLabel?.text = "testing"
return cell
}
class ATableCell: UITableViewCell {
var turnsView = UIView()
var turnsColor: UIColor {
get {
return self.turnsView.backgroundColor
}
set {
self.turnsView.backgroundColor = newValue
}
}
override func awakeFromNib() {
super.awakeFromNib()
// let height = self.bounds.size.height;
let height = 100;
turnsView.frame = CGRect(x: 0, y: 0, width: 10, height: height)
self.contentView.addSubview(turnsView)
self.backgroundColor = UIColor.clear
}
}

Swift - How to change the color of an accessoryType (disclosureIndicator)?

I have question about the accessoryType of cells. I am using a cell with an disclosureIndicator as accessoryType and I want to change it's color but I can't.
Does anyone know if this is a bug or if Apple forces me to use the grey color?
Actually I can change the colors of other accessoryType.
My code looks like this:
let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath) as! customCell
cell.tintColor = UIColor.red
cell.accessoryType = .disclosureIndicator
And my arrow is still grey. But if I use a checkmark accessoryType it becomes red.
Is there any way to fix this or do I have to use a colored image?
You can do something like this
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.tintColor = UIColor.white
let image = UIImage(named: "Arrow.png")
let checkmark = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!));
checkmark.image = image
cell.accessoryView = checkmark
let object = objects[indexPath.row] as! NSDate
cell.textLabel!.text = object.description
return cell
}
Sample Arrow Images
Output
Use SF Symbol
let image = UIImage(systemName: "chevron.right")
let accessory = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!))
accessory.image = image
// set the color here
accessory.tintColor = UIColor.white
cell.accessoryView = accessory
Updated for Swift 4.2 with images attached:
cell.accessoryType = .disclosureIndicator
cell.tintColor = .black
let image = UIImage(named:"disclosureArrow")?.withRenderingMode(.alwaysTemplate)
if let width = image?.size.width, let height = image?.size.height {
let disclosureImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: width, height: height))
disclosureImageView.image = image
cell.accessoryView = disclosureImageView
}
Images you can use:
What it could look like:
Bellow Code is Swift 3.0 code, and will change the accessoryType color as per tintColor.
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.textLabel?.text = "SOME TITLE GOES HERE"
cell.accessoryType = .disclosureIndicator
cell.tintColor = UIColor.blue
let image = UIImage(named:"arrow1")?.withRenderingMode(.alwaysTemplate)
let checkmark = UIImageView(frame:CGRect(x:0, y:0, width:(image?.size.width)!, height:(image?.size.height)!));
checkmark.image = image
cell.accessoryView = checkmark
return cell
}
Swift 5. Extension style ;)
extension UITableViewCell {
func setupDisclosureIndicator() {
accessoryType = .disclosureIndicator
let imgView = UIImageView(frame: CGRect(x: 0, y: 0, width: 7, height: 12))
imgView.contentMode = .scaleAspectFit
imgView.image = UIImage(named: "your_icon_name")
accessoryView = imgView
}
}
Swift 5 & iOS 15 & Xcode 13
Here is an extension which uses SF Symbols, so you have a chevron like the default disclosure indicator one:
extension UITableViewCell {
func addCustomDisclosureIndicator(with color: UIColor) {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 10, height: 15))
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 15, weight: .regular, scale: .large)
let symbolImage = UIImage(systemName: "chevron.right",
withConfiguration: symbolConfig)
button.setImage(symbolImage?.withTintColor(color, renderingMode: .alwaysOriginal), for: .normal)
button.tintColor = color
self.accessoryView = button
}
}
You can use it like this:
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
cell.addCustomDisclosureIndicator(with: .white) // Here your own color
return cell
}
Swift 5 & iOS 11-15
A combination of some answers
extension UITableViewCell {
func addCustomDisclosureIndicator(with color: UIColor) {
accessoryType = .disclosureIndicator
let disclosureImage = UIImage(named: "arrow_right")?.withRenderingMode(.alwaysTemplate)
let imageWidth = (disclosureImage?.size.width) ?? 7
let imageHeight = (disclosureImage?.size.height) ?? 12
let accessoryImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: imageWidth, height: imageHeight))
accessoryImageView.contentMode = .scaleAspectFit
accessoryImageView.image = disclosureImage
accessoryImageView.tintColor = color
accessoryView = accessoryImageView
}
}

Table View Cell Content Repeating While I reload data

My table view cell is repeating when scroll while waiting to reload Data . After reload all item are reset and all repeating content are remove . Here a video showing the problem , anyone know why and how can i fixed it ? As you can see in the video the hdsdjhjdhhsdsjshhsdhsjhdjd is repeating again on the top?
https://www.dropbox.com/s/e0arcajkuuot8xa/Reflector%20Recording.mp4?dl=0
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:StatusTableCell! = tableView.dequeueReusableCellWithIdentifier("statusCell", forIndexPath: indexPath) as! StatusTableCell
if (cell == nil) {
cell.uploadDate = nil
cell.uploadStatus.text = nil
cell.statusUploader.setTitle("", forState: .Normal)
}
cell.photoImage.hidden = true
self.photoHidden = true
print("\n\n\n\n")
cell.layoutIfNeeded()
cell.likesButton.setImage(UIImage(named: "Likes"), forState: .Normal)
cell.likesButton.setTitle("0", forState: UIControlState.Normal)
print("\n\n\n\n")
//Makes The Cell Of Text View Detect Link
cell.uploadStatus.dataDetectorTypes = .Link
cell.uploadStatus.delegate = self
do {
print(date2)
cell.statusUploader.setTitle("\(user2[indexPath.row])", forState: UIControlState.Normal)
if isLoadingLikes == false {
//Modified Height Based ON Status NOTE: STILL BUGGY
cell.uploadStatus.text = status2[indexPath.row]
cell.uploadStatus.frame.size.height = textViewHeight(cell.uploadStatus)
test = cell.uploadStatus.frame.size.height
self.tableView(tableView, heightForRowAtIndexPath: indexPath)
//Likes Button Data
let uploadLikes = likes2[indexPath.row]
cell.likesButton.tag = indexPath.row
cell.likesButton.setTitle("\(uploadLikes)", forState: UIControlState.Normal)
//Add An Action Connector To Likes Button
cell.likesButton.addTarget(self, action: Selector("likesFunction:"), forControlEvents: .TouchUpInside)
cell.moreButton.addTarget(self, action: Selector("moreFunction:"), forControlEvents: .TouchUpInside)
print(liked2)
if liked2[indexPath.row] == "liked" {
cell.likesButton.setImage(UIImage(named: "Likes2"), forState: .Normal)
}else {
cell.likesButton.setImage(UIImage(named: "Likes"), forState: .Normal)
}
}
print("----------------------------- Row \(indexPath.row)")
print("Checking Date Array\(date2[indexPath.row])")
print("Check NSDATE \(NSDate().timeIntervalSinceDate(date2[indexPath.row]))")
print("Checking TIME FORMATTER \(timeAgoSinceDate(date2[indexPath.row], numericDates: true))")
print("Status = \(status2[indexPath.row])")
cell.uploadDate.text = timeAgoSinceDate(date2[indexPath.row], numericDates: true)
let stringWithNSDataDetector: String = cell.uploadStatus.text
let error: NSError? = nil
let dataDetector: NSDataDetector = try NSDataDetector(types: NSTextCheckingType.Link.rawValue)
//Check if (error) before
var allMatches: [AnyObject] = [AnyObject]()
dataDetector.enumerateMatchesInString(stringWithNSDataDetector, options: NSMatchingOptions.Anchored, range: NSMakeRange(0, stringWithNSDataDetector.characters.count), usingBlock: { (match:NSTextCheckingResult?, flags:NSMatchingFlags, pointer:UnsafeMutablePointer<ObjCBool>) -> Void in
print("Link \(match!.resultType == .Link)")
if match!.resultType == .Link {
allMatches.append(match!.URL!)
self.photoHidden = false
cell.photoImage.hidden = false
print(match!.URL!)
}
})
print("ALL Matches \(allMatches)")
print("Test \(test) -- row : \(indexPath.row)")
print(cell.uploadStatus.frame.size.height)
}
catch {
print("Error Loading Status -- (StatusTableView)")
}
print("----------------------------- End \n")
cell.setNeedsDisplay()
return cell
}
And here is another
func textViewHeight (textView:UITextView) -> CGFloat{
textView.scrollEnabled = false
let fixedWidth = textView.frame.size.width
textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.max))
var newFrame = textView.frame
newFrame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)
textView.frame = newFrame;
return textView.frame.height
}
internal func textViewHeightForText(text: String?, andWidth width: CGFloat) -> CGFloat {
let calculationView = UITextView()
//IMPORTANT - have to specify the name/size of your font
let attributedText = NSAttributedString(string: (text != nil) ? text! : "", attributes: [NSFontAttributeName : UIFont(name: "Helvetica Neue", size: 16.0)!])
calculationView.attributedText = attributedText
let height = calculationView.sizeThatFits(CGSize(width: width, height: CGFloat.max)).height
return height
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let width = tableView.frame.size.width - 79
if photoHidden == false {
return textViewHeightForText(status2[indexPath.row], andWidth: width) + 260
}else {
return textViewHeightForText(status2[indexPath.row], andWidth: width) + 140
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.dequeueReusableCellWithIdentifier("statusCell", forIndexPath: indexPath) as! StatusTableCell
cell.uploadStatus.text = status2[indexPath.row]
cell.uploadStatus.frame.size.height = textViewHeight(cell.uploadStatus)
test = cell.uploadStatus.frame.size.height
self.tableView(tableView, heightForRowAtIndexPath: indexPath)
//If it is last row of the loaded table views , it will loading it got more than one current object else finish loading
if (indexPath.row == objectCount - 1) && isLoadingMoreCell == false
{
self.isLoadingMoreCell = true
self.tableView.tableFooterView = footerView
footerLoading.center.x = self.footerView.frame.width/2
footerLoading.startAnimating()
loadMoreCell()
}
}

UICollectionview view in cell incorrect drawing

I am writing a chat application for Apple-tv, and I have a problem with displaying custom view in cells chat.
I have code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ->
UICollectionViewCell {
var myCell = self.chatCollectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: indexPath) as UICollectionViewCell
myCell.removeFromSuperview()
currentIndexPath = indexPath
if flag[indexPath.row]==0
{
myCell = sendBotMessage(historyString[indexPath.row], path: indexPath, collectionView: chatCollectionView)
}
else
{
myCell = sendUserMessage(historyString[indexPath.row], path: indexPath, collectionView: chatCollectionView)
}
return myCell
}
Code displays two versions of messages, as can be seen, sendBotMessage and sendUserMessage. The problem is that the display of the next cell is rendered incorrectly previous. First run with 1 sendBotMessage-view
and after adding second item
second (right) messages adding by sendUserMessage, another view.
the whole history of "correspondence" is stored in historyString - an array of type string. Storage is organized correctly , as when scrolling display errors disappear. For this reason, it can be concluded about the correctness of the rendering functions .
All new message appends in historyString, after that calling reloadData() and collectionView must be redrawing.
Where I could make a mistake? I tried to clean the subview for collectionView, disable scrolling animation, it did not help.
Code of procedure drawing view's :
func sendUserMessage(text : String, path : NSIndexPath, collectionView : UICollectionView) -> UICollectionViewCell {
let userMessage = text
let textSize = getTextFrameSize(userMessage)
let frameForMessage = getFrameforView(textSize)
let messageBuble = Chat_ViewInCell(frame: frameForMessage, textSize: textSize, text: userMessage)
messageBuble.backgroundColor = UIColor.clearColor()
let avatarImage = UIImage(named: "\(userAvatar+1).png")
let avatarView = UIImageView(image: avatarImage)
avatarView.contentMode = UIViewContentMode.ScaleAspectFit
let totalX = messageBuble.frame.width + 340
let constraint = 1750 - totalX
messageBuble.frame.origin = CGPointMake(constraint, 0)
avatarView.frame = CGRectMake(messageBuble.frame.maxX + 10, 0, 170, 170)
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: path) as! chatCollectionViewCell
//добавляем, счастье, радуемся
cell.addSubview(messageBuble)
cell.addSubview(avatarView)
return cell
}
func sendBotMessage(text : String, path : NSIndexPath, collectionView : UICollectionView) -> UICollectionViewCell {
let userMessage = text
let textSize = getTextFrameSize(userMessage)
let frameForMessage = getFrameforView(textSize)
let messageBuble = bot_ViewInCell(frame: frameForMessage, textSize: textSize, text: userMessage)
messageBuble.backgroundColor = UIColor.clearColor()
let avatarImage = UIImage(named: partner_image)
let avatarView = UIImageView(image: avatarImage)
avatarView.contentMode = UIViewContentMode.ScaleAspectFit
avatarView.frame = CGRectMake(0, 0, 170, 170)
let constraint = avatarView.frame.maxX + 10
messageBuble.frame.origin = CGPointMake(constraint, 0)
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: path) as! chatCollectionViewCell
//добавляем в возвращаемую ячейку
cell.addSubview(avatarView)
cell.addSubview(messageBuble)
return cell
}
After recommended changes with custom CollectionCellView i have this code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) ->
UICollectionViewCell {
var myCell = chatCollectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: indexPath) as! chatCollectionViewCell
var customCell = myCell
if flag[indexPath.row]==0
{
customCell = sendBotMessage(historyString[indexPath.row], path: indexPath, collectionView: collectionView)
}
else
{
customCell = sendUserMessage(historyString[indexPath.row], path: indexPath, collectionView: collectionView)
}
myCell = customCell
currentIndexPath = indexPath
return myCell
}
Function on drawing too have changes to custom cell:
func sendUserMessage(text : String, path : NSIndexPath, collectionView : UICollectionView) -> chatCollectionViewCell {
let userMessage = text
let textSize = getTextFrameSize(userMessage) //высчитали необходимые размеры лейбла
let frameForMessage = getFrameforView(textSize) //высчиитали необходимые размеры всей вьюшки
let messageBuble = Chat_ViewInCell(frame: frameForMessage, textSize: textSize, text: userMessage)
messageBuble.backgroundColor = UIColor.clearColor()
//создаем аватар
let avatarImage = UIImage(named: "\(userAvatar+1).png")
let avatarView = UIImageView(image: avatarImage)
avatarView.contentMode = UIViewContentMode.ScaleAspectFit
//считаем отступ до правого края, позицию аватара
let totalX = messageBuble.frame.width + 340
let constraint = 1750 - totalX
messageBuble.frame.origin = CGPointMake(constraint, 0)
avatarView.frame = CGRectMake(messageBuble.frame.maxX + 10, 0, 170, 170)
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: path) as! chatCollectionViewCell
//добавляем, счастье, радуемся
cell.addSubview(messageBuble)
cell.addSubview(avatarView)
return cell
}
func sendBotMessage(text : String, path : NSIndexPath, collectionView : UICollectionView) -> chatCollectionViewCell {
let userMessage = text
let textSize = getTextFrameSize(userMessage) //высчитали необходимые размеры лейбла
let frameForMessage = getFrameforView(textSize) //высчиитали необходимые размеры всей вьюшки
//создали всю вьюшку
let messageBuble = bot_ViewInCell(frame: frameForMessage, textSize: textSize, text: userMessage)
messageBuble.backgroundColor = UIColor.clearColor()
//создаем аватар и считаем его позицию
let avatarImage = UIImage(named: partner_image)
let avatarView = UIImageView(image: avatarImage)
avatarView.contentMode = UIViewContentMode.ScaleAspectFit
avatarView.frame = CGRectMake(0, 0, 170, 170)
let constraint = avatarView.frame.maxX + 10
messageBuble.frame.origin = CGPointMake(constraint, 0)
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatCellIdentifier, forIndexPath: path) as! chatCollectionViewCell
//добавляем в возвращаемую ячейку
cell.addSubview(avatarView)
cell.addSubview(messageBuble)
return cell
}
But problem no fixes... What i makes wrong with custom CollectionViewCell? I must to do smth another?
The problem is fixed! I don't know about prepareForReuse() method. So simple, in custom cell class defeniton i must override it method, and call for subviews clearsContextBeforeDrawing and removeFromSuperview. Code here:
class chatCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var view: Chat_ViewInCell!
override func prepareForReuse() {
super.prepareForReuse()
for currView in self.subviews
{
currView.clearsContextBeforeDrawing = true
currView.removeFromSuperview()
}
}
All worked, without incorrect redrawing.

Resources