2017-05-20 31 views
1

在底部上这个应用程序正与一个的TabBar后的NavBar在顶部具有分段控制:UISegmented控制消失驳回查看

我有一个问题,即查看A(段一)有一个UITableView,在选择一个单元格,显示更多的细节一个新的观点,当我点击后面,顶部的分段控制将消失,从观的TableView中会被拉高。

这并不总是会发生 - 有时会在很多次尝试之后或有时只是一次。我没有发现与导致它的任何相关性。

我发现如果从分段控件中选择查看B,然后返回到查看A,然后单击其中一个表格单元格以进入详细信息屏幕,然后单击返回,100%的时间返回顶部导航栏随着分段控制消失。

enter image description here

TabBarItemOneViewController

let segmentOneVC: SegmentOneViewController 
let segmentTwoVC: SegmentTwoViewController 

var currentViewController: UIViewController 

let viewControllerYLoc = 60 // statusBarHeight + topBarHeight 
let viewWidth = Helper.getViewWidth() 
let tabBarHeight = 40 

func pressedSegItem(segControl: UISegmentedControl){ 

    let viewControllerHeight = Int(self.view.frame.height) 

    let viewFrame = CGRect(x: 0, y: viewControllerYLoc, width: Int(viewWidth), height: viewControllerHeight) 

    let selectedIndex = segControl.selectedSegmentIndex 
    previouslySelectedMyLoadsIndex = selectedIndex 

    self.currentViewController.removeFromParentViewController() 

    if(selectedIndex == 0){ 
     currentViewController = segmentOneVC 
    } 
    else if(selectedIndex == 1){ 
     currentViewController = segmentTwoVC 
    } 

    self.view.addSubview(self.currentViewController.view) 
    self.currentViewController.didMove(toParentViewController: self) 
} 

public init() { 

    segmentOneVC = SegmentOneViewController(nibName: nil, bundle: nil) 
    segmentTwoVC = SegmentTwoViewController(nibName: nil, bundle: nil) 

    if(previouslySelectedIndex == 0){ 
     currentViewController = segmentOneVC 
    } 
    else{ 
     currentViewController = segmentTwoVC 
    } 

    super.init(nibName: nil, bundle: nil) 

    self.calculateItems() 

    self.addSegmentedControl() 

    let viewControllerHeight = (Int(self.view.frame.height) - viewControllerYLoc) - tabBarHeight 

    let viewFrame = CGRect(x: 0, y: viewControllerYLoc, width: Int(viewWidth), height: viewControllerHeight) 

    self.currentViewController.view.frame = viewFrame 
    self.addChildViewController(segmentOneVC) 
    self.addChildViewController(segmentTwoVC) 
    self.view.addSubview(self.currentViewController.view) 
    self.currentViewController.didMove(toParentViewController: self) 
} 

SegmentOneViewController(注:SegmentTwoViewController是相同的)

let cellReuseIdentifier = "ItemDetailTableViewCell" 

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    let row = indexPath.row 

    let dataItem = self.dataArray[row] 

    let itemDetailVC = ItemDetailViewController() 
    itemDetailVC.dataItem = dataItem 
    self.present(itemDetailVC, animated: true, completion: nil) 
} 

func addTableView(){ 
    self.tableView = UITableView() 

    tableView.register(ItemDetailTableViewCell.self, forCellReuseIdentifier: self.cellReuseIdentifier) 

    tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) 

    tableView.frame = CGRect(x: 0, y: 0, width: Int(viewWidth), height: (Int(self.view.frame.height) - bottomOfTopNavBar) - heightOfTabBar) 

    self.view.addSubview(tableView) 
} 

override func viewDidAppear(_ animated: Bool){ 
    super.viewDidAppear(animated) 

    loadData() 

    tableView.dataSource = self 
    tableView.delegate = self 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 

    addTableView() 
} 

ItemDetailViewController

// Connected to a back button in a top Navigation Bar 
func goBack(){ 
    self.dismiss(animated: false, completion: nil) 
} 
+0

似乎很难猜到没有看到任何源代码。 –

+0

我将使用一些代码示例进行编辑。 – SB2017

+0

模式显示您的详细视图吗? – Magnas

回答

1

不错的图形顺便说一句,这个插图让你更容易理解你的问题。

另外BTW,我是一个Obj-C的人,仍然在学习Swift的细微差别,所以请让我知道我的语法或其他是不正确的。我在使用容器VC方面也相对缺乏经验。

我已经写了我的回应分两部分。

,第一部分是我试图解决您的问题。

第二部分是我的建议,供您考虑替代方案。

第一部分

这是我在你的代码的执行顺序/序列的了解...

父视图与分段控制

  1. public init():上父视图控制器的实例化,两个子VC(segmentOneVC和segmentTwoVC)被实例化并且取决于先前的选择分配为currentViewController。然后,您将分段控件添加到TabBarItemOneViewController

  2. 用户点击分段控件。

  3. 根据用户的输入,无论是SegmentOneViewControllerSegmentTwoViewController视图加入作为subviewTabBarItemOneViewController.view。 (注意,当VC被初始化这个也做)

子视图

  • override func viewDidLoad():一旦认为没有负载时,可以调用功能addTableView

  • func addTableView():在这个自定义函数中,你实例化你的表视图并将它放在SegmentOneViewController中,这本身就是我假设的UIViewController

  • override func viewDidAppear(_ animated: Bool):您调用自定义函数loadData并设置您的表视图数据源和委托。

  • 后退按钮

  • 用户轻敲后退按钮。

  • 子VC被解雇,TabBarItemOneViewController成为屏幕上的活动视图。

  • 让我们来看看按下后退按钮时视图控制器生命周期中没有发生什么......列表中的项目1。

    这可能解释不一致。

    试试这个...运行该应用程序,点击选项卡控件带你到TabBarItemOneViewController。不要点击分段控件。在表格视图中点击一行。点击你的孩子VC中的后退按钮。我会猜测你的分段控制仍然存在。

    现在试试这个...运行应用程序,点击选项卡控件带你到TabBarItemOneViewController。点击分段控件。在表格视图中点击一行。点击你的孩子VC中的后退按钮。我会猜测你的分段控制不再存在。

    为什么?由于我假定自定义功能pressedSegItem已将目标操作分配给分段控件,因此将覆盖您的init,这是将分段控件添加到标签栏视图控制器的位置。作为示例,尝试将代码实例化为您的分段控件,而不是在TabBarItemOneViewController VC的覆盖函数viewWillAppear中。

    所以有几个概念要考虑......

    • 延迟加载以节省内存分配 - 只在用户明确请求应用程序中的函数时实例化需要的对象;
    • UIViewController生命周期中每个函数的执行顺序;和
    • 哪些功能被执行一次,哪些在您的视图成为第一响应者/活动视图时执行。

    一些阅读recomendations:

    第二部分

    通过提供这种选择,我不建议你的方法不正确,不过我建议你考虑的选择。

    我一直使用标签栏控制器来更改视图和分段控件来过滤数据集或更改当前视图的外观。

    考虑使用UISegmentedControl来管理或调整仅在一个表视图中的数据集。这将缓解对多个视图控制器的需求以及管理这些控制器的杂耍行为。

    例如,写你的看法TABEL您的数据源和委托方法/功能时,您可以包括以下代码,以确保表视图加载和响应accordinagly:

    let selectedIndex = segControl.selectedSegmentIndex 
    if(selectedIndex == 0) { 
        rowHeight = 20 'for example 
    } else { 
        rowHeight = 30 'for example 
    } 
    

    然后你需要重新表达您的表格视图以实现更改。

    +0

    我其实很喜欢这个选择。我最终重构了应用程序的整个部分,因为两个屏幕都只是表格视图单元格。如果两个屏幕截然不同,我可以看到我的方法。 – SB2017

    0

    你配置viewDidLoad中()viewWillAppear中()分段控制? 我推荐后者。