I have a controller which has a table with four cells. Each of these custom cells contain another table, in which I display row data.
Take a look at the screenshot:
Here is how I init custom cell and pass data to it:
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
let cell = tableView.dequeueReusableCellWithIdentifier("DashCell", forIndexPath: indexPath) as! DashCell
cell.dictionary = dataArray[indexPath.row] as Dictionary!
cell.sectionTitle = sectionTitles[indexPath.row]
cell.titlesArray = columnTitles[indexPath.row]
return cell
}
And here is my custom cell code:
#objc(DashCell) class DashCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableViewInsideCell: UITableView!
var dictionary: Dictionary<String, String>?
var sectionTitle: String?
var titlesArray: Array<String>?
var screenWidth: CGFloat!
var data: Array<String> = []
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
}
required init(coder aDecoder: NSCoder) {
println("Dictionary in cell \(dictionary)")
let firstColumn: String = dictionary!["FirstColumn"]!
let secondColumn: String = dictionary!["SecondColumn"]!
let thirdColumn: String = dictionary!["ThirdColumn"]!
let fourthColumn: String = dictionary!["FourthColumn"]!
let fifthColumn: String = dictionary!["FifthColumn"]!
var sixthColumn: String? = dictionary!["SixthColumn"]!
var sevenColumn: String? = dictionary!["SeventhColumn"]!
data.append(firstColumn)
data.append(secondColumn)
data.append(thirdColumn)
data.append(fourthColumn)
data.append(fifthColumn)
if sixthColumn != nil {
data.append(sixthColumn!)
}
if sevenColumn != nil {
data.append(sevenColumn!)
}
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
screenWidth = UIScreen.mainScreen().bounds.size.width
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func addTitleLabel(text: String, withOffset offset: CGFloat) -> UILabel {
var label: UILabel = UILabel(frame: CGRectMake(15 + offset, 23, screenWidth / CGFloat(titlesArray!.count), 17))
label.font = UIFont.boldSystemFontOfSize(10.0)
label.numberOfLines = 1
label.backgroundColor = UIColor.clearColor()
label.textAlignment = NSTextAlignment.Left
label.text = text
return label
}
func addRowLabel(text: String, withOffset offset: CGFloat) -> UILabel {
var label: UILabel = UILabel(frame: CGRectMake(15 + offset, 2, screenWidth / CGFloat(data.count) - 10, 17))
label.font = UIFont.systemFontOfSize(9.0)
label.numberOfLines = 1
label.backgroundColor = UIColor.clearColor()
label.textAlignment = NSTextAlignment.Left
label.text = text
return label
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 8
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var headerView: UIView = UIView()
var sectionTitleLabel: UILabel = UILabel(frame: CGRectMake(15, 3, screenWidth, 20))
sectionTitleLabel.font = UIFont.systemFontOfSize(14.0)
sectionTitleLabel.numberOfLines = 1
sectionTitleLabel.backgroundColor = UIColor.clearColor()
sectionTitleLabel.textAlignment = NSTextAlignment.Left
var lableText: String = sectionTitle!
sectionTitleLabel.text = lableText.uppercaseString
sectionTitleLabel.textColor = UIColor(red: 110 / 255.0, green: 110 / 255.0, blue: 115 / 255.0, alpha: 1.0)
sectionTitleLabel.text!.uppercaseString
headerView.addSubview(sectionTitleLabel)
var offset: CGFloat = screenWidth / CGFloat(titlesArray!.count)
for var j: Int = 0; j < titlesArray!.count; j++ {
let headerLabel: UILabel = self.addTitleLabel(titlesArray![j], withOffset: offset * CGFloat(j))
headerView.addSubview(headerLabel)
}
return headerView
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 40
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 22
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var CellIdentifier: String = "Cell"
var cell = tableView.dequeueReusableCellWithIdentifier(CellIdentifier) as? UITableViewCell
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: CellIdentifier)
}
var offset: CGFloat = screenWidth / CGFloat(data.count)
for var j = 0; j < data.count; j++ {
let string: String = data[j] as String
var label: UILabel = self.addRowLabel(string, withOffset: offset * CGFloat(j))
cell!.contentView.addSubview(label)
}
return cell!
}
The problem is that dictionary variable always comes nil, although sectionTitle and titlesArray are filled with data. Why is it so?
[UPDATE] The dictionary is set like this in parent view controller in viewDidLoad:
var one: Dictionary<String, String> = ["FirstColumn" : "R-L-1776-07-2015-1", "SecondColumn" : "Aaron Bloch", "ThirdColumn" : "$5,000.00", "FourthColumn" : "153 E 32 STREET", "FifthColumn" : "Open"]
var two: Dictionary<String, String> = ["FirstColumn" : "R-L-1776-07-2015-4", "SecondColumn" : "Test User", "ThirdColumn" : "$500.00", "FourthColumn" : "635 W 42nd St", "FifthColumn" : "Yes"]
var three: Dictionary<String, String> = ["FirstColumn" : "Bruno", "SecondColumn" : "Ricciotti", "ThirdColumn" : "bruno#bondnewyork.com", "FourthColumn" : "917-699-7151", "FifthColumn" : "Some text"]
var four: Dictionary<String, String> = ["FirstColumn" : "#448438", "SecondColumn" : "Resid. Rent", "ThirdColumn" : "$345.00", "FourthColumn" : "Studio", "FifthColumn" : "1", "SixthColumn" : "Hamilton Heights", "SeventhColumn" : "Aaron Bloch"]
dataArray = [one, two, three, four]
dataArray is inited like this:
var dataArray: Array<Dictionary<String, String>> = []
Related
Does somebody have a good Tutorial for a Search Bar with Sections? I did not found a good one yet. Or maybe you can help me straight with my project!?
The section Title is static but i integrated some customized subtitles to show the regions and the total time i spend to make all this Locations(Liegenschaften) in this section. I create this values in the function createWinterdienstDetail. This values should not change when i search for one Location.
I get the Values for my tableview from a different ViewController as
var AllWinterdienstTourInfos: [Int:[Int:[String]]] = [:] // Section - Locationnumber - Locationinformations
Here is my ViewController File:
import UIKit
class WinterdienstTourVC: UIViewController {
var sections = ["Tour 1","Tour 2","Tour 3","Tour 4"]
var LiegenschaftDetail: [String] = []
// VARIABLEN WINTERDIENST
var WinterdienstregionTour1: [String] = []
...
var WinterdienstregionTour15: [String] = []
var WinterdienstaufwandTour1String: [String] = []
...
var WinterdienstaufwandTour15String: [String] = []
var WinterdienstaufwandTour1: [Double] = []
...
var WinterdienstaufwandTour15: [Double] = []
var Totaltouraufwand1 = Double()
...
var Totaltouraufwand15 = Double()
var AllWinterdienstTourInfos: [Int:[Int:[String]]] = [:]
// Initialisierung
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
createWinterdienstDetail()
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView(frame: CGRect.zero)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "WinterdienstDetailSegue1") {
let DetailviewController = segue.destination as! WinterdienstLiegenschaftDetailVC
DetailviewController.LiegenschaftDetail = LiegenschaftDetail
}
}
func createWinterdienstDetail() {
if let liegenschaftenTour1 = AllWinterdienstTourInfos[0],
let liegenschaftenTour2 = AllWinterdienstTourInfos[1],
let liegenschaftenTour3 = AllWinterdienstTourInfos[2],
let liegenschaftenTour4 = AllWinterdienstTourInfos[3]{
self.myGroup.enter()
// DETAILS TOUR 1
for liegenschaften in liegenschaftenTour1.keys {
WinterdienstregionTour1.append(AllWinterdienstTourInfos[0]![liegenschaften]![6])
WinterdienstaufwandTour1String.append(AllWinterdienstTourInfos[0]![liegenschaften]![15])
for i in 0 ..< WinterdienstregionTour1.count-1 {
var j = WinterdienstregionTour1.count - 1
while(j > i) {
if WinterdienstregionTour1[i] == WinterdienstregionTour1[j] {
WinterdienstregionTour1.remove(at: j)
}
j -= 1
}
}
}
for WinterdienstaufwandTour1Array in WinterdienstaufwandTour1String {
WinterdienstaufwandTour1.append((WinterdienstaufwandTour1Array as NSString).doubleValue)
}
Totaltouraufwand1 = WinterdienstaufwandTour1.reduce(0,+)
// DETAILS TOUR 2
// DETAILS TOUR 3
// DETAILS TOUR 4
self.myGroup.leave()
self.myGroup.notify(queue: .main) {}
DispatchQueue.main.async {}
} // ENDE Function Create Winterdienst
} // ENDE CLASS WinterdienstTourVC
// DataSource-Methoden
extension WinterdienstTourVC: UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int
{
return sections.count
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
// SECTION HEADER ALLGEMEIN
view.backgroundColor = UIColor.lightGray
// SECTION HEADER TOUR - NR
let tournr = UILabel()
tournr.text = sections[section]
tournr.font = UIFont.boldSystemFont(ofSize: 20.0)
tournr.frame = CGRect(x: 15,y:0, width: 100, height: 30)
view.addSubview(tournr)
// SECTION HEADER - TOURREGION / TOURAUFWAND
let tourregion = UILabel()
WinterdienstregionTour1.sort()
WinterdienstregionTour1.sort()
WinterdienstregionTour3.sort()
WinterdienstregionTour4.sort()
switch section{
case 0:
let tourregion1 = WinterdienstregionTour1.joined(separator: ", ")
tourregion.text = "\(tourregion1)"
case 1:
let tourregion2 = WinterdienstregionTour2.joined(separator: ", ")
tourregion.text = "\(tourregion2)"
.....
default:
tourregion.text = "Keine Angaben"
}
tourregion.font = UIFont.systemFont(ofSize: 16)
tourregion.frame = CGRect(x: 15,y:22, width: 200, height: 30)
view.addSubview(tourregion)
let touraufwand = UILabel()
switch section{
case 0:
touraufwand.text = "\(Totaltouraufwand1) h"
case 1:
touraufwand.text = "\(Totaltouraufwand2) h"
....
default:
touraufwand.text = "Keine Angaben"
}
touraufwand.frame = CGRect(x: -5,y:12, width: 370, height: 30)
touraufwand.font = UIFont.boldSystemFont(ofSize: 22.0)
touraufwand.textAlignment = .right
view.addSubview(touraufwand)
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView,
numberOfRowsInSection section: Int) -> Int
{
switch section{
case 0:
return self.AllWinterdienstTourInfos[0]!.count
// self.WinterdienstadressTourAll[0]!.count
case 1:
return self.AllWinterdienstTourInfos[1]!.count
//self.WinterdienstAlltourinfosAll[1]![section]!.count
....
default:
return 1
}
}
func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath)
-> UITableViewCell
{
// versuchen, eine Zelle wiederzuverwenden
var cell = tableView.dequeueReusableCell(
withIdentifier: "cell")
if cell == nil {
// nicht möglich, daher neue Zelle erzeugen
cell = UITableViewCell(
style: .default, reuseIdentifier: "cell")
}
// Eigenschaften der Zelle einstellen
cell!.textLabel!.text = AllWinterdienstTourInfos[indexPath.section]![indexPath.row]?[4]
cell!.textLabel!.adjustsFontSizeToFitWidth = true
cell!.textLabel!.textAlignment = .left
// Zelle zurückgeben
return cell!
}
}
// TableView-Delegates
extension WinterdienstTourVC: UITableViewDelegate {
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath)
{
LiegenschaftDetail = AllWinterdienstTourInfos[indexPath.section]![indexPath.row]!
performSegue(withIdentifier: "WinterdienstDetailSegue1", sender: self)
}
}
I have made an Collapsed TableView. The size of the tableView's label is not increasing according the content. I had set WordWrap and Lines = 0 but still it's not working.
I'm using 2 tableView cell's to make the collapsed view.
extension UIView {
func rotate(toValue: CGFloat, duration: CFTimeInterval = 0.2, completionDelegate: AnyObject? = nil) {
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.toValue = toValue
rotateAnimation.duration = duration
rotateAnimation.removedOnCompletion = false
rotateAnimation.fillMode = kCAFillModeForwards
if let delegate: AnyObject = completionDelegate {
rotateAnimation.delegate = delegate
}
self.layer.addAnimation(rotateAnimation, forKey: nil)
}
}
class CollapsibleTableViewController: UITableViewController {
struct Section {
var name: String!
var items: [String]!
var collapsed: Bool!
init(name: String, items: [String], collapsed: Bool = false) {
self.name = name
self.items = items
self.collapsed = collapsed
}
}
var sections = [Section]()
override func viewDidLoad() {
super.viewDidLoad()
sections = [Section(name: "TEXT OVER HERE", items: ["TEXT OVER HERE."])]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return sections.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return (sections[section].collapsed!) ? 0 : sections[section].items.count
}
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = tableView.dequeueReusableCellWithIdentifier("header") as! CollapsibleTableViewHeader
header.toggleButton.tag = section
header.titleLabel.text = sections[section].name
header.toggleButton.rotate(sections[section].collapsed! ? 0.0 : CGFloat(M_PI_2))
header.toggleButton.addTarget(self, action: #selector(CollapsibleTableViewController.toggleCollapse), forControlEvents: .TouchUpInside)
return header.contentView
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
cell.textLabel?.lineBreakMode = NSLineBreakMode.ByWordWrapping
cell.textLabel?.numberOfLines = 0
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row]
return cell
}
//
// MARK: - Event Handlers
//
func toggleCollapse(sender: UIButton) {
let section = sender.tag
let collapsed = sections[section].collapsed
// Toggle collapse
sections[section].collapsed = !collapsed
// Reload section
tableView.reloadSections(NSIndexSet(index: section), withRowAnimation: .Automatic)
}
}
try this code:
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName.frame.size.height
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
var lblSectionName: UILabel = UILabel()
lblSectionName.text = self.sectionNames[section]
lblSectionName.numberOfLines = 0
lblSectionName.lineBreakMode = .ByWordWrapping
lblSectionName.sizeToFit()
return lblSectionName
}
Better is this answer: https://stackoverflow.com/a/29763200/1054550
self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 25;
I have a ChartCell(UITableViewCell), it has an UIView that I use for showing a chart
class ChartCell: UITableViewCell {
#IBOutlet weak var itemChart: ChartView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
but my UITableView repeat the cell after scroll down
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return items.count
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return items[section]["title"].stringValue
}
func tableView(tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
let header = view as! UITableViewHeaderFooterView
header.textLabel?.font = UIFont(name: (header.textLabel?.font?.fontName)!, size: 13)!
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 30.0
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.items[section]["data"].count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
switch items[indexPath.section]["cell"]{
case "bar" :
let cell = tableView.dequeueReusableCellWithIdentifier("bar", forIndexPath: indexPath) as! ChartCell
cell.itemChart.data = items[indexPath.section]["data"][indexPath.row]
cell.itemChart.total = items[indexPath.section]["total"].intValue
return cell
default :
let cell = tableView.dequeueReusableCellWithIdentifier("issue", forIndexPath: indexPath) as! IssueCell
cell.itemDescription.text = items[indexPath.section]["data"][indexPath.row]["group_name"].stringValue
cell.itemAmount.text = items[indexPath.section]["data"][indexPath.row]["ticket_count"].stringValue
return cell
}
}
func loadReport(sender : AnyObject) {
let closedController = self
self.activityIndicatorView.startAnimating()
Services.getClosedReport({(status : Bool, data : JSON) -> Void in
let tR = data["data"]["summary_by_resolution"]["data"] ?? []
let tP = data["data"]["summary_by_priority"]["data"] ?? []
let tI = data["data"]["summary_by_issue_type"]["data"] ?? []
var totalR = 0
for (_, subJson) in tR {
if totalR < subJson["ticket_count"].intValue{
totalR = subJson["ticket_count"].intValue
}
}
var totalP = 0
for (_, subJson) in tP {
if totalP < subJson["ticket_count"].intValue{
totalP = subJson["ticket_count"].intValue
}
}
let tS = [
JSON(["title" : "By Top 5 Resolution Types", "data" : tR , "cell" : "bar", "total" : JSON(totalR)]),
JSON(["title" : "By Top 5 Issue Types", "data" : tI, "cell" : "issue"]),
JSON(["title" : "By Priority", "data" : tP , "cell" : "bar", "total" : JSON(totalP)]),
]
closedController.items = JSON(tS)
self.itemReportTable.reloadData()
self.activityIndicatorView.stopAnimating()
})
}
I debugged the tableView func for cellForRowAtIndexPath but the data is correct in each one section and row, the cell doesn't call the drawRect func of UIView into the custom cell, this last one repeat another cell in another section
UPDATE :
the Custom UIView is the following:
class ChartView: UIView {
var data : JSON!
var total : Int!
override func drawRect(rect: CGRect) {
let itemView = self
let data = itemView.data
let corePoint = CGPoint(x: 10, y: 10)
let viewWidth = self.bounds.width
let space = CGFloat(10.0)
// MARK : -- Description
let widthL = CGFloat(100.0)
let heightL = CGFloat(20.0)
let text = data["group_name"].stringValue
let rectL = CGRectMake(corePoint.x, corePoint.y, widthL, heightL)
let itemL = UILabel(frame: rectL)
itemL.text = text
itemL.font = UIFont(name: itemL.font.fontName, size: 13.0)
itemView.addSubview(itemL)
// MARK : -- CGRect
let heightR = CGFloat(30.0)
let toY = (heightR - heightL) / 2.0
let yR = corePoint.y - toY
let xR = corePoint.x + widthL + space
let rect = CGRectMake(xR, yR, 0, heightR)
let itemR = UIView(frame: rect)
itemR.backgroundColor = UIColor(red: 49.0/255.0, green: 149.0/255, blue: 169.0/255.0, alpha: 1.0)
itemView.addSubview(itemR)
// MARK : -- Amount
let widthA = widthL
let heightA = heightL
let textA = data["ticket_count"].stringValue
let xA = xR + space
let yA = corePoint.y
let rectA = CGRectMake(xA, yA, widthA, heightA)
let itemA = UILabel(frame: rectA)
itemA.text = textA
itemA.font = UIFont(name: itemA.font.fontName, size: 13.0)
itemView.addSubview(itemA)
// MARK : -- Animation
UIView.animateWithDuration(0.75, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: { () -> Void in
let widthT = (viewWidth - xR - 50) * CGFloat(data["ticket_count"].intValue) / CGFloat(self.total)
itemR.frame = CGRectOffset(CGRectMake(xR, yR, widthT, heightR), 0.0, 0.0)
itemA.frame.origin.x = xA + widthT + 5.0
}, completion: nil)
}
}
I have some basic code, trying to load a UITableView with some cells. I had set cell's ID in Storyboard,and create a swift file and xib for cell named "DemoListCell". I keep getting this error, although i don't use storyboards in my project.
Any ideas? Thanks for all of you .
import UIKit
// MARK:
class ViewController: UIViewController,UITableViewDataSource {
let cellId = "DemoListID"
let TopTableView = UITableView()
let PageTableView = UITableView()
let PageScrollView = UIScrollView()
var CellsIdentifier:String = ""
var NumbersofTab:CGFloat = 4
var Number:CGFloat = 4
var Size:CGFloat = 0
var OldPoint:CGFloat = 0
var NewPoint:CGFloat = 0{
didSet{
TopTableView.reloadData()
}
}
// MARK: - ViewDidLoad and init()
override func viewDidLoad() {
let TopWidth = self.view.frame.size.width
Size = TopWidth
let TopHeight:CGFloat = 50
let TopY = 0 - (TopWidth - TopHeight)/2
let TopX = 0 + (TopWidth - TopHeight)/2
let PageY = TopHeight
let PageHeight = self.view.frame.size.height - TopHeight
//TopTableView
TopTableView.frame = CGRectMake(TopX, TopY, TopHeight,TopWidth)
TopTableView.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI/2))
TopTableView.showsVerticalScrollIndicator = false
TopTableView.backgroundColor = UIColor.yellowColor()
TopTableView.dataSource = self
TopTableView.delegate = self
//PageTableView
PageTableView.frame = CGRectMake(0, 0, TopWidth,PageHeight)
let nib = UINib(nibName: "DemoListCell", bundle: nil) //Cell's Name
self.PageTableView.registerNib(nib, forCellReuseIdentifier: cellId)
PageTableView.backgroundColor = UIColor.blueColor()
//PageScrollView
PageScrollView.frame = CGRectMake(0, PageY, TopWidth,PageHeight)
PageScrollView.delegate = self
PageScrollView.contentSize = CGSize(width: TopWidth * NumbersofTab, height: PageScrollView.frame.height)
PageScrollView.pagingEnabled = true
PageScrollView.alwaysBounceHorizontal = false
PageScrollView.alwaysBounceVertical = false
//addSubview
self.view.addSubview(TopTableView)
PageScrollView.addSubview(PageTableView)
self.view.addSubview(PageScrollView)
}
}
// MARK: - UIScrollViewDelegate
extension ViewController: UIScrollViewDelegate{
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
OldPoint = PageScrollView.contentOffset.x
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
NewPoint = PageScrollView.contentOffset.x
print("\( NewPoint)")
}
}
// MARK: - UITableViewDalegate
extension ViewController:UITableViewDelegate{
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier(self.cellId, forIndexPath: indexPath) as! DemoListCell
if tableView.isEqual(TopTableView){
var cell:TopTableViewCell! = tableView.dequeueReusableCellWithIdentifier("cd") as? TopTableViewCell
if (cell == nil) {
cell = TopTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "cd")
switch indexPath.row{
case 0:
cell.backgroundColor = UIColor.greenColor()
case 1:
cell.backgroundColor = UIColor.redColor()
case 2:
cell.backgroundColor = UIColor.yellowColor()
case 3:
cell.backgroundColor = UIColor.whiteColor()
default:
cell.backgroundColor = UIColor.grayColor()
}
}
cell.TabTitle.text = "\(Int(NewPoint / Size))"
}
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let RowNumber:Int = 1
switch RowNumber{
default: return Int(NumbersofTab)
}
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let NumberofPages = Size / NumbersofTab
return NumberofPages
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
UIView.animateWithDuration(0.3) { () -> Void in
let Pages = self.Size * CGFloat(indexPath.row)
self.PageScrollView.contentOffset = CGPoint(x: Pages, y: 0)
self.TopTableView.reloadData()
self.NewPoint = self.PageScrollView.contentOffset.x
}
}
}
and this is "CellId" cell's Code:
class DemoListCell: UITableViewCell {
#IBOutlet weak var cellImg: UIImageView!
#IBOutlet weak var cellLabel: UILabel!
#IBOutlet weak var cellIcon: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
self.cellImg.layer.masksToBounds = true
self.cellImg.layer.cornerRadius = 20.0
self.cellImg.layer.borderWidth = 0.0
self.cellImg.image = UIImage(named: "avatar.jpg")// Initialization code
self.cellIcon.image = UIImage(named: "Next")
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
and there is "Cd" cell's Code:
class TopTableViewCell: UITableViewCell {
var TabTitle = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String!) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
TabTitle = UILabel(frame: CGRectZero)
TabTitle.textAlignment = NSTextAlignment.Right
TabTitle.numberOfLines = 1
TabTitle.backgroundColor = UIColor.clearColor()
TabTitle.textColor = UIColor(red: 130/255, green: 137/255, blue: 141/255, alpha: 1.0)
self.contentView.addSubview(self.TabTitle)
// 130 137 141
self.separatorInset = UIEdgeInsets(top: 0, left: 100, bottom: 0, right: -100)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
let marginX = CGFloat(0.0)
let marginY = CGFloat(0.0)
let width = CGFloat(30)
let height = self.contentView.frame.size.width
self.TabTitle.transform = CGAffineTransformMakeRotation(CGFloat(M_PI/2))
self.TabTitle.frame = CGRectMake(marginX, marginY, width, height)
}
}
When you register a nib with registerNib, you pass in a reuse identifier (second parameter). That identifier needs to be used in cellForRowAtIndexPath. However, your cellForRowAtIndexPath uses "cd" as the reuse identifier, not cellId, the one you registered the nib with. To fix this, change the two reuse identifier strings in cellForRowAtIndexPath:
var cell:TopTableViewCell! = tableView.dequeueReusableCellWithIdentifier(cellId) as? TopTableViewCell
if (cell == nil) {
cell = TopTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: cellId)
Edit
My mistake, I did not see the other dequeue at the top of the cellForRowAtIndexPath. However, I only saw one nib registered in viewDidLoad, so that means TopTableViewCell was never registered with identifier "cd".
I've been following (and converting to swift) a Ray Wenderlich tutorial (link to tutorial) on how to make an interface with horizontal tables. My application loads but does not show any data in the cells as below:
I have three swift files in the project:ArticleTableViewCell.swiftHorizontalTableViewCell.swiftArticleListViewController.swift
// ArticleTableViewCell.swift
// HorizontalTables
import UIKit
class ArticleTableViewCell: UITableViewCell {
var thumbnail: UIImageView!
var titleLabel: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
var frameA: CGRect = CGRectMake(3, 3, 100, 314)
thumbnail = UIImageView(frame: frameA)
thumbnail.opaque = true
self.contentView.addSubview(thumbnail)
var frameB: CGRect = CGRectMake(0, thumbnail.frame.size.height * 0.632, thumbnail.frame.size.width, thumbnail.frame.size.height * 0.37)
titleLabel = UILabel(frame: frameB)
titleLabel.opaque = true
titleLabel.backgroundColor = UIColor.clearColor()
titleLabel.textColor = UIColor.blackColor()
titleLabel.numberOfLines = 2
titleLabel.font = UIFont(name: "Helvetica Neue", size: 12)
thumbnail.addSubview(titleLabel)
self.transform = CGAffineTransformMakeRotation(CGFloat(M_PI) * 0.5)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
func reuseIdentifier() -> String {
return "ArticleCell"
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
// HorizontalTableViewCell.swift
// HorizontalTables
import UIKit
class HorizontalTableViewCell: UITableViewCell, UITableViewDelegate, UITableViewDataSource {
var horizontalTableView: UITableView!
var articles: NSArray!
override init(frame: CGRect) {
super.init(frame: frame)
var frameA: CGRect = CGRectMake(0, 0, 106, 320)
horizontalTableView = UITableView(frame: frameA)
horizontalTableView.showsVerticalScrollIndicator = false
horizontalTableView.showsHorizontalScrollIndicator = false
horizontalTableView.transform = CGAffineTransformMakeRotation(CGFloat(-M_PI) * 0.5)
horizontalTableView.frame = CGRectMake(0, 0, 320, 106)
horizontalTableView.rowHeight = 106
horizontalTableView.separatorStyle = UITableViewCellSeparatorStyle.SingleLine
horizontalTableView.separatorColor = UIColor.clearColor()
horizontalTableView.backgroundColor = UIColor(red: 201/252, green: 235/252, blue: 245/252, alpha: 1)
horizontalTableView.dataSource = self
horizontalTableView.delegate = self
self.addSubview(horizontalTableView)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return articles.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ArticleCell", forIndexPath: indexPath) as ArticleTableViewCell
let currentArticle: NSDictionary = articles.objectAtIndex(indexPath.row) as NSDictionary
cell.titleLabel.text = currentArticle.objectForKey("Title") as NSString
var pics: AnyObject = currentArticle.objectForKey("ImageName")!
cell.imageView?.image = UIImage(named: "\(pics)")
return cell
}
}
// ArticleListViewController.swift
// HorizontalTables
import UIKit
class ArticleListViewController: UITableViewController {
var articleDictionary: NSDictionary = NSDictionary()
let kHeadlineSectionHeight: Int = 26
let kRegularSectionHeight: Int = 26
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 45
let path = NSBundle.mainBundle().pathForResource("Articles", ofType: "plist")
UITableViewHeaderFooterView.appearance().tintColor = UIColor(red: 201/252, green: 235/252, blue: 245/252, alpha: 1)
articleDictionary = NSDictionary(contentsOfFile: path!)!
}
override func awakeFromNib() {
super.awakeFromNib()
self.tableView.backgroundColor = UIColor(red: 201/252, green: 235/252, blue: 245/252, alpha: 1)
tableView.rowHeight = 106
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return articleDictionary.allKeys.count
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let keys: NSArray = articleDictionary.allKeys
var sortedCategories: NSArray = keys.sortedArrayUsingSelector("localizedCompare:")
var categoryName: NSString = sortedCategories.objectAtIndex(section) as NSString
return categoryName.substringFromIndex(1)
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as HorizontalTableViewCell
let keys: NSArray = articleDictionary.allKeys
var sortedCategories: NSArray = keys.sortedArrayUsingSelector("localizedCompare:")
var categoryName: NSString = sortedCategories.objectAtIndex(indexPath.section) as NSString
let currentCategory: NSArray = articleDictionary.objectForKey(categoryName) as NSArray
cell.articles = currentCategory
if (indexPath.row % 2) == 1 {
cell.backgroundColor = UIColor(red: 201/252, green: 235/252, blue: 245/252, alpha: 1)
} else {
cell.backgroundColor = UIColor.clearColor()
}
return cell
}
}
Any thoughts on why I have tableView cells with no data?
It looks like you didn't register your cells to your tableview. If you're using a Storyboard, you need to enter in the cell identifier there. If XIBs, you'll need to register the class to the tableview first:
tableView.registerClass(ArticleTableViewCell.self, forCellReuseIdentifier: "ArticleCell")
The UITableViewController will be initialized. In the meanwhile, the delegate method and data sources methods are called for initializing purpose. That moment, you will only get what you have from your prototype of UITableViewCell. So, you have to call reloadData after you successfully distribute the data.
The problem is that you are using dequeueReusableCellWithIdentifier. It doesn't even use HorizontalTableViewCell(frame:CGRect) to init a TableViewCell, unless you manually do so. You should do something like this:
var cell = tableView.dequeueReusableCellWithIdentifier("CellIdentifier", forIndexPath: indexPath) as? HorizontalTableViewCell
if cell == nil {
cell = HorizontalTableViewCell(frame: CGRectMake(0, 0, tableView.frame.size.width, tableView.frame.size.height))
}
Same for ArticleTableViewCell:
var cell = tableView.dequeueReusableCellWithIdentifier("ArticleCell", forIndexPath: indexPath) as? ArticleTableViewCell
if cell == nil {
cell = ArticleTableViewCell(frame: CGRectMake(0, 0, 106, 106))
}
You can try using this init function in your cell
initWithStyle:reuseIdentifier: