Multiple UICollectionView layers on same cells - ios

This might be a compound question, so please bear with me.
Upon finishing loading objects from Parse and populating the CollectionViewCells with them, it shows a strange bouncing animation even if I explicitly set self.collectionView?.bounces = false. Moreover, the labels are clearly drawing over each other and you can see a picture bouncing under another.
Here are the bugs I'm seeing:
https://youtu.be/q306SGM_tLE and https://youtu.be/gK9HN877nRo
This is how I handle the cells:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("itemCell", forIndexPath: indexPath) as UICollectionViewCell
let nameLabelFont = UIFont(name: "Lato-Regular", size: 13)
let priceLabelFont = UIFont(name: "Lato-Regular", size: 10)
var priceLabel = UILabel(frame: CGRectMake(0, 0, 50, 40))
var name = UILabel(frame: CGRectMake(0, 180, self.view.frame.size.width/2-5, 20))
var unitLabel = UILabel(frame: CGRectMake(0, 200, self.view.frame.size.width/2-5, 20))
var addToCartButton = UIButton(frame: CGRectMake(0, 220, 100, 30))
if self.productImageArray.count != 0 {
var image = self.productImageArray.objectAtIndex(indexPath.row) as UIImage
var imageView = UIImageView(image: image)
imageView.frame.size = CGSize(width: 187.5, height: 180)
name.attributedText = NSAttributedString(
string: self.productArray.objectAtIndex(indexPath.row).valueForKey("name") as NSString,
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.blackColor()])
var price:Float = self.productArray.objectAtIndex(indexPath.row).valueForKey("price_tipsy") as Float
priceLabel.backgroundColor = UIColor.redColor()
priceLabel.attributedText = NSAttributedString(
string: "$\(price)",
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.whiteColor()])
unitLabel.attributedText = NSAttributedString(
string: self.productArray.objectAtIndex(indexPath.row).valueForKey("unit") as NSString,
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.blackColor()])
addToCartButton.setAttributedTitle(NSAttributedString(
string: "ADD TO CART",
attributes: [NSFontAttributeName : priceLabelFont!, NSForegroundColorAttributeName : UIColor.redColor()]),
forState: UIControlState.Normal)
addToCartButton.backgroundColor = UIColor.whiteColor()
addToCartButton.layer.borderColor = UIColor.redColor().CGColor
addToCartButton.layer.borderWidth = 1
addToCartButton.layer.cornerRadius = 5
cell.addSubview(imageView)
cell.addSubview(name)
cell.addSubview(priceLabel)
cell.addSubview(unitLabel)
cell.addSubview(addToCartButton)
} else {
cell.backgroundColor = UIColor.whiteColor()
}
return cell
}
EDIT
This is my UI
and its Debug View Hierarchy
after a few times of pull to refresh, Debug View Hierarchy shows multiple layers on the same cell, number of layers corresponding to number of refreshes.
EDIT 2
Here is my custom cell class:
override init(frame: CGRect) {
super.init(frame: frame)
}
func setup(frameWidth:CGFloat, image: UIImage, name: NSString, price:Float, unit:NSString) {
let nameLabelFont = UIFont(name: "Lato-Regular", size: 13)
let priceLabelFont = UIFont(name: "Lato-Regular", size: 10)
var priceLabel = UILabel(frame: CGRectMake(0, 0, 50, 40))
var nameLabel = UILabel()
var unitLabel = UILabel()
var addToCartButton = UIButton(frame: CGRectMake(0, 220, 100, 40))
nameLabel = UILabel(frame: CGRectMake(0, 180, frameWidth/2-5, 20))
unitLabel = UILabel(frame: CGRectMake(0, 200, frameWidth/2-5, 20))
nameLabel.backgroundColor = UIColor.whiteColor()
unitLabel.backgroundColor = UIColor.whiteColor()
var imageView = UIImageView(image: image)
imageView.frame.size = CGSize(width: frameWidth/2-5, height: 180)
nameLabel.attributedText = NSAttributedString(
string: name,
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.blackColor()])
priceLabel.backgroundColor = UIColor.redColor()
priceLabel.attributedText = NSAttributedString(
string: "$\(price)",
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.whiteColor()])
unitLabel.attributedText = NSAttributedString(
string: unit,
attributes: [NSFontAttributeName : nameLabelFont!, NSForegroundColorAttributeName : UIColor.blackColor()])
addToCartButton.setAttributedTitle(NSAttributedString(
string: "ADD TO CART",
attributes: [NSFontAttributeName : priceLabelFont!, NSForegroundColorAttributeName : UIColor.redColor()]),
forState: UIControlState.Normal)
addToCartButton.backgroundColor = UIColor.whiteColor()
addToCartButton.layer.borderColor = UIColor.redColor().CGColor
addToCartButton.layer.borderWidth = 1
addToCartButton.layer.cornerRadius = 5
self.contentView.addSubview(imageView)
self.contentView.addSubview(nameLabel)
self.contentView.addSubview(priceLabel)
self.contentView.addSubview(unitLabel)
self.contentView.addSubview(addToCartButton)
}
And in terms of UICollectView class, self.collectionView?.reloadData() is called when RefreshController is pulled, and here:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("itemCell", forIndexPath: indexPath) as ShopCell
cell.setup(self.view.frame.width, image: UIImage(), name: "AAA", price: 20.00, unit: "aaa")
cell.contentView.backgroundColor = UIColor.orangeColor()
return cell
}

Related

How to check current font size of UILabel?

I have 3 UILabels and I want to set same (the smallest one from all of 3 possibilities) font for all of them. What is the problem? I don't know how to check the current font - each of UILabels use Autoshrink with minimal font scale and lines amount equaled to 0. The text of UILabels is set in ViewDidLoad() method (there are many combinations of possible label texts).
I tried to get the current font size with UILabel.font.pointSize property (called in viewDidAppear() method) and than compare all of them. The problem is that that UILabel.font.pointSize returns not current value of UILabel text font size (after Autoshrink has been done) but the value that is set in storyboard.
I'm totally out of ideas so thanks for the help!
Greetings, John
use this extention
extension String {
func height(withConstrainedWidth width: CGFloat, font: UIFont) -> CGFloat {
let constraintRect = CGSize(width: width, height: .greatestFiniteMagnitude)
let boundingBox = self.boundingRect(with: constraintRect, options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
return ceil(boundingBox.height)
}
}
get height
height = strDesc.height(withConstrainedWidth: UIScreen.main.bounds.size.width - 160, font: UIFont.systemFont(ofSize: 14.0))
This is one way to get the current size of the UILabel pointsize although I know of more ways if this does not work. This is the cleanest and fastest. See example and extension included.
import UIKit
class ViewController: UIViewController {
lazy var label1 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: 80, width: self.view.bounds.width - 40, height: 40))
lbl.text = "This is some large text to make it fit to size with a big font size"
lbl.font = UIFont.systemFont(ofSize: 50, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
lazy var label2 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: label1.frame.maxY + 5, width: self.view.bounds.width - 40, height: 40))
lbl.text = "This is one line"
lbl.font = UIFont.systemFont(ofSize: 20, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
lazy var label3 : UILabel = {
let lbl = UILabel(frame: CGRect(x: 20, y: label2.frame.maxY + 10, width: self.view.bounds.width - 40, height: 80))
lbl.text = "This is some large text to make it fit to size with a big font size"
lbl.font = UIFont.systemFont(ofSize: 100, weight: .bold)
lbl.textColor = .black
lbl.minimumScaleFactor = 0.01
lbl.adjustsFontSizeToFitWidth = true
lbl.numberOfLines = 0
return lbl
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.view.addSubview(label1)
self.view.addSubview(label2)
self.view.addSubview(label3)
var minSize : CGFloat = .greatestFiniteMagnitude
for sub in self.view.subviews{
if let lbl = sub as? UILabel{
//get the size
let font = lbl.adjustedFont()
print("the size is \(font.pointSize)")
minSize = min(font.pointSize,minSize)
}
}
print("the minimum for all fonts is \(minSize)")
print("i am going to delay for 3 seconds and then reset all the labels to the minimum size :)")
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3.0) {
for sub in self.view.subviews{
if let lbl = sub as? UILabel{
lbl.font = lbl.font.withSize(minSize)
}
}
}
}
}
extension UILabel{
func adjustedFont()->UIFont {
guard let txt = text else {
return self.font
}
let attributes: [NSAttributedString.Key: Any] = [.font: self.font]
let attributedString = NSAttributedString(string: txt, attributes: attributes)
let drawingContext = NSStringDrawingContext()
drawingContext.minimumScaleFactor = self.minimumScaleFactor
attributedString.boundingRect(with: bounds.size,
options: [.usesLineFragmentOrigin,.usesFontLeading],
context: drawingContext)
let fontSize = font.pointSize * drawingContext.actualScaleFactor
return font.withSize(CGFloat(floor(Double(fontSize))))
}
}
Example in Action
What I've found is that inside viewDidLoad() your constraints are not fully defined yet. You can try to do these calculations in another method for example viewWillAppear() or any other that suits you and is executed after viewDidLoad().

Strikethrough UITableView cell text after cell containing String

I'd like to strikethrough all cell text in UITableView after a specific line of text.
Example (after "+")
I think I'm close, but the strikethrough isn't applied in the Simulator. (build is successful)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "Cell")
if indexPath.row > dailyTasks.index(of: "+")! {
let attributeString: NSMutableAttributedString = NSMutableAttributedString(string: dailyTasks[indexPath.row])
attributeString.addAttribute(NSAttributedStringKey.strikethroughStyle, value: 1, range: NSMakeRange(0, attributeString.length))
cell.textLabel?.attributedText = attributeString
} else {
cell.textLabel?.text = dailyTasks[indexPath.row]
}
cell.textLabel?.font = UIFont(name: "GillSans-Light", size: 17)
cell.indentationLevel = 1
cell.textLabel?.addCharactersSpacing(1.2)
cell.backgroundColor = UIColor(red:0.99, green:0.97, blue:0.91, alpha:1.0)
cell.selectionStyle = UITableViewCellSelectionStyle.none
return cell
}
Don't set the font on the label if you are using an attributed string; instead set the font as an attribute. Here is a playground that shows how to do it:
import UIKit
import PlaygroundSupport
let label = UILabel()
let text = "sample text"
let view = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
let attributes: [NSAttributedStringKey: Any] =
[NSAttributedStringKey.font: UIFont(name: "GillSans-Light", size: 17)!,
NSAttributedStringKey.foregroundColor : UIColor.white,
NSAttributedStringKey.strikethroughStyle: 1]
label.attributedText = NSAttributedString(string: text, attributes: attributes)
view.addSubview(label)
label.sizeToFit()
PlaygroundPage.current.liveView = view

how to change color of the part of header title in tableView in swift 3?

I have read similar questions But I didn't got the answer :
I have Table View With Headers and the first one has title and a number I want to change the color of that number in the header in table view
here is my codes :
var headerList = ["Account" , "Help" , "" ]
override func viewDidLoad() {
super.viewDidLoad()
self.headerList[0] = "Account \(userAccountMoney)"
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
label.textColor = .lightGray
}
as you See in my codes the header Titles Are Gray But I want in the first header Title the Account word Still be Gray But the userAccountMoney be the Green the problem is that because userAccountMoney is another variable I couldn't use similar questions
If you want to change the color of a part of a string you need to use NS(Mutable)AttributedString and add the color attribute only to the specific range:
if section == 0 {
let sectionTitle = self.headerList[0]
let attributedString = NSMutableAttributedString(string: sectionTitle)
if sectionTitle.characters.count > 8 {
attributedString.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSRange(location: 8, length: sectionTitle.characters.count - 8))
}
label.attributedText = attributedString
} else {
label.text = self.headerList[section]
}
The index 8 is the hard-coded index after "Account "
However in your case I'd recommend to create headerList as constant
let headerList = ["" , "Help" , "" ]
then delete the code in viewDidLoad and use this code to create the account amount dynamically
if section == 0 {
let attributedString = NSMutableAttributedString(string: "Account ")
attributedString.append(NSAttributedString(string: "\(userAccountMoney)", attributes: [NSForegroundColorAttributeName : UIColor.red]))
label.attributedText = attributedString
} else {
label.text = self.headerList[section]
}
Using NSAttributedString you can create two multiple colour text, even you can change the font. Here is the snippet:
let titleAtt = NSAttributedString(string: "Hello", attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!, NSForegroundColorAttributeName: UIColor.blue])
let numberAtt = NSAttributedString(string: "123", attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 18.0)!, NSForegroundColorAttributeName: UIColor.red])
let combinationAtt = NSMutableAttributedString()
combinationAtt.append(titleAtt)
combinationAtt.append(numberAtt)
label.attributedText = combinationAtt
You can achieve it by writing like below code:
I have created one common function to reuse it in every controller.
//MARK:- Set title with two different color
func setTitle(title : String, loc : Int, len : Int) -> NSMutableAttributedString
{
let myMutableString = NSMutableAttributedString(
string: title,
attributes: [:])
myMutableString.addAttribute(
NSForegroundColorAttributeName,
value: UIColor(red: 29/255, green: 140/255, blue: 242/255, alpha: 1.0),
range: NSRange(
location:loc,
length:len))
return myMutableString
}
I am using this fuction like,
For same controller you can write it,
self.lblTitle.attributedText = self.setTitle(title: "My Profile", loc: 3, len: 7)
You can also use this to change color of specific characters. You need to specify lenght of string and starting location of characters.
I might not understand your problem completely but I think you want to set different color for your first tableview header.
You want do this by using If-else statement on section variable.
Like this
func setAttributedString(text string : String, subStringRange range : NSRange, subStringFont font1 : UIFont, mainStringFont font2 : UIFont, subStringColor color1 : UIColor = UIColor.gray, mainStringColor color2 : UIColor = UIColor.green) -> NSAttributedString {
let mainStringAttribute = [ NSFontAttributeName: font2, NSForegroundColorAttributeName : color2] as [String : Any]
let attributedString = NSMutableAttributedString(string: string, attributes: mainStringAttribute)
let subStringAttribute = [ NSFontAttributeName: font1, NSForegroundColorAttributeName : color1] as [String : Any]
attributedString.addAttributes(subStringAttribute, range: range)
return attributedString
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if (section == 0) // this is first header
{
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
let font1 = UIFont.systemFont(ofSize: 14.0)
let font2 = UIFont.systemFont(ofSize: 14.0)
label.attributedText = setAttributedString(text: "", subStringRange: NSRange(location: 0, length: 1), subStringFont: font1, mainStringFont: font2)
}
else /// remaining headers
{
let returnedView = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 25))
returnedView.backgroundColor = UIColor.init(red: 229/255, green: 233/255, blue: 236/255, alpha: 1.0)
let label = UILabel(frame: CGRect(x: -20, y: 7, width: view.frame.size.width, height: 25))
label.text = self.headerList[section]
label.textAlignment = .right
label.textColor = .lightGray
}
}

iOS Swift TableviewCell issue

I have a strange problem with tableView cell.
when I scroll tableView and cell disappear and back again to the cell I understand that tableView add similar cell exactly on cell.
for example look at the picture . 3 exact text add on each other.
cellForRowAtIndexPath function :
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
if indexPath.row == 0 {
let reviewNumber = UILabel()
if (self.book.review_count == 0) {
reviewNumber.text = "\(self.lang.book["no_review"]!)"
}
if (self.book.review_count > 0) {
reviewNumber.text = "\(self.book.review_count!) \(self.lang.general["review"]!)"
}
reviewNumber.textAlignment = .Right
reviewNumber.font = UIFont(name: "Vazir", size: 14)
reviewNumber.numberOfLines = 0
reviewNumber.translatesAutoresizingMaskIntoConstraints = false
reviewNumber.textColor = UIColor.grayColor()
cell.contentView.addSubview(reviewNumber)
let voteIcon = UIImageView()
voteIcon.image = UIImage(named: "vote-icn")
voteIcon.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(voteIcon)
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[v0(24)]-|",options: [],metrics: nil,views: ["v0" : voteIcon]))
let reviewIcon = UIImageView()
reviewIcon.image = UIImage(named: "review-icn")
reviewIcon.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(reviewIcon)
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-[v0(24)]-|",options: [],metrics: nil,views: ["v0" : reviewIcon]))
let voteNumber = UILabel()
voteNumber.text = " ۴.۵ از ۱۶۵۴رأی"
voteNumber.textAlignment = .Left
voteNumber.font = UIFont(name: "Vazir", size: 14)
voteNumber.numberOfLines = 0
voteNumber.translatesAutoresizingMaskIntoConstraints = false
voteNumber.textColor = UIColor.grayColor()
cell.contentView.addSubview(voteNumber)
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-3-[v0]-3-|",options: [],metrics: nil,views: ["v0" : reviewNumber]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-3-[v0]-3-|",options: [],metrics: nil,views: ["v0" : voteNumber]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-35-[v0]-8-[v1(25)]",options: [],metrics: nil,views: ["v0" : voteNumber, "v1" : voteIcon, "v2" : reviewNumber, "v3" : reviewIcon]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[v2]-8-[v3(25)]-35-|",options: [],metrics: nil,views: ["v0" : voteNumber, "v1" : voteIcon, "v2" : reviewNumber, "v3" : reviewIcon]))
}
if indexPath.row == 1 {
let userBookStatusButtn = UIButton(type: .Custom)
userBookStatusButtn.setTitle("خواهم خواند", forState: .Normal)
userBookStatusButtn.alpha = 0.2
userBookStatusButtn.titleLabel?.font = UIFont(name: "Vazir", size: 14)
userBookStatusButtn.setTitleColor(UIColor.whiteColor(), forState: .Normal)
// userBookStatusButtn.setImage(UIImage(named: "vote-icn"), forState: .Normal)
userBookStatusButtn.translatesAutoresizingMaskIntoConstraints = false
userBookStatusButtn.backgroundColor = UIColor(red:0.0/256.0 ,green:150.0/256.0, blue:136.0/256.0 ,alpha:1 )
cell.contentView.addSubview(userBookStatusButtn)
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[v0(48)]-20-|",options: [],metrics: nil,views: ["v0" : userBookStatusButtn]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-35-[v0]-35-|",options: [],metrics: nil,views: ["v0" : userBookStatusButtn]))
}
if indexPath.row == 2 {
let topBorder = UIView()
topBorder.translatesAutoresizingMaskIntoConstraints = false
topBorder.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
cell.contentView.addSubview(topBorder)
let bottomBorder = UIView()
bottomBorder.translatesAutoresizingMaskIntoConstraints = false
bottomBorder.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
cell.contentView.addSubview(bottomBorder)
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.lineSpacing = 5
paragraphStyle.baseWritingDirection = .RightToLeft
guard let descriptionStr = self.book.description else {return cell}
let attrString = NSMutableAttributedString(string: descriptionStr)
attrString.addAttribute(NSParagraphStyleAttributeName, value:paragraphStyle, range:NSMakeRange(0, attrString.length))
let description = UILabel()
description.attributedText = attrString
description.textAlignment = .Justified
description.font = UIFont(name: "Vazir", size: 14)
description.numberOfLines = 0
description.translatesAutoresizingMaskIntoConstraints = false
description.lineBreakMode = NSLineBreakMode.ByWordWrapping
cell.contentView.addSubview(description)
let title = UILabel()
title.text = "\(self.lang.book["summery"]!)"
title.alpha = 0.2
title.textAlignment = .Center
title.font = UIFont(name: "Vazir-Bold", size: 16)
title.translatesAutoresizingMaskIntoConstraints = false
cell.contentView.addSubview(title)
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-[v0]-|",options: [.AlignAllCenterX],metrics: nil,views: ["v0" : title]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[v0]-20-|",options: [],metrics: nil,views: ["v0" : description]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-8-[v1]-44-[v0]",options: [],metrics: nil,views: ["v0" : description,"v1" : title ]))
cell.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[v0]-8-|",options: [],metrics: nil,views: ["v0" : description,"v1" : title ]))
}
cell.textLabel?.text = nil
return cell
}
I get data from son file with Alamofire and reloadData :
func tableRefresh()
{
dispatch_async(dispatch_get_main_queue(), {
self.bookDetailTableView.reloadData()
})
}
what's my problem?
thanks guys.
You made a classical error when using iOS cells.
(I am a teacher, so I see this kind of error frequently... don't worry..)
some Considerations:
1) NEVER add a label to a cell. Doing so, very time a cell is reused, previous label stays here, and a new label is added
2) as label are transparent, you will see all text overlapped..
3) You are leaking memory, as no one will detach/ release labels.
so the way can be:
A)Simple for simple case
use TAGS, as Apple did on old days of cells..
(code i
make some defines:
let TEXT_TAG = 2000
add label if not present, if present get it vi TAG:
let cell = tableView.dequeueReusableCell(withIdentifier: REUSE, for: indexPath )
let text = "my text..."
if let label = cell.viewWithTag(TEXT_TAG) as? UILabel{
label.text = text
}else{
let frame = CGRect(x: 100, y: 20, width: 50, height: 50)
let label = UILabel(frame: frame)
label.text = text
cell.addSubview(label)
}
B) make a custom cell...
class CustomViewCell: UITableViewCell {
var label: UILabel?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let frame = CGRect(x: 100, y: 20, width: 50, height: 50)
let label = UILabel(frame: frame)
self.addSubview(label)
}
in controller simply:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: REUSE,
for: indexPath ) as! CustomViewCell
cell.label = "my text"
I get your problem,you get the cell from tableView reuseable pool.The first problem,if you want change UITableViewCell View,you need to creat a son class of it.I get a function to fix it.
I use Stackoverflow first time,I don't know where can I put my code,so I write it under this sentence.
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
for let item in cell.contentView.subviews {
item.removeFromSuperView();
}
And then using your code,it should help you.

How to set frame of elements inside CollectionViewCell?

I have a custom cell class that looks like this:
class CollectionViewCell: UICollectionViewCell {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
var textLabel: UILabel = UILabel()
var buttonView: UIButton!
var id: String = String()
override init(frame: CGRect) {
super.init(frame: frame)
let textFrame = CGRect(x: buttonView.center.x - self.frame.width/2, y: 90, width: frame.size.width, height: frame.size.height/3)
textLabel = UILabel(frame: textFrame)
textLabel.font = UIFont.systemFontOfSize(UIFont.smallSystemFontSize())
textLabel.textAlignment = .Center
contentView.addSubview(textLabel)
buttonView = UIButton.buttonWithType(UIButtonType.System) as! UIButton
buttonView.frame = CGRect(x: frame.width / 2 - frame.width * 0.4, y: 0 + textLabel.frame.size.height, width: frame.size.width * 0.8, height: frame.size.height * 0.8 )
contentView.addSubview(buttonView)
}
}
and the func where I dequeue cells looks like this:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
switch collectionView{
case collectionViewOne!:
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewDetailCell", forIndexPath: indexPath) as! CollectionViewDetailCell
cell.backgroundColor = UIColor.whiteColor()
cellHeightOne = cell.frame.height
cell.productLabel.text = "\(array[indexPath.row].name)"
cell.textLabel.numberOfLines = 0
let myText = NSString(format: self.array[indexPath.row].description)
let paragraphStyle = NSMutableParagraphStyle() as NSMutableParagraphStyle
paragraphStyle.alignment = NSTextAlignment.Justified
let attributes: NSDictionary = [NSFontAttributeName: UIFont.systemFontOfSize(12), NSBaselineOffsetAttributeName: 0, NSParagraphStyleAttributeName: paragraphStyle, NSForegroundColorAttributeName: UIColor.grayColor()]
let attributedText = NSAttributedString(string: myText as String, attributes: attributes as [NSObject : AnyObject])
cell.textLabel.attributedText = attributedText
cell.textLabel.sizeToFit()
cell.contentView.addSubview(cell.textLabel)
return cell
I want for my labels text height to move the button down, but nothing happens, i also tried to find out the height and to send it to cell something like:
cell.textHeigth = textHeigth, and use textHeigth in
buttonView.frame = CGRect(x: frame.width / 2 - frame.width * 0.4, y: 0 + textHeigth, width: frame.size.width , height: frame.size.height * 0.8)
but then i get the error that some variable is nil, but I tryed printing the variable and before sending it to customClass it is not nil
Implement the below delegate method to set width and height of collection view cell
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
return CGSizeMake(width,height);
}
I managed to put my button under the text with this code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewDetailCell", forIndexPath: indexPath) as! CollectionViewDetailCell
let myText = NSString(format: newString)
let paragraphStyle = NSMutableParagraphStyle() as NSMutableParagraphStyle
paragraphStyle.alignment = NSTextAlignment.Justified
let attributes: NSDictionary = [NSFontAttributeName: UIFont.systemFontOfSize(12), NSBaselineOffsetAttributeName: 0, NSParagraphStyleAttributeName: paragraphStyle, NSForegroundColorAttributeName: UIColor.grayColor()]
let attributedText = NSAttributedString(string: myText as String, attributes: attributes as [NSObject : AnyObject])
cell.textLabel.attributedText = attributedText
cell.textLabel.sizeToFit()
cell.contentView.addSubview(cell.textLabel)
cell.buttonView.frame = CGRect(x: 0, y: 200 + cell.textLabel.frame.size.height, width: 10, height: 10)
return cell
}
You have to do everything in this cellForItemAtIndexPath

Resources