Alessandro
Alessandro

Reputation: 4100

Subclass UITableView in Swift

I am trying to create a subclass of UITableView in Swift.

var tableScroll = HorizontalScrollTableView(frame: CGRectMake(15, 15, cell.contentView.frame.width - 30, cell.contentView.frame.height - 30))
cell.contentView.addSubview(tableScroll)

I add the table in the following way and then I have a HorizontalScrollTableView swift file with

import UIKit

class HorizontalScrollTableView : UITableView {

func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
    return 1
}
...

However the Table presents like a normal default table and the functions in HorizontalScrollTableView do not override the default ones.

Upvotes: 0

Views: 3907

Answers (2)

nielsbot
nielsbot

Reputation: 16022

I went ahead and made a simple example using a Playground. You can see table view isn't subclassed, but instead there is a view controller which serves as the table view's delegate and a stand-in data source for the table view.

The data source provides the row data for the table view and the delegate (which is also the view controller) provides the cells.

This is a skeleton for how I normally set up my table views, although I would use an XIB generally.


import UIKit

// data for table view is array of String
let rowData = [ "Chicago", "Milwaukee", "Detroit", "Lansing" ]

//
// simple subclass of UITableViewCell that has an associated ReuseIdentifier
// and a value property. Setting the value property changes what the cell displays
//

public class TableViewCell : UITableViewCell
{
    public static let ReuseIdentifier = "TableViewCell"

    var value:AnyObject? {
        didSet {
            self.textLabel!.text = value as? String
        }
    }
}

//
// Simple implementation of a table view data source--just contains one String per row
// You could change your rowData to be an array of Dictionary for richer content possibilities.
// You could also load your data from a JSON file... for example
//

class TableViewDataSource : NSObject, UITableViewDataSource
{
    var rowData:[String]?

    init( rowData:[String] )
    {
        self.rowData = rowData
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        return rowData?.count ?? 0
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    {
        assert( indexPath.section ==  0 ) // we only have 1 section, so if someone section ≠ 0, it's a bug

        var cell:TableViewCell! = tableView.dequeueReusableCellWithIdentifier( "Cell" ) as? TableViewCell
        if cell == nil
        {
            cell = TableViewCell( style: .Default, reuseIdentifier: "Cell" )
        }

        cell.value = self.rowData![ indexPath.row ]

        return cell
    }

}

// This is the view controller for our table view.
// The view controller's view happens to be a table view, but your table view
// could actually be a subview of your view controller's view

class TableViewController : UIViewController, UITableViewDelegate
{
    // data source for our table view, lazily created
    lazy var tableViewDataSource:TableViewDataSource = TableViewDataSource( rowData: rowData )

    override func loadView()
    {
        // our view is a UITableView
        let tableView = UITableView()
        tableView.delegate = self
        tableView.dataSource = self.tableViewDataSource // using a self-contained data source object for this example
        self.view = tableView
    }
}

let window:UIWindow! = UIWindow()
window.rootViewController = TableViewController()
window.makeKeyAndVisible()  // click the "preview eyeball" to see the window

Upvotes: 0

Patrick Lynch
Patrick Lynch

Reputation: 2782

You're probably looking to override numberOfSections instead of numberOfSectionsInTableView:, which is a method on the UITableViewDataSource protocol. However, I believe it's more wise to create your own subclass of UITableViewController or your class conforming to UITableViewDataSource and set it as your table view's delegate rather than of the table view itself. Subclassing UIView and its descendants is usually reserved for customizing view-specific functionality and attributes, such as adding custom drawing or custom touch handling.

Upvotes: 1

Related Questions