在没有故事板的情况下,使用自定义单元格在视图控制器中嵌套UITableView。

4
我正在使用Swift 2.0和Xcode 7.2。
我想学习如何制作一个没有storyboard的应用程序(纯编程代码UI)。首先,我正在尝试制作一个简单的应用程序,在自定义的UITableView单元格中有三个标签,这些标签将通过互联网动态更新。
到目前为止,我已经完成了以下内容:
- 创建了一个新的Swift项目,并从项目中删除了main.storyboard - 添加了一个视图控制器作为AppDelegate中的rootViewController - 包含代码以在此视图内创建UITableView
以下是我想要完成的其他任务(全部以编程方式完成,而不使用属性检查器):
- 将UINavigationController插入ViewController中 - 添加具有三个标签的自定义单元格 - 更新表视图数据
如果可能的话,我希望拥有一切都能在横向模式下工作的能力。
有人可以告诉我如何做到这一点吗?
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.
    }
}

我不知道如何通过编程创建自定义单元格并添加对象。

希望能得到帮助。

谢谢。

3个回答

7
如果您不使用故事板,您可以在您的ViewController类之上定义单元格,其中包含您的tableView,例如下面所示的自定义单元格myCell。
在这个myCell中,您可以添加任意数量的对象,并在setUpCell()块中设置它们。
完整代码如下,请确保在cellForRowAtIndexPath中使用单元格时调用setUpCell()
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!
    }
}

看看这是否适用于您。我从未使用编程创建tableView,因此这可能不是以编程方式创建tableView的最佳方法。如果可能的话,我希望其他人能提供更好的答案。


2
你可以创建一个 UITableViewCell 的子类,比如 PackageListTableViewCell。
根据你的需求在自定义的 tableViewCell 类中声明标签数量,例如以下形式:
var label1 : UILabel?;

在自定义单元格中,可以使用以下附加参数覆盖 init:reuseIdentifier: 方法。

        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);          

    }

您的 tableView:cellForRowAtIndexPath: 方法将会如下所示:

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;
    }

我创建了一个新的UITableViewCell类PackageListTableViewCell。但是我不确定Product和StoreProduct是什么?我收到了“使用未声明类型”的错误。我该如何处理它? - Vicky Arora
你可以删除这些参数,这些参数是我的自定义数据。 - Hitendra Solanki
阅读此链接中的代码,您将了解到: //根据您的要求更改参数,或者除了“style:”和“reuseIdentifier:”之外,您也可以删除其他参数 - Hitendra Solanki
那样做消除了一些错误,但现在我不确定如何使用“Constant.cellID”作为标识符?因此,我不确定如何使用if(cell == nil){ cell = PackageListTableViewCell.init(style: UITableViewCellStyle.Default, reuseIdentifier: reuseIdentifier, storeProduct: storeProduct, package: package); }我是一个相当新手,总是使用storyboard。您能否编辑掉所有与自定义数据相关的内容,并使其更与问题相关。这将非常有帮助。我真的很感激您的努力。 - Vicky Arora
谢谢。现在问题是当数据滚动到视图底部时,所有数据都会重叠在一起。顶行数据没有问题。这里仍然存在一些问题。你知道是什么吗? - Vicky Arora
1
@VickyArora Hitendra的代码运行良好,唯一的问题是你现在在cellForRowAtIndexPath中缺少了cell.clipsToBounds = true。一旦你添加了这个,这段代码就应该可以工作了。所有的功劳归功于这篇文章:https://dev59.com/k2Eh5IYBdhLWcg3wfjeq - NS1518

0

您必须使用tableview上的registerClass方法来注册自定义tableviewcell类。

请使用以下修改后的ViewController代码:

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.
}

}


我应该如何创建一个使用你创建的标识符myIdentifier的自定义tableViewCell?从我所看到的,你的代码仍然使用基本的UITableView单元格及其标签和详细文本。你能告诉我如何创建一个带有多个标签的自定义单元格而不使用storyboard吗? - Vicky Arora
tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "myIdentifier") - 这就行了。在这里,您可以使用自己的自定义UITableviewCell子类。 - Aruna Mudnoor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接