繁体   English   中英

如何将UITableView放在UIView中

[英]How to put UITableView inside a UIView

我正在尝试在UIView中实现一个表视图。 我目前正在努力解决的一个问题是链接委托和dataSource。 如果我取消注释Xcode下面的两行,则会出现“预期声明”错误。 如果我从文档大纲中链接它们Xcode说没关系然后模拟崩溃。 如果有人能够找出问题,那就太好了。

谢谢!

import UIKit
class CurrentGameDetailView: UIView, UITableViewDelegate, UITableViewDataSource {

    @IBOutlet weak var tableView: UITableView!
    var theGame: GameObject? = nil

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return theGame!.roundNumber
    }

//    tableView.delegate = self
//    tableView.dataSource = self

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("OldGameDetailCell", forIndexPath: indexPath) as! OldGameDetailCell

        cell.roundLabel.text = theGame!.gameRounds[indexPath.row].gamePlayed.description
        ...

        return cell
    }
}

这是震撼,完整的项目,它的工作原理。 第一个视图控制器弹出,你看到一些按钮,我只是使用带有一些随机名称的tableview,你点击名称,然后弹出另一个tableview,表格的标题与你在第一个视图上点击的单元格相同控制器。 这通过使用块来实现,UIView中没有委托,但我将所有内容放在自定义视图中,除了使用“loadView”方法创建的第一个viewcontroller视图。 如您所见,没有数据从UIView传递到UITableViewCells,您不这样做,您从第一个视图控制器的单元格中提取所有数据,并假设第一个viewcontroller的表格单元格具有TON数据形式一个JSON数组或类似的东西然后你可以通过属性声明变量将整个“得分数组”传递给下一个视图控制器,我只是告诉你如何使用UIViewController的“title”属性传递信息,你可以创建自己的属性,并在单击单元格或regualr按钮的按钮时传递整个数组。 您不希望将此信息放入Subclassed tableViewCell,但是您可以从secondViewController的cellForRowAtIndexPath传递数据来为第二页上的记分板设置自定义信息,UIVeiw可以接受UIViewController的需求,而不是相反,您使用自定义UITableView将命令发送到UIView,并且UIViewController设置自定义UITableView的数据。 这是做事的正确方法。 还有更多可以添加到这个例子来使这个超级健壮,但这个想法是这样的:

示例1: UIViewController1

button1 ==> UIViewController从网络中提取信息或告诉UIView从网络中提取此信息存储在您拥有的包含ARRAY数据的自定义UIButton中

button2 ==> UIViewController从网络中提取信息或告诉UIView从网络中提取此信息存储在您拥有的包含ARRAY数据的自定义UIButton中

button3 ==> UIViewController从网络中提取信息或告诉UIView从网络中提取此信息存储在您拥有的包含ARRAY数据的自定义UIButton中

UIViewcontroller2 UITableView将存储在上面数组中的每个按钮的数据传递给secondViewController,然后填充表,这就是它的工作原理。

示例2: UIViewController1

button1 ==> UIViewController只是向UIButton添加一个动作事件

button2 ==> UIViewController只是向UIButton添加一个动作事件

button3 ==> UIViewController只是向UIButton添加一个动作事件

UIViewcontroller2自定义方法中的TableView调用网络并根据UIViewcontroller1中按钮的标题填充数据数组,通过使用从第二个视图控制器中的viewdidload调用的自定义方法将此数组粉碎到第二个视图控制器中然后,第二个viewcontroller调用它自己的视图,该视图使用UITableView对自定义UIView子类进行了类型转换。 然后,这个UIViewController2调用“cellForRowAtIndexPath”并在单元格上用setter方法填充表,从而强制数据进入UITableView

在这两种方法中,我们在自定义视图中设置了多少个代理? ZERO,因为UIViewControllers应该负责设置数据并向下发送,UIView绝不应该向上发送数据,除非UIViewController特别要求:

工作简单的例子(程序化,没有故事板,所以你可以看到发生了什么):

AppDelegate.swift:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var rootViewController: UINavigationController?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        rootViewController = UINavigationController(rootViewController: ViewController())
        if let window = window {
            window.backgroundColor = UIColor.whiteColor()
            window.rootViewController = rootViewController
            window.makeKeyAndVisible()
        }
        return true
    }
}

ViewController.swift

import UIKit

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var tableView : UITableView?
    var items = [
        "Ginger",
        "larry",
        "Moe",
        "Fred",
        "Terry"]

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView = UITableView(frame: CGRectMake(0, 0, 414, 736), style: UITableViewStyle.Plain)
        tableView!.delegate = self
        tableView!.dataSource = self
        tableView!.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "Cell")
        self.view .addSubview(tableView!)
    }
    override func loadView() {
        var stuf = UIView()
        stuf.frame = CGRectMake(0, 0, 414, 736)
        stuf.backgroundColor = UIColor .redColor()
        self.view = stuf
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count;
    }
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat {
        return 44
    }   
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomTableViewCell
        cell.doWork = {
            () -> Void in
            self.doStuff(indexPath.row)
        }
        cell.labelMessage.text = items[indexPath.row] as String
        return cell
    }
    func doStuff(integer: NSInteger) {
        var newViewController = SecondViewController()
        newViewController.title = items[integer] as String
        var dismissButton = UIBarButtonItem(title: "done", style: UIBarButtonItemStyle.Plain, target: self, action: "dismiss")
        newViewController.navigationItem.rightBarButtonItem = dismissButton
        var navControl =  UINavigationController(rootViewController: newViewController);
        self.navigationController?.presentViewController(navControl, animated: true, completion: { () -> Void in })
    }
    func dismiss() {
        self.navigationController?.dismissViewControllerAnimated(true, completion: { () -> Void in})
    }
}

SecondViewController.swift

import UIKit

class SecondViewController: UIViewController , UITableViewDataSource, UITableViewDelegate {

    var items = [
        "sports score1",
        "sports score2",
        "sports score3",
        "sports score4",
        "sports score5"]

    var myView: CustomViewWithTableView! {
        return self.view as! CustomViewWithTableView
    }
    override func loadView() {
        let height = self.navigationController!.navigationBar.frame.size.height as CGFloat

        view = CustomViewWithTableView(frame: CGRectMake(0, height, UIScreen.mainScreen().bounds.size.width, UIScreen.mainScreen().bounds.size.height-height as CGFloat))
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        self.myView.tableView.delegate = self
        self.myView.tableView!.dataSource = self
        self.myView.tableView!.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
    }
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items.count;
    }
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat {
        return 44
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
        cell.textLabel!.text =  items[indexPath.row] as String
        return cell
    }
}

CustomViewWithTableView.swift

import Foundation
import UIKit

class CustomViewWithTableView: UIView {

    var tableView: UITableView!

    override init(frame: CGRect) {
        super.init(frame: frame)
        tableView = UITableView(frame: CGRectMake(frame.origin.x, frame.origin.y, frame.width, frame.height), style: .Plain)
        self.addSubview(tableView)
    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

CustomTableViewCell.swift

import Foundation
import UIKit

class CustomTableViewCell: UITableViewCell, UIGestureRecognizerDelegate {

    var labelMessage = UILabel()

    var doWork: (() -> Void)?

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        let touchie: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "this")
        touchie.delegate = self
        touchie.cancelsTouchesInView = false
        self.addGestureRecognizer(touchie)
        labelMessage.setTranslatesAutoresizingMaskIntoConstraints(false)
        contentView.addSubview(labelMessage)

        //custom layout constraints
        var viewsDict =  ["labelMessage" : labelMessage]

        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[labelMessage]|", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))
        contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[labelMessage]", options: NSLayoutFormatOptions(0), metrics: nil, views: viewsDict))

    }
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

   //custom touch interceptor for presentation navigation
    func this () {
        if let callback = self.doWork {
            println("swipe detected, cell function run")
            callback ()
        }
    }

}

正如我上面所说,位于自定义UIView中的UITableView已经死了,直到UIViewController告诉视图它没有死。 这就是MVC应该如何工作,事实上,除此之外,还有一些我个人会添加的东西,以使这一点更加明显。

1. ViewController.swift的另一个自定义UIView

2. SecondViewController.swift的另一个自定义UITableViewCell

3.第一组Button数据的对象模型,这是一个NSObject子类,这是第一个viewController屏幕上的“按钮”数据

4.另一个对象模型(可能),用于对“得分”数据中的第二组数据进行建模

5. 2个UILabel的自定义子类

6. UIButton的2个自定义子类

UIView子类在上面的5和6中声明AS属性是子类UIElements,因此5和6只控制它们自己,UIViews就像它们的直接父类一样,是UIView本身的属性。

在这个项目的最后,我会为每个ViewController提供大约5-10个带有swift和可能更多的子类(使用ObjC,它将是这个大小的两倍)。 subViews的父类只控制其子视图和属性的内容,并且永远不会控制父视图的内容,这就是IOS的设计方式,封装了从UIViewController向下延伸的“数据聊天”流而不是其他方式。

无论如何,在你的Swift冒险中好运,我也在学习Swift,因为我回答这样的问题并将强烈和高级的ObjC代码翻译成Swift。 如果您有其他问题,请询问。 谢谢,祝你好运!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM