2017-10-28 99 views
2

我正在制作一个应用程序,其中1个屏幕具有3段的分段控制。最初我有1个表视图,当你改变段时,我只是简单地改变数据源/单元格等,并重新加载表。虽然这很好,但总是存在这样的问题,即当您更改段时,它将不会记住您的上一个滚动位置,因为表视图会重新加载。如何在使用多个容器视图时处理iOS 11大标题动画?

我试图解决这个与存储偏移位置,行等,但我永远不能让它像我想要的那样工作。似乎特别烦人,当你有不同的细胞类型的细分,他们也是自我大小。

我决定有一个主视图控制器分段控制和3个容器视图与他们自己的VC和表视图为每个分段。我只是在更改段时隐藏/显示正确的容器视图。这也很好,但我有1个问题与iOS 11风格的大头。只有第一个容器视图作为子视图添加到ViewControllers视图中时,才会在滚动时操纵标题的缩放/展开。

enter image description here

因此,当我换到第二或第三容器视图和开始滚动我不明白的大标题合拢动画。我该如何解决这个问题?

我尝试以下

1)改变容器视图z向位置时改变段

2)通过调用view.bringSubview(toFront: ...)

3将容器视图到前)通过子视图循环并调用 view.exchangeSubview(at: 0, withSubviewAt: ...)

我相信我可以删除所有的容器视图,并添加一个我需要再给它们约束但我不知道是否有矿石直接解决方案。

或者,如果有人有一个很好的解决方案,记住一个tableViews重新加载前滚动位置,我也很感激。

回答

0

因此,我发现了一个似乎适用于我的答案,这要感谢这篇文章。 https://cocoacasts.com/managing-view-controllers-with-container-view-controllers/

基本上我所做的是

1)从MasterViewController故事板拆下ContainerViews和塞格斯。

2)在MasterViewController中为每个分段控件的VC添加一个惰性属性。他们是懒惰的,让他们当你真正需要它们

lazy var viewController1: LibraryViewController = { 
     let viewController = UIStoryboard.libraryViewController // convenience property to create the VC from Storyboard 
     // do other set up if required. 
     return viewController 
    }() 

lazy var viewController2: LibraryViewController = { 
      let viewController = UIStoryboard.libraryViewController // convenience property to create the VC from Storyboard 
      // do other set up if required. 
      return viewController 
     }() 

3)用以下2种方法创建的UIViewController的延伸只得到初始化。我将它们添加到纯代码组织的扩展中,因为它们可能会在其他ViewController上重用。

extension UIViewController { 

    func add(asChildViewController viewController: UIViewController) { 
     // Add Child View Controller 
     addChildViewController(viewController) 

     // Add Child View as Subview 
     view.addSubview(viewController.view) 

     // Configure Child View 
     viewController.view.frame = view.bounds 
     viewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 

     // Notify Child View Controller 
     viewController.didMove(toParentViewController: self) 
    } 

    func remove(asChildViewController viewController: UIViewController) { 
     // Notify Child View Controller 
     viewController.willMove(toParentViewController: nil) 

     // Remove Child View From Superview 
     viewController.view.removeFromSuperview() 

     // Notify Child View Controller 
     viewController.removeFromParentViewController() 
    } 
} 

4)现在我的分段控制方法,当你改变段时被调用,我只需添加正确的ViewController。好消息是删除/添加它们并不实际释放它们。

func didPressSegmentedControl() { 

    if segmentedControl.selectedSegmentIndex == 0 { 
     remove(asChildViewController: viewController2) 
     add(asChildViewController: viewController1) 
    } else { 
     remove(asChildViewController: viewController1) 
     add(asChildViewController: viewController2) 
    } 
} 

5)确保您在ViewDidLoad调用该方法在点4,以便当VC加载的第一时间正确的VC加入。

func viewDidLoad() { 
    super.viewDidLoad() 

    didPressSegmentedControl() 
} 

这样,当我们删除ChildViewController并添加另一个它永远是顶级VC子视图数组中,我得到我的动听的名字合拢动画。

这种做法的另一个好处是,如果你从来没有去一个特定段的特定VC永远不会初始化,因为他们是懒惰的性质,应以效率有所帮助。

希望这有助于有人试图这样做。

+0

你有没有做其他任何事情有从子控制器滚动视图导航控制器获取滚动事件?我目前正在尝试实现类似的东西,我有一个容器控制器来检查数据。如果没有数据,则显示一个空状态控制器,否则显示一个表控制器。导航控制器不会移动。 – Maximilian