Swift - 使用UITableViewController创建子菜单

时间:2016-08-04 08:50:41

标签: ios swift uitableview xcode7 drilldown

我正在使用Xcode 7和Swift 2开发一个简单的混合iOS应用程序。我需要从主菜单中创建子菜单。

我的主菜单使用表格视图。现在我可以创建第二个UITableViewController并在其中加载子菜单并创建第三个UITableViewController以加载另一个子菜单,依此类推。

但重新使用我的初始UITableViewController是否有更好的方法?

UITableViewController已嵌入UINavigationController

我正在使用一个UIViewController来显示最终的文字信息。

enter image description here

这是我的主菜单代码:

class MainMenuTableViewController:UITableViewController {

// MARK: Properties

var mainMenu = [MainMenu]()
var Item1Menu = [MainMenu]()
var Item12Menu = [MainMenu]()
var selectedMenu: Int = 0

override func viewDidLoad() {
    super.viewDidLoad()

    // Load the sample data.
    loadMainMenu()
    loadItem1Menu()
    loadItem12Menu()

}

func loadMainMenu() {
    let image1 = UIImage(named: "menu-1")!
    let menuItem1 = MainMenu(name: "Item 1", photo: image1, url: "no-url", urlType: "subMenu")!

    let image2 = UIImage(named: "menu-2")!
    let menuItem2 = MainMenu(name: "Item 2", photo: image2, url: "our-services", urlType: "localURL")!

    let image3 = UIImage(named: "menu-3")!
    let menuItem3 = MainMenu(name: "Item 3", photo: image3, url: "http://www.google.com", urlType: "webURL")!

    let image4 = UIImage(named: "menu-1")!
    let menuItem4 = MainMenu(name: "Item 4", photo: image4, url: "our-info", urlType: "localURL")!

    let image5 = UIImage(named: "menu-2")!
    let menuItem5 = MainMenu(name: "Item 5", photo: image5, url: "http://www.bing.com", urlType: "webURL")!

    //mainMenu.removeAll()
    mainMenu += [menuItem1, menuItem2, menuItem3, menuItem4, menuItem5]
}

func loadItem1Menu() {
    let image = UIImage(named: "menu-1")!
    let menuItem1 = MainMenu(name: "Item 1.1", photo: image, url: "our-profile", urlType: "localURL")!

    let menuItem2 = MainMenu(name: "Item 1.2", photo: image, url: "no-url", urlType: "sub-menu")!

    let menuItem3 = MainMenu(name: "Item 1.3", photo: image, url: "our-history", urlType: "localURL")!

    //mainMenu.removeAll()
    Item1Menu += [menuItem1, menuItem2, menuItem3]
}

func loadItem12Menu() {
    let image = UIImage(named: "menu-1")!
    let menuItem1 = MainMenu(name: "Item 1.2.1", photo: image, url: "portfolio-1", urlType: "localURL")!

    let menuItem2 = MainMenu(name: "Item 1.2.2", photo: image, url: "portfolio-2", urlType: "localURL")!

    let menuItem3 = MainMenu(name: "Item 1.2.3", photo: image, url: "portfolio-3", urlType: "localURL")!

    //mainMenu.removeAll()
    Item12Menu += [menuItem1, menuItem2, menuItem3]
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

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

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return mainMenu.count
}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    // Table view cells are reused and should be dequeued using a cell identifier.
    let cellIdentifier = "MainMenuTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MainMenuTableViewCell

    // Fetches the appropriate menu for the data source layout.
    let menu = mainMenu[indexPath.row]

    cell.nameLabel.text = menu.name
    cell.menuImageView.image = menu.photo

    return cell
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    var segueString:String
    selectedMenu = indexPath.row
    let urlType = mainMenu[selectedMenu].urlType

    if urlType == "subMenu" {

        //http://stackoverflow.com/a/38763630/1019454
        let vc = (UIStoryboard(name: "Main", bundle: NSBundle.mainBundle())).instantiateViewControllerWithIdentifier("MenuViewController") as! MainMenuTableViewController

        vc.mainMenu = Item1Menu
        // then push or present view controller
        self.navigationController!.pushViewController(vc, animated: true)

    } else {


        switch(mainMenu[selectedMenu].urlType){

        case "localURL":
            segueString = "ShowLocalWeb"
        default:
            segueString = "ShowWeb"
        }

        self.performSegueWithIdentifier(segueString, sender: self)
    }
}


// MARK: - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

    /*
    if segue.identifier == "ShowSubMenu" {
        let subMenuController = segue.destinationViewController as! SubMenuTableViewController
        subMenuController.subMenu = mainMenu[selectedMenu]
    }*/

    if segue.identifier == "ShowLocalWeb" {
        let localViewController = segue.destinationViewController as! LocalWebViewController
        localViewController.mainMenu = mainMenu[selectedMenu]
    }

    if segue.identifier == "ShowWeb" {
        let webViewController = segue.destinationViewController as! WebViewController
        webViewController.mainMenu = mainMenu[selectedMenu]

    }
}

}

3 个答案:

答案 0 :(得分:1)

实际上你已经准备好了。您需要的唯一更改是创建MainMenuTableViewController的实例,并为您的新菜单指定mainMenu

示例:

当您想要显示新菜单时。

let vc = MainMenuTableViewController()
vc.menu = <new menu here>
// then push or present view controller
self.navigationController.pushViewController(vc, animated: true)

对以下评论的回复:

不,您不必创建新文件,而是创建MainMenuTableViewController的新实例。您必须在包含menu的案例数组中更改数据部分。 <new menu here>指的是新菜单项的数组。

为此,您必须Decouple数据,这将有所帮助。

修改

您可以尝试从故事板创建vc,而不是以上述方式创建MainMenuTableViewController。请按照以下步骤操作:

  1. 在故事板中将故事板标识符分配给let vc = MainMenuTableViewController()而不是此行
  2. let vc = (UIStoryboard(name: <your storyboard file name>, bundle: NSBundle.mainBundle())).instantiateViewControllerWithIdentifier(<storyboard identifier of MainMainMenuTableViewController>)

    使用

    If IsPostBack Then
    
        Dim errorText As String = ""
        Dim formName As String = "register"
        Dim _username As String = MyUtils.setme(username.Text)
        Dim _fname As String = MyUtils.setme(fname.Text)
        Dim _password As String = MyUtils.setme(password.Text)
        Dim _tel As String = MyUtils.setme(tel.Text)
        Dim _street As String = MyUtils.setme(street.Text)
        Dim _street_no As String = MyUtils.setme(street_no.Text)
        Dim _city As String = MyUtils.setme(city.Text)
    
        Dim ds As New DataSet
        ds = MyUtils.runMSSQL_DS("select num from buyers where username='" & _username & "'")
    
        If MyUtils.isSpam(formName) Then
            errorText = "test1"
        ElseIf _fname = "" Then
            errorText = "test2"
        ElseIf _tel.Length < 7 Or _tel.Length > 11 Then
            errorText = "test3"
        ElseIf MyUtils.checkEmail(_username) = False Then
            errorText = "test4"
        ElseIf _password.Length < 4 Then
            errorText = "test5"
        Else
            If ds.Tables(0).Rows.Count > 0 Then
                errorText = "test6"
            End If
        End If
    End If
    

    我怀疑的原因是我之前无法找到要创建的单元格并因此进行删除的行。

答案 1 :(得分:0)

如果您想要一个最简单的解决方案,您应该切换数据源并在tableView上调用.reloadData()。

你是否真的有一些实现数据源协议的对象,只是在它们之间切换或者有一个对象数组作为你的数据源,只是切换这个数组的内容是你的决定,更像是造型/建筑事物

答案 2 :(得分:0)

如果我对这个问题的理解是正确的,我猜你有一个主菜单,并希望在它们下面显示子菜单。

这样做的一种方法是插入和删除行。这样您就可以重用相同的UITableViewController。因此,在单击项目2时,可以在填充了子菜单数据的索引处将一组行插入到tableView中。

您可以在调用tableView.beginUpdates()和tableView.endUpdates()的块内使用insertRowsAtIndexPaths(:withRowAnimation :)和deleteRowsAtIndexPaths(:withRowAnimation :)中的函数并更新tableView数据源实现这一目标。

希望这有帮助。