How to set frame of elements inside CollectionViewCell? - ios

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

Related

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 do I add subviews to a custom UICollectionViewCell

I have a custom UICollectionViewCell class where I want to add subviews.
My cell class: The SetUpView() method will add all the subvies I need.
import Foundation
import UIKit
class RecipeCell: UICollectionViewCell {
var RecipeImg: UIImage!
var StarRatingImg: UIImage!
var RecipeTitleText = ""
var RecipeTextDescription = ""
var View: UIView!
var ImageContainer: UIImageView!
var FavIcon: UIImageView!
var StarRatingContainer: UIImageView!
var KCAL: UILabel!
var RecipeTitle: UITextView!
var RecipeText: UITextView!
func SetUpView()
{
//DropDown!.backgroundColor = UIColor.blueColor()
self.translatesAutoresizingMaskIntoConstraints = false
//View for recipe
View = UIView(frame: CGRectMake(0, 0, self.frame.width, self.frame.height))
View.backgroundColor = UIColor.whiteColor()
//Recipe image
ImageContainer = UIImageView(frame: CGRectMake(0, 0, View.frame.width, View.frame.height/2))
ImageContainer.image = RecipeImg
ImageContainer.contentMode = .ScaleToFill
//Recipe favorit icon
FavIcon = UIImageView(frame: CGRectMake(ImageContainer.frame.width - 35, 5, 30, 30))
FavIcon.image = UIImage(named: "LikeHeart")
//Star rating image
StarRatingContainer = UIImageView(frame: CGRectMake(10, ImageContainer.frame.height + 5, ImageContainer.frame.width - 20, (View.frame.height/2) * (1/5)))
StarRatingContainer.image = StarRatingImg
StarRatingContainer.contentMode = .ScaleAspectFit
//RecipeTitle container
RecipeTitle = UITextView(frame: CGRectMake(10, StarRatingContainer.frame.height + ImageContainer.frame.height + 10, View.frame.width - 20, 30))
RecipeTitle.font = UIFont(name: "OpenSans-Semibold", size: 12)
//RecipeTitle.backgroundColor = UIColor.redColor()
RecipeTitle.editable = false
RecipeTitle.text = RecipeTitleText
RecipeTitle.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)
//RecipeText container
RecipeText = UITextView(frame: CGRectMake(10, StarRatingContainer.frame.height + ImageContainer.frame.height + RecipeTitle.frame.height + 15, View.frame.width - 20, 50))
RecipeText.font = UIFont(name: "OpenSans", size: 12)
//RecipeText.backgroundColor = UIColor.grayColor()
RecipeText.editable = false
RecipeText.text = RecipeTextDescription
RecipeText.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0)
//KCAL label
KCAL = UILabel(frame: CGRectMake(15, StarRatingContainer.frame.height + ImageContainer.frame.height + RecipeTitle.frame.height + RecipeText.frame.height + 20, 200, 20))
KCAL.text = "420 KCAL. PER. PORTION"
KCAL.font = UIFont(name: "OpenSans-Bold", size: 10)
KCAL.textColor = UIColor(CGColor: "#dc994a".CGColor)
//Adding the views
self.addSubview(View)
View.addSubview(ImageContainer)
View.addSubview(KCAL)
View.addSubview(StarRatingContainer)
View.addSubview(RecipeTitle)
View.addSubview(RecipeText)
ImageContainer.addSubview(FavIcon)
View.bringSubviewToFront(ImageContainer)
}
}
I have a UICollectionView which uses the custom cell class.
I create my UICollectionView in viewDidLoad()
// Create Collection view
layout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
layout.itemSize = CGSize(width: screenWidth/MenuViewConst - 1, height: screenWidth - 1)
layout.minimumInteritemSpacing = 1
layout.minimumLineSpacing = 1
collectionView = UICollectionView(frame: CGRect(x: 0, y: 105, width: self.view.frame.width, height: self.view.frame.height - 150), collectionViewLayout: layout)
collectionView?.tag = 5
collectionView!.dataSource = self
collectionView!.delegate = self
collectionView!.registerClass(RecipeCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
collectionView!.backgroundColor = UIColor.lightGrayColor()
collectionView!.contentInset.top = 0
In cellForItemAtIndexPath delegate I set up the UICollectionView to use my custom cell class. But I can't call the SetUpView() method from my custom cell class here, because that will just keep adding subviews on subviews. I can't figure out how to add the subviews to the UICollectionViewCell before entering the delegate. Hope you guys can help - Thank you
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! RecipeCell
let recipe = self.RecipeArr[indexPath.row]
cell.backgroundColor = UIColor.grayColor()
cell.layer.borderColor = UIColor.whiteColor().CGColor
cell.layer.borderWidth = 0.5
cell.RecipeImg = UIImage(named: "Burger")
cell.StarRatingImg = UIImage(named: "StarRating")
cell.RecipeTitleText = recipe["name"].string!
cell.RecipeTextDescription = recipe["instruction"].string!
//BAD IDEA!
//cell.SetUpView()
print("new cell")
return cell
}
You need to use init(frame: CGRect) inherited function in the UICollectionViewCell .
class RecipeCell: UICollectionViewCell {
var imageView : UIImageView?
override init(frame: CGRect) {
super.init(frame: frame)
//initialize all your subviews.
imageView = UIImageView()
}
}
also don't forget to register your custom class in the viewDidLoad function
collectionView!.registerClass(RecipeCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
and your collectionview delegate would be like this
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as! RecipeCell
cell.imageView.image = UIImage(named:"yourImage.png")
}

UITableViewCell redrawing on scroll

I have a UITableView that contains cells with a slider and two labels, each time a slider goes out of view it appears to be drawn again on top of the current content.
Here is a gif explaining what I mean.
http://i.imgur.com/4dYtyJy.gifv
And here is the relevant code.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellIdentifier: String = "\(indexPath.row) - \(indexPath.section)"
var cell: UITableViewCell! = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: CellIdentifier)
}
let label = UILabel(frame: CGRect(x: 16.0, y: 16.0, width: 300, height: 30.0))
let percentageLabel = UILabel(frame: CGRect(x: 16.0, y: 0, width: 200.0, height: 30.0))
let slider = CustomUISlider(frame: CGRect(x: 16.0, y: 55.0, width: 300.0, height: 20.0))
slider.maximumTrackTintColor = Global().turqTint
slider.minimumTrackTintColor = Global().blueTint
slider.minimumValue = 0.0
slider.maximumValue = 1.0
slider.value = 0.0
slider.tag = indexPath.row
slider.setThumbImage(UIImage(named: "sliderThumbImage"), forState: .Normal)
slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: .ValueChanged)
label.text = Array(selectedTypes)[indexPath.row].1
percentageLabel.text = "\(slider.value)"
percentageLabel.tag = indexPath.row
cell.tintColor = Global().tintColor
cell.addSubview(label)
cell.addSubview(slider)
cell.addSubview(percentageLabel)
return cell
}
I have had a similar problem. As Horst said in the comments, putting that snippet inside the block will do the trick:
if (cell == nil)
{
// Code that draws frames
}
If you insist to go with your way, you would like to have something more like
(Note: "\(indexPath.row) - \(indexPath.section)") this will create different CellIDs for every cell. What you would like to have is some common CellID to be able to benefit from the reuse logic of the TableView:
//Global constants for the View tags
let textLabelTag = 1
let percentageLabelTag = 2
let sliderTag = 3
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellIdentifier: String = "SomeUniqueID"
var cell: UITableViewCell! = self.tableView.dequeueReusableCellWithIdentifier(CellIdentifier)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: CellIdentifier)
self.createUIforCell(cell);
}
self.configureCell(cell, indexPath: indexPath)
return cell
}
Create the UI components for the cell and add them as subviews. This method will be called only once if the cell doesn't exist:
func createUIforCell(cell: UITableViewCell) {
let textLabel = UILabel(frame: CGRect(x: 16.0, y: 16.0, width: 300, height: 30.0))
textLabel.tag = textLabelTag
cell.addSubview(textLabel)
let percentageLabel = UILabel(frame: CGRect(x: 16.0, y: 0, width: 200.0, height: 30.0))
percentageLabel.tag = percentageLabelTag
cell.addSubview(percentageLabel)
let slider = CustomUISlider(frame: CGRect(x: 16.0, y: 55.0, width: 300.0, height: 20.0))
slider.tag = sliderTag
slider.maximumTrackTintColor = Global().turqTint
slider.minimumTrackTintColor = Global().blueTint
slider.minimumValue = 0.0
slider.maximumValue = 1.0
slider.setThumbImage(UIImage(named: "sliderThumbImage"), forState: .Normal)
slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: .ValueChanged)
cell.addSubview(slider)
}
Update the UI with the correct data:
func configureCell(cell: UITableViewCell, indexPath: NSIndexPath) {
let textLabel: UILabel = cell.viewWithTag(textLabelTag) as! UILabel
textLabel.text = Array(selectedTypes)[indexPath.row].1
let slider: CustomUISlider = cell.viewWithTag(sliderTag) as! CustomUISlider
slider.value = 0.0
let percentageLabel: UILabel = cell.viewWithTag(percentageLabelTag) as! UILabel
percentageLabel.text = "\(slider.value)"
}
Note: It'll be cleaner if you've your own UITableViewCell subclass where the UI to be created (either in the code or in .xib)
You should subclass UITableViewCell and override prepeareForReuse method. With it you can set your cell to default mode.
-(void)prepareForReuse {
[super prepareForReuse];
//Reset your cell here to default state.
}

Create Custom Dynamic Prototype Cells programmatically

I am having an issue trying to create Dynamic Prototype Cells programmatically. This is my first time trying this approach. I have always created them through storyboard.
I have my ViewController.swift file which contains the following
var noteListTableView: UITableView = UITableView()
noteListTableView.frame.origin.x = 0.0
noteListTableView.frame.origin.y = kNAV_BAR_HEIGHT
noteListTableView.frame.size.width = kDEVICE_WIDTH
noteListTableView.frame.size.height = kDEVICE_HEIGHT - kNAV_BAR_HEIGHT
noteListTableView.dataSource = self
noteListTableView.delegate = self
self.view.addSubview(noteListTableView)
Also in the file, I have included the appropriate TableView delegate and Data source functions
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return GlobalDataController.notesDB.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var aNote: NoteItem = GlobalDataController.notesDB[indexPath.row] as NoteItem
if var cell: NoteListTVCell = noteListTableView.dequeueReusableCellWithIdentifier(kReuseCellNoteList) as? NoteListTVCell {
cell.noteTitle.text = "Title"
cell.noteContentSummary.text = "Content Summary"
cell.noteDate.text = "May 20"
return cell
}
else{
var cell: NoteListTVCell = NoteListTVCell(style: UITableViewCellStyle.Default, reuseIdentifier: kReuseCellNoteList)
cell.noteTitle.text = "Title"
cell.noteContentSummary.text = "Content Summary"
cell.noteDate.text = "May 20"
return cell
}
}
(1) The IF-STATEMENT always seems to fail, that is why I added the else statement as per some example I found online for Obj-C.
(2) When the ELSE is triggered, the program always crashes trying to assign the cell.* values, saying it encountered a nil value.
EDIT: NoteListTVCell
class NoteListTVCell: UITableViewCell {
var noteTitle: UILabel!
var noteContentSummary: UILabel!
var noteDate: UILabel!
var cellMargin: CGFloat = kPadding * 3
override func awakeFromNib() {
super.awakeFromNib()
noteTitle = UILabel(frame: CGRect(x: cellMargin, y: kPadding, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 30.0))
noteTitle.backgroundColor = kColorTransparent
noteTitle.font = UIFont(name: kFont02, size: 20.0)
noteTitle.textColor = Scripts.hexColor(0x000000, alpha: 0.8)
noteTitle.text = "Title"
self.addSubview(noteTitle)
/* Note Content Summary
-----------------------------------------------------------------------------------------*/
var noteContentSummaryY: CGFloat = noteTitle.frame.origin.y + noteTitle.frame.size.height
noteContentSummary = UILabel(frame: CGRect(x: cellMargin, y: noteContentSummaryY, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 20.0))
noteContentSummary.backgroundColor = kColorTransparent
noteContentSummary.font = UIFont(name: kFont02, size: 14.0)
noteContentSummary.textColor = Scripts.hexColor(0x000000, alpha: 0.4)
noteContentSummary.text = "This is a summary..."
self.addSubview(noteContentSummary)
/* Note Date
-----------------------------------------------------------------------------------------*/
noteDate = UILabel(frame: CGRect(x: kDEVICE_WIDTH - 100.0 - kPaddingx2, y: kPadding, width: 100.0, height: 20.0))
noteDate.backgroundColor = kColorTransparent
noteDate.font = UIFont(name: kFont02, size: 10.0)
noteDate.textColor = Scripts.hexColor(kColorThemeBlue, alpha: 1.0)
noteDate.textAlignment = NSTextAlignment.Right
noteDate.text = "May 8, 2:14 AM"
self.addSubview(noteDate)
}
}
You haven't override the init method in your custom cell, but anyway it will call super init method, if you don't provide. Put your cell initialisation code in init method instead of awakeFromNib method.
Try this below.
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//Do your cell set up
noteTitle = UILabel(frame: CGRect(x: cellMargin, y: kPadding, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 30.0))
noteTitle.backgroundColor = kColorTransparent
noteTitle.font = UIFont(name: kFont02, size: 20.0)
noteTitle.textColor = Scripts.hexColor(0x000000, alpha: 0.8)
noteTitle.text = "Title"
self.addSubview(noteTitle)
/* Note Content Summary
-----------------------------------------------------------------------------------------*/
var noteContentSummaryY: CGFloat = noteTitle.frame.origin.y + noteTitle.frame.size.height
noteContentSummary = UILabel(frame: CGRect(x: cellMargin, y: noteContentSummaryY, width: kDEVICE_WIDTH - cellMargin - kPadding, height: 20.0))
noteContentSummary.backgroundColor = kColorTransparent
noteContentSummary.font = UIFont(name: kFont02, size: 14.0)
noteContentSummary.textColor = Scripts.hexColor(0x000000, alpha: 0.4)
noteContentSummary.text = "This is a summary..."
self.addSubview(noteContentSummary)
/* Note Date
-----------------------------------------------------------------------------------------*/
noteDate = UILabel(frame: CGRect(x: kDEVICE_WIDTH - 100.0 - kPaddingx2, y: kPadding, width: 100.0, height: 20.0))
noteDate.backgroundColor = kColorTransparent
noteDate.font = UIFont(name: kFont02, size: 10.0)
noteDate.textColor = Scripts.hexColor(kColorThemeBlue, alpha: 1.0)
noteDate.textAlignment = NSTextAlignment.Right
noteDate.text = "May 8, 2:14 AM"
self.addSubview(noteDate)
}
Do this in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
noteListTableView = UITableView(frame: self.view.frame, style: UITableViewStyle.Plain)
noteListTableView.dataSource = self
noteListTableView.delegate = self
self.view.addSubview(noteListTableView)
noteListTableView.registerClass(NoteListTVCellTableViewCell.self, forCellReuseIdentifier: kReuseCellNoteList)
// Do any additional setup after loading the view, typically from a nib.
}
You need to register your custom tableViewCell class in viewDidLoad:
notelistTableView.registerClass(NoteListTVCell.self, forCellReuseIdentifier: kReuseCellNoteList)
Documentation
When designing the prototype in InterfaceBuilder this is done automatically. It is required when you design your cell in code.

Multiple UICollectionView layers on same cells

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
}

Resources