仅在布置了UIView后才发送数据源信息吗?

时间:2019-06-19 15:23:02

标签: ios swift uiview datasource subview

我很难理解这一点。我早些时候已经能够做这样的项目,但是现在类似的方法对我不起作用。

这是问题所在: 我有一个具有4 storyViewControllers的UIPageViewController。 每个storyViewControllers都有一个自定义的containerView。我想在UIViews上添加n个containerView。我正在从视图控制器发送dataSource或'n'。但是,我不能正确地将子视图放在容器视图上。

基本上,我想知道何时从视图控制器发送数据源信息。显然,添加自定义容器视图后,我想发送它。

我正在使用viewDidLayoutSubviews。这使其工作。但是,我认为这不是正确的方法。现在,每次视图控制器布置子视图时,都会调用我的委托。

我尝试在viewDidLoad()中执行此操作,但这也不起作用。

这有效。但是似乎并不正确。阿尔斯 我的storyViewController代码

    override func viewDidLoad() {
    super.viewDidLoad()
    segmentContainerView = ATCStorySegmentsView()
    view.addSubview(segmentContainerView)
    configureSegmentContainerView()
    segmentContainerView.translatesAutoresizingMaskIntoConstraints = false

}

  override func viewDidLayoutSubviews() {
    segmentContainerView.delegate = self
     DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
        self.segmentContainerView.startAnimation() // I am also animating these views that are laid on the containerView. Doing them here starts the animation randomly whenever I scroll through the UIPageController
    }
}

containerView中:

    var delegate: ATCSegmentDataSource? {
    didSet {
        addSegments()
    }
}

private func addSegments() {
    let numberOfSegment = delegate?.numberOfSegmentsToShow()
    guard let segmentQuantity = numberOfSegment else { return }
    layoutIfNeeded()
    setNeedsLayout()
    for i in 0..<segmentQuantity {
        let segment = Segment()
        addSubview(segment.bottomSegment)
        addSubview(segment.topSegment)
        configureSegmentFrame(index: i, segmentView: segment)
        segmentsArray.append(segment)
    }


}

private func configureSegmentFrame(index: Int, segmentView: Segment) {
    let numberOfSegment = delegate?.numberOfSegmentsToShow()
    guard let segmentQuantity = numberOfSegment else { return }

    let widthOfSegment : CGFloat = (self.frame.width - (padding * CGFloat(segmentQuantity - 1))) / CGFloat(segmentQuantity)

    let i = CGFloat(index)

    let segmentFrame = CGRect(x: i * (widthOfSegment + padding), y: 0, width: widthOfSegment, height: self.frame.height)
    segmentView.bottomSegment.frame = segmentFrame
    segmentView.topSegment.frame = segmentFrame
    segmentView.topSegment.frame.size.width = 0

}

这按应有的方式工作。但是,当我滚动UIPageViewController时,动画并不总是从头开始。由于它依赖于布局子视图。有时,如果我在页面控制器中缓慢滚动,则子视图会重新布置,动画从头开始。其他时候,当视图已经加载时,动画从我遗漏的地方开始。

问题,我想知道从视图控制器向containerView发送数据源的最佳方法是什么?该数据源是生成要添加到containerView上的视图数量所需要的。

这是我从viewDidLayoutSubviews发送数据源时得到的结果。我今天早些时候问了另一个问题,其中列出了我用来发送数据源的其他方法。还要看一下:Not able to lay out Subviews on a custom UIView in Swift

enter image description here

1 个答案:

答案 0 :(得分:0)

这是一个非常基本的示例...

它具有:

  • 一个Segment: UIView子类,其中包含一个“ bottomSegment”和一个“ topSegment”
  • 带有ATCStorySegmentsView: UIView的{​​{1}}子类,以布置所需数量的分段
  • 一个UIStackView子类,在其视图的顶部添加了StoryViewController: UIViewController,然后告诉该视图为ATCStorySegmentsView上的第一段设置动画。

viewDidAppear()

结果(显示视图时,白色条会在灰色条上动起来)

enter image description here

enter image description here

有5个细分:

enter image description here

请注意,正如自动布局的设计目的一样,它还可以处理尺寸变化,例如设备旋转时:

enter image description here