UiView fixed on top of UiTableViewController - ios

I need to put an UIView fixed on top of UITableViewController (like a header). I've tried this:
override func scrollViewDidScroll (scrollView: UIScrollView) {
var fixedFrame: CGRect = self.uiTopView.frame;
fixedFrame.origin.y = scrollView.contentOffset.y;
self.uiTopView.frame = fixedFrame;
}
But it does not work and I don't know why. Someone have any idea?

This can not be done, one way to accomplish this is to add the UITableViewController insideUIContainerView
So the structure will be as follows:
ViewController1 contains aUIContainerView this container view has embedded segue
to your tableViewController.
Then you can add the view to the ViewController1.

Why do you actually use UITableViewController instead of UIViewController with a tableView inside?
Maybe you should add your header view first then add you tableview depending on the header's frame.
for example: `import UIKit
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
var fixedLabel : UILabel!
var tableView : UITableView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.tableView.frame = CGRectMake(0, self.fixedLabel.frame.maxY, self.view.frame.width, self.view.frame.height-70)
self.fixedLabel.frame = CGRectMake(0,0,self.view.bounds.width,70)
}
override func viewDidLoad() {
super.viewDidLoad()
self.fixedLabel = UILabel()
self.fixedLabel.backgroundColor = UIColor.blueColor()
self.fixedLabel.text = "This is a fixedLabel"
self.fixedLabel.textAlignment = .Center
self.tableView = UITableView()
self.tableView.delegate = self
self.tableView.dataSource = self
self.view.addSubview(fixedLabel)
self.view.addSubview(tableView)
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell : UITableViewCell? = tableView.dequeueReusableCellWithIdentifier("cell")
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cell")
}
cell?.textLabel?.text = "Your text"
return cell!
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 3
}
}
`

Related

how to subclass UITableView to use in other viewControllers

I'm looking to create a subclass for a tableview that I would like to use throughout out all my app. My problem is when I set the fields variable the tableview is still empty. I'm assuming that the fields variable is not setting right when it is set in the new ViewController. Thank you for the help in advance.
MySubClass
import UIKit
import LGButton
class RquestTableViewController: UITableViewController {
var fields:[UIView]
override func viewDidLoad() {
super.viewDidLoad()
viewSetup()
}
func viewSetup(){
tableView.register(CustomFormCell.self, forCellReuseIdentifier: labelReuseCellIdentifier)
self.tableView.tableFooterView = UIView.init(frame: CGRect.zero)
}
}
//MARK: Delegate
extension RquestTableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return fields.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: self.labelReuseCellIdentifier, for: indexPath) as! CustomFormCell
let itemView = fields[indexPath.row]
cell.viewPassed = itemView
cell.backgroundColor = .clear
if let _ = itemView as? UILabel {
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0)
return cell
}
if let _ = itemView as? UIButton {
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0)
return cell
}
if let _ = itemView as? LGButton {
cell.separatorInset = UIEdgeInsetsMake(0, cell.bounds.size.width, 0, 0)
return cell
}
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 40.0
}
}
MyNewViewController
class NewRquestViewController: RquestTableViewController {
lazy var password:JVFloatLabeledTextField = {
let v = JVFloatLabeledTextField()
v.placeholder = "Password"
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
fields = [password]
}
}
Have you verified that fields really isn't being set properly? I see no reason why it wouldn't be. But I do see another problem: in addition to overriding numberOfSections(in:) and tableView(_,cellForRowAt:), you have to override tableView(_,numberOfRowsInSection:). What you have now is numberOfSections(in:) returning the number of fields, but tableView(_,cellForRowAt:) is expecting to populate the rows with the fields. That means that tableView(_,cellForRowAt:) will be called only when section is 0, so at most you'd see only one field. Instead, change numberOfSections(in:) to return 1, and implement tableView(_,numberOfRowsInSection:) to return fields.count.

UITableView inside a ViewController with custom cell without storyboard

I'm working with Swift 2.0 and Xcode 7.2.
I want to learn how to make an app without a storyboard (UI with pure programming code). To start off, I am trying to make a simple app, with three labels, inside a custom UITableView cell which will be updated dynamically through the internet.
Here is what I have achieved so far:
Created a new Swift project and deleted the main.storyboard from the project
Added a view controller as the rootViewController in AppDelegate
Included code to create a UITableView inside this view
Here are the other tasks I want to accomplish (all programmatically, without using the attribute inspector):
Insert a UINavigationController into the ViewController
Add a custom cell with three labels
Update the table view with data
If possible, I would want to have the ability to have everything working in landscape mode as well.
Can anyone tell me how to do this?
AppDelegate.swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
window = UIWindow(frame: UIScreen.mainScreen().bounds)
window!.backgroundColor = UIColor.whiteColor()
window!.rootViewController = ViewController()
window!.makeKeyAndVisible()
return true
}
ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView = UITableView(frame: self.view.bounds, style: UITableViewStyle.Plain)
tableView.dataSource = self
tableView.delegate = self
tableView.backgroundColor = UIColor.whiteColor()
tableView.frame = CGRectMake(0 , 0, self.view.bounds.width, self.view.bounds.height)//Optional for table size
self.view.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "myIdentifier")
myCell.textLabel?.text = "\(indexPath.row)"
myCell.detailTextLabel?.text = "Subtitle"
return myCell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I have no idea how to create a custom cell programmatically to which I can add objects.
Help would be appreciated.
Thanks.
If you are not using storyboard, you can define your cell just above the class where your ViewController where your are including your tableView something like myCell which is your custom UITableViewCell as given below.
In this myCell, you can add as many objects as your want and set them up in the setUpCell() block.
The full code is as below, please make sure you call setUpCell() when you use your cell's in cellForRowAtIndexPath.
ViewController.swift
import #UIKit
class myCell: UITableViewCell {
// Define label, textField etc
var aMap: UILabel!
// Setup your objects
func setUpCell() {
aMap = UILabel(frame: CGRectMake(0, 0, 200, 50))
self.contentView.addSubview(aMap)
}
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView = UITableView()
// for ex, lets say, your data array is defined in the variable below
var dataArray = [[String:AnyObject]]() //Array of your data to be displayed
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView = UITableView(frame: self.view.bounds, style: UITableViewStyle.Plain)
tableView.dataSource = self
tableView.delegate = self
tableView.backgroundColor = UIColor.whiteColor()
// register your class with cell identifier
self.tableView.registerClass(myCell.self as AnyClass, forCellReuseIdentifier: "Cell")
self.view.addSubview(tableView)
dataArray = // Something loaded from internet
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return flightDataArr.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// let myCell = tableView.dequeueReusableCellWithIdentifier("myIdentifier", forIndexPath: indexPath)
var cell:myCell? = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? myCell
if cell == nil {
cell = myCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
}
var data = dataArray[indexPath.row]
cell?.setUpCell()
cell!.aMap.text = String(dict["productName"])
return cell!
}
}
See if this works for you. I never used programming to create tableView, so this may not be the optimal way to create your tableView programmatically. I hope someone else may help you with a better answer if possible.
You can create a sub class of UITableViewCell say PackageListTableViewCell.
Declare number of labels in tabelViewCell custom class as per your requirements like below,
var label1 : UILabel?;
override init:reuseIdentifier: in custom cell with additional parameters as below.
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//create labels as per your requirement
self.label1 = //initialise you label
//set frame, or constraint
//set text color, background color etc
//add created labels to cell as below
self.contentView.addSubView(self.label1);
}
your tableView:cellForRowAtIndexPath: will be look like,
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let lable1String = "lbl1"
let lable2String = "lbl2"
let lable3String = "lbl3"
var cell : PackageListTableViewCell! = tableView.dequeueReusableCellWithIdentifier("cellID") as?PackageListTableViewCell
if (cell == nil) {
cell = PackageListTableViewCell.init(style: UITableViewCellStyle.Default,
reuseIdentifier:"cellID");
}
cell.selectionStyle = UITableViewCellSelectionStyle.None;
//set text of your lables as below
cell.label1.text = lable1String;
return cell;
}
You have to register a custom tableviewcell class using method registerClass on tableview.
Use this modified Viewcontroller code:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
tableView = UITableView(frame: self.view.bounds, style: UITableViewStyle.Plain)
tableView.dataSource = self
tableView.delegate = self
tableView.backgroundColor = UIColor.whiteColor()
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myIdentifier")
tableView.frame = CGRectMake(0 , 0, self.view.bounds.width, self.view.bounds.height)//Optional for table size
self.view.addSubview(tableView)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let myCell = tableView.dequeueReusableCellWithIdentifier("myIdentifier", forIndexPath: indexPath)
myCell.textLabel?.text = "\(indexPath.row)"
myCell.detailTextLabel?.text = "Subtitle"
return myCell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

When I swipe a UITableViewCell, the header view moves as well

So, I have a few Swipe actions like delete, block, etc in my UITableView. I wanted to add headers to separate my two sections. So, I added a prototype cell, named it HeaderCell and then went to the view. I added one label, named headerLabe. My problem is that when I swipe for the actions, the header cells were moving as well, which looked bad. I researched, and found a solution to just return the contentView of the cell. However, when I do this, the label has not shown up. I have tried a dozen different solutions, and nothing has worked, so I have turned to SO. Can anyone help me?
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell : CustomHeaderTableViewCell = tableView.dequeueReusableCellWithIdentifier("HeaderCell") as! CustomHeaderTableViewCell
if section == 0 {
headerCell.headerLabel.text = "Thank You's"
} else if section == 1 {
headerCell.headerLabel.text = "Conversations"
}
return headerCell.contentView
}
Thanks so much.
You can use a section Header as #ozgur suggest.If you still want to use a cell.
Refer to this datasource method
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
if indexPath = YourHeaderCellIndexPath{
return false
}
return true
}
check the following methods
In your UIViewController use the following
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 60
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerCell = tableView.dequeueReusableCellWithIdentifier("HeaderCell") as! WishListHeaderCell
headerCell.lblTitle.text = cartsData.stores_Brand_Name
let imgVw = UIImageView()
imgVw.frame = CGRectMake(8, 18, 25, 25)
imgVw.image = UIImage(named: "location.png")
let title = UILabel()
title.frame = CGRectMake(41, 10, headerCell.viwContent.frame.width - 49, 41)
title.text = cartsData.stores_Brand_Name
title.textColor = UIColor.whiteColor()
headerCell.viwContent.addSubview(imgVw)
headerCell.viwContent.addSubview(title)
return headerCell.viwContent
}
In your UITableViewCell use the following
import UIKit
class HeaderCell: UITableViewCell {
#IBOutlet weak var viwContent: UIView!
#IBOutlet weak var imgIcn: UIImageView!
#IBOutlet weak var lblTitle: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
self.viwContent.backgroundColor = UIColor.grayColor()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//UITableViewCell
let headerCell = tableView.dequeueReusableCellWithIdentifier("headerCell") as! SecJobCCHeaderTableViewCell
// Cell Rect
var cellRect : CGRect = headerCell.frame
cellRect.size.width = screenBounds.width
// Header Footer View
let headerFooterView = UITableViewHeaderFooterView(frame : cellRect)
//Adding Gesture
let swipeGestRight = UISwipeGestureRecognizer(target: self, action:#selector(AddSecJobCostCentreViewController.draggedViewRight(_:)))
swipeGestRight.enabled = true
swipeGestRight.direction = UISwipeGestureRecognizerDirection.Right
headerFooterView.addGestureRecognizer(swipeGestRight)
// Update Cell Rect
headerCell.frame = cellRect
// Add Cell As Subview
headerCell.tag = 1000
headerFooterView.addSubview(headerCell)
// Return Header Footer View
return headerFooterView
}
func draggedViewRight(sender:UISwipeGestureRecognizer) {
// Swipe Gesture Action
let currentHeaderView = sender.view?.viewWithTag(1000) as! SecJobCCHeaderTableViewCell
}

Programmatically added UITableView won't populate data

I wish to create UITableView and a custom cell, and add them to my UIViewController.
If I layout UITableView from the storyboard onto my UIViewController, everything works fine with custom cell.
But I realized that animation regarding its height is not very smooth - sometimes the table view disappears
So I decided to create/destroy a UITableView everytime I wish to do some animation, and add it as a subview to my UIViewController.
But the programmatically-added UITableView won't populate data.
What am I doing wrong here?
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var dataArr = [String]() // Holds data for UITableView
var tv: UITableView! // Notice it's not #Outlet
override func viewDidLoad() {
super.viewDidLoad()
dataArr = ["one", "two", "three"]
// Create and add UITableView as drop down
tv = UITableView()
tv.delegate = self
tv.dataSource = self
createTableView()
}
func createTableView() {
let w = UIScreen.mainScreen().bounds.size.width
tv.frame = CGRectMake(0, 50, w, 0)
tv.rowHeight = 25.0
// Register custom cell
var nib = UINib(nibName: "searchCell", bundle: nil)
tv.registerNib(nib, forCellReuseIdentifier: "searchCell")
self.view.addSubview(tv)
UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions.BeginFromCurrentState, animations: {
self.tv.frame.size.height = 100
}, completion: { (didFinish) in
self.tv.reloadData()
})
}
func destroyTableView() {
UIView.animateWithDuration(0.2, animations:
{
// Hide
self.tv.frame.size.height = 0
}, completion: { (didFinish) in
self.tv.removeFromSuperview()
})
}
// MARK: - UITableView
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dataArr.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: SearchCell = self.tv.dequeueReusableCellWithIdentifier("searchCell") as! SearchCell
cell.cellLabel.text = dataArr[indexPath.row]
return cell;
}
}
I think the problem is with this line.
self.tv.frame.size.height = 100
Try setting the whole frame instead of just the height. Pretty sure a UIView's Frame's properties are read only.
See here
If that doesn't work. Maybe try implementing
func tableView(_ tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

UICollectionView cells with Images inside UITableView prototype

UPDATE: I solved my primary issue of correct images not loading until scrolling on the collectionView. I added a collectionView.reloadData() to the tableView:cellForRowAtIndexPath. I also made some changes to pre-load the sequence array, instead of building it while scrolling through the table (tableView:cellForRowAtIndexPath).
Added the updates to GitHub if you are interested.
https://github.com/Druiced/OpenDeck
I will follow-up once I figure out how to prevent the App from crashing when a dynamic value is placed in the return (if i set this to 15, the app will not crash):
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return count(Array(sequenceArray[collectionView.tag])) / 2
}
ORIGINAL POST:
request for some guidance.
This tutorial helped me realize this must have to do with my DataSource/Delegate. The author builds the cell with addSubview instead of taking advantage of the Xcode prototype cell, which seems like a cool thing, so I'm trying to do it.
http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell
Any criticism about my approach or failure to follow best practices is welcome.
Each cell in the table has a UICollectionView. Each cell in the Collection View displays an image in order of the saved "Sequence" string. example: "ADKDQDJDTD" link up to AD.png KD.png QD.png JD.png TD.png
I have two issues I can't seem to get past.
numberOfItemsInSection gets whacky when the number of cards is driven by the array length (return handArray.count / 2). If I place a fixed number the app will work, but not very slick.
When the table first comes up, the correct cards do not display until I scroll up and down the table. It also appears the data for each CollectionView is crossing paths as the wrong cards show up when scrolling up and down rapidly.
I'm almost positive this has to do with how my datasource is setup.
DeckTableViewController.swift
import UIKit
import Parse
var deviceID: String?
var noRefresh: Bool?
var sequenceArray: Array<Character>?
class DeckTableViewController: UITableViewController, UICollectionViewDelegate, UICollectionViewDataSource {
var handArray: Array<Character>!
var timeLineData:NSMutableArray = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
noRefresh = false
deviceId = UIDevice.currentDevice().identifierForVendor.UUIDString
}
override func viewDidAppear(animated: Bool) {
if noRefresh == false {
loadData()
noRefresh = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return timeLineData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell:DeckTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! DeckTableViewCell
let deck:PFObject = timeLineData.objectAtIndex(indexPath.row) as! PFObject
cell.collectionView.dataSource = self
cell.collectionView.delegate = self
let sequenceTemp = deck.objectForKey("Sequence") as! String
handArray = Array(sequenceTemp)
cell.sequenceId.setTitle(deck.objectId, forState: UIControlState.Normal)
cell.cardCountLabel.text = "\((count(sequenceTemp)/2))"
// Date to String Stuff
var dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "(MM-dd) hh:mm:ss"
cell.timeLabel.text = dateFormatter.stringFromDate(deck.updatedAt!)
let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.itemSize = CGSizeMake(99, 140)
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
cell.collectionView.collectionViewLayout = layout
return cell
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return handArray.count / 2
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:TableCollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! TableCollectionViewCell
var bcolor : UIColor = UIColor.orangeColor()
cell.layer.borderColor = bcolor.CGColor
cell.layer.borderWidth = 2
cell.layer.cornerRadius = 3
var firstLetter: Character!
var secondLetter: Character!
//Building card file names from Sequence data
if (indexPath.row * 2) + 1 <= handArray.count {
firstLetter = handArray[indexPath.row * 2]
secondLetter = handArray[indexPath.row * 2 + 1]
let imageNameString = "\(firstLetter)\(secondLetter).png"
let front = UIImage(named: imageNameString)
cell.ImageView.backgroundColor = UIColor.orangeColor()
cell.ImageView.image = front
}
return cell
}
DeckTableViewCell.swift
import UIKit
class DeckTableViewCell: UITableViewCell, UITextViewDelegate {
#IBOutlet var collectionView: UICollectionView!
#IBOutlet var sequenceId: UIButton!
#IBOutlet var timeLabel: UILabel!
#IBOutlet var cardCountLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
TableCollectionViewCell.swift
import UIKit
class TableCollectionViewCell: UICollectionViewCell {
#IBOutlet var ImageView: UIImageView!
}
For this example I set (return handArray.count / 2) to a 10 and loaded 3 sequences.
The number in the top center represents the number of cards for each row.
Notice the CollectionView does not update with the right cards, it's picking up data from the other CollectionViews. IF I add bunch more sequences to this mix, when scrolling up and down, the correct cards WILL populate SOMETIMES, but unpredictable.
Thanks for any suggestions, I'm happy to go back to the drawing board. Cheers
Ok lets think this way, your DeckTableViewController acts as datasource for tableview, and DeckTableViewCell acts as datasource for collection view.
with the above thing in mind we create a sample project
i am not going in depth, i am giving example like the tutorial as u go through
lets create a sample project with single view app and in ViewController
past the below code, i took one array of integers which contains some values as how many cells to be appears in collection view. don't forget add tableview and set its datasource and deleagte.
before we are coding to controller class we need some classes like custom tableview cell and custom collection view cell we create them first
create a new file which is the subclass of UICollectionViewCell and name it as CustomCollectionViewCell and with xib file.
class CustomCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var aLabel: UILabel! //to show the card number
#IBOutlet weak var imageView: UIImageView! //imageview i am setting it's background color
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
}
}
and create a outlets for label and image view as in the above code.
Next, create new file subclass of UITableViewCell and name it as CustomTableViewCell with xib file. open up CustomTableViewCell.xib file and drag and drop the collection view and set it's datasource and delegate to cell not the controller.
and create a outlet for the collection view and name it as foldersCollectionView.
pass the below code
import UIKit
class CustomTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var foldersCollectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
// fatalError("init(coder:) has not been implemented")
super.init(coder: aDecoder)
}
var folderCount:Int?
{
didSet(value)
{
}
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
//configure our collectionview
var aFlowLayout : UICollectionViewFlowLayout = UICollectionViewFlowLayout()
aFlowLayout.scrollDirection = UICollectionViewScrollDirection.Horizontal
aFlowLayout.itemSize = CGSizeMake(60.0, 90.0)
aFlowLayout.minimumLineSpacing = 10.0
aFlowLayout.minimumInteritemSpacing = 0.0
aFlowLayout.sectionInset = UIEdgeInsetsMake(2, 9, 0, 10)
foldersCollectionView.collectionViewLayout = aFlowLayout
foldersCollectionView.registerClass(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "FOLDER_CELL")
var cNib:UINib? = UINib(nibName: "CustomCollectionViewCell", bundle: nil)
foldersCollectionView.registerNib(cNib, forCellWithReuseIdentifier: "FOLDER_CELL")
foldersCollectionView.frame = self.bounds
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
class func CreateCustomCell() -> CustomTableViewCell
{
var nibElements: Array = NSBundle.mainBundle().loadNibNamed("CustomTableViewCell", owner: self, options: nil)
var item: AnyObject?
for item in nibElements
{
if item is UITableViewCell
{
return item as CustomTableViewCell
}
}
return item as CustomTableViewCell
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell :CustomCollectionViewCell? = collectionView.dequeueReusableCellWithReuseIdentifier("FOLDER_CELL", forIndexPath: indexPath) as? CustomCollectionViewCell
//hear u can modify which image to be displayed in the collection view cell
cell?.aLabel.text = "Card:\(indexPath.row)"
return cell!
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return folderCount!
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
}
now we are going the code the ViewController class
now just past the below code
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var cardCountArray:[Int] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
cardCountArray = [5,15,6,12,7,10]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return cardCountArray.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
if(cell == nil)
{
cell = CustomTableViewCell.CreateCustomCell()
}
cell?.folderCount = cardCountArray[indexPath.section]
cell?.foldersCollectionView.reloadData()
cell?.clipsToBounds = true
return cell!;
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat
{
return 100.0
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var headerView:UIView = UIView(frame: CGRectMake(0, 0, tableView.bounds.size.width, 70.0))
var labelTitle:UILabel = UILabel(frame: CGRectMake(0, 0, tableView.bounds.size.width, 35))
var descriptionTitle:UILabel = UILabel(frame: CGRectMake(0, 20,tableView.bounds.size.width , 30))
headerView.addSubview(labelTitle)
headerView.addSubview(descriptionTitle)
labelTitle.text = "TOTAL_CARDS in section:\(section)"
descriptionTitle.text = "This CARD_SECTION contains \(cardCountArray[section]) CARDS"
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50.0
}
}
result will be like below
if any thing missing please let me know
For your comment I have an array, for example, ["2C3C4C5C6C7C", "AD2D3D4D5D", "9H8H7H"]
for this u need to make below modification
//for first row u get like this
//the string for the row is 2C3C4C5C6C7C
//stringForCell = "2C3C4C5C6C7C"
//2C
//3C
//4C
//5C
//6C
//7C
//for other cells u can get like below
//the string for the row is AD2D3D4D5D
//stringForCell = "AD2D3D4D5D"
//AD
//2D
//3D
//4D
//5D
//the string for the row is 9H8H7H
//stringForCell = "9H8H7H"
//9H
//8H
//7H
//in controller controller class define array of string
class ViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
var cardCountArray:[Int] = []
var stringArray : [String] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
stringArray = ["2C3C4C5C6C7C", "AD2D3D4D5D", "9H8H7H"]
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
// return cardCountArray.count
return stringArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
var cell:CustomTableViewCell? = tableView.dequeueReusableCellWithIdentifier("CELL") as? CustomTableViewCell;
if(cell == nil)
{
cell = CustomTableViewCell.CreateCustomCell()
}
//cell?.folderCount = cardCountArray[indexPath.section]
cell?.stringForCell = stringArray[indexPath.section];
cell?.foldersCollectionView.reloadData()
cell?.clipsToBounds = true
return cell!;
}
//in custom tableview cell add a string variable
class CustomTableViewCell: UITableViewCell,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var foldersCollectionView: UICollectionView!
var stringForCell:String = "" //add the string to hold the string
//rest of the code
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
var cell :CustomCollectionViewCell? = collectionView.dequeueReusableCellWithReuseIdentifier("FOLDER_CELL", forIndexPath: indexPath) as? CustomCollectionViewCell
var str:NSString = stringForCell
var length = str.length
var totalLlength:Int = length/2
var indexStart = indexPath.row * (2);
var aRange = NSMakeRange(indexStart, 2)
var cardString:NSString = str.substringWithRange(aRange)
println(cardString)
cell?.aLabel.text = "Card: \(cardString)"
return cell!
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
println("the string for the row is \(stringForCell)")
var str:NSString = stringForCell
var length:Int = str.length
return length / 2
//return folderCount!
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
i written a detailed post about how to add collection view inside custom table view cell hear hope this gives more detailed explanation than this post.

Resources