【问题标题】:Dynamic number of ChildViewControllers for XLPagerTabStripXLPagerTabStrip 的 ChildViewController 的动态数量
【发布时间】:2017-10-16 09:15:12
【问题描述】:

我正在使用XLPagerTabStrip 在 Swift 4 中创建一个基于类别的阅读应用程序。我了解到可以使用以下函数轻松创建静态数量的 ViewController。

override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] { } 

但是,在我的案例中,类别的数量取决于服务器响应,这可能会根据需要而变化。我尝试通过根据从 json 响应中解析的类别名称创建视图控制器来创建动态数量的选项卡。这是我尝试过的方法。

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
    var childrenVC = [UIViewController]()
    for eachCategory in postCategories {
            print(eachCategory)
        let newVC = self.storyboard?.instantiateViewController(withIdentifier: "FirstTVC") as? FirstTVC
        newVC?.childName = eachCategory.name
        childrenVC.append(newVC!)
        self.reloadPagerTabStripView()
        self.reloadInputViews()
}
    return childrenVC
}

是的,失败了。在这种情况下,如何实现标签的动态数量?如果不是,我也愿意接受任何其他选择。我完成了 json 响应的事情,但停留在这一步。 SO answerGithub Issue 也没有帮助。

【问题讨论】:

    标签: ios json ios11 swift4 xlpagertabstrip


    【解决方案1】:

    我也有同样的情况。如果您按照您应该的方式从服务器异步获取结果,您将遇到崩溃,因为 xlpagertabstrip 至少需要一个子视图控制器。 我找到的解决方案是在应用程序启动时返回一个虚拟视图控制器,然后从服务器获取数据以重新加载PagerTabStripView。

    在您的父视图控制器中,您应该创建一个从服务器获取的对象的空数组,例如:

    var menuItems = [MenuObject]()
    

    接下来,viewControllers(for pagerTabStripController ... ) 方法应该如下所示:

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        var children = [UIViewController]()
        if menuItems.count == 0 {
            let child = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "DummyVC") as! DummyVC
            children.append(child)
            return children
        } else {
            let menuItemsUrls = menuItems.map{$0.url}
            for menuItem in menuItems {
                let child = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "MainVC") as! TelegrafMainVC
                child.name = menuItem.name.uppercased
                child.url = menuItem.url
                children.append(child)
            }
    
            return children
        }
    }
    

    从服务器获取数据后,无论是使用 URLSession 还是 Alamofire 或其他任何方法,在函数或闭包中,您都应该输入如下内容:

    self.menuItems = menuItems
    
     DispatchQueue.main.async {
           self.reloadPagerTabStripView()
     }
    

    如果我需要澄清一些事情,请告诉我,但我相信这足以帮助你。 干杯

    【讨论】:

      【解决方案2】:

      第 1 步:在您的初始视图控制器中执行此操作,

      class initialViewController: UIViewController {
           override func viewWillAppear(_ animated: Bool) {
                self.loadMainView(viewControllerArray: self.setMainViewTabParameters())
           }
      
       func setMainViewTabParameters() -> NSMutableArray {
            let viewControllerArray = NSMutableArray()
            var tabArray = ["Tab1", "Tab2", "Tab3", "Tab4", "Tab5", "Tab6", "Tab7"]
      
            var tabIndex = NSInteger()
            for item in tabArray {
                 let tabString = tabArray[tabIndex]
                 let tabview = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "YourTabControllerIdentifier") as! YourTabController
                 tabview.tabHeadingTitle = tabString as NSString
                 viewControllerArray.add(tabview)
                 tabIndex = tabIndex + 1
            }
            return viewControllerArray
       }
      
       func loadMainView(viewControllerArray : NSMutableArray) -> Void {
            let mainView = self.storyboard?.instantiateViewController(withIdentifier: "YourMainControllerIdentifier") as! YourMainController
            mainView.viewControllerList = viewControllerArray
            self.navigationController?.pushViewController(mainView, animated: false)
       }
      }
      

      第 2 步:

      class YourMainController: ButtonBarPagerTabStripViewController {
      
           var viewControllerList = NSArray()
           var isReload = false
      
           //MARK: - PagerTabStripDataSource
           override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
                guard isReload else {
                     return viewControllerList as! [UIViewController]
                }
      
                var childViewControllers = viewControllerList as! [UIViewController]
      
                for (index, _) in childViewControllers.enumerated(){
                     let nElements = childViewControllers.count - index
                     let n = (Int(arc4random()) % nElements) + index
                     if n != index{
                          swap(&childViewControllers[index], &childViewControllers[n])
                     }
                }
                let nItems = 1 + (arc4random() % 8)
                return Array(childViewControllers.prefix(Int(nItems)))
           }
      
           override func reloadPagerTabStripView() {
                isReload = true
                if arc4random() % 2 == 0 {
                     pagerBehaviour = .progressive(skipIntermediateViewControllers: arc4random() % 2 == 0, elasticIndicatorLimit: arc4random() % 2 == 0 )
                } else {
                     pagerBehaviour = .common(skipIntermediateViewControllers: arc4random() % 2 == 0)
                }
                super.reloadPagerTabStripView()
           }
      }
      

      第 3 步:您的标签视图控制器:

      class YourTabController: UIViewController, IndicatorInfoProvider {
           var tabHeadingTitle = NSString()
      
           // MARK: - Top Tab Bar Method - IndicatorInfoProvider
           func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
                return IndicatorInfo(title: tabHeadingTitle as String)
           }
      }
      

      【讨论】:

        【解决方案3】:

        试试这个

        override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
            var childrenVC: [UIViewController] = []
        
            for eachCategory in postCategories {
                 let newVC = UIStoryboard(name: "Main (YOUR-STORYBOARD-NAME)", bundle: nil).instantiateViewController(withIdentifier: "FirstTVC") as? FirstTVC
                 newVC?.childName = eachCategory.name
                 childrenVC.append(newVC!)
            }
            return childrenVC
        }
        

        【讨论】:

        • 对此也进行了尝试和测试,给出了 fatalError("viewControllers(for:) should provide at least one child view controller") 错误
        • 这是由于“childrenVC”为空,请确保“postCategories”不为空
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多