簡體   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