【发布时间】:2019-11-02 09:35:29
【问题描述】:
我无法理解这一点。我之前已经能够完成这样的项目,但现在类似的方法对我不起作用。
这里是问题:
我有一个 UIPageViewController,它有 4 个storyViewControllers。
每个storyViewControllers 都有一个自定义containerView。我想在containerView 上添加“n”个UIViews。我从视图控制器发送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
【问题讨论】:
-
利用自动布局而不是尝试计算尺寸。正如我对您的其他问题所评论的那样,
UIStackView可能会完全满足您的需求 不需要任何帧计算。 -
@DonMag 我仍然需要数据源信息。例如,我需要创建多少 UIView,然后将它们添加到 stackView。我的主要问题是我应该在什么时候将数据源信息从控制器发送到子 uiview。 'viewDidLayoutSubviews()'以外的任何东西
-
基本上,当使用自动布局约束时,您可以添加子视图并在
viewDidLoad()中设置约束。之后,自动布局会为您处理实际尺寸——无论设备大小、纵向还是横向都无关紧要。你还没有展示你想用 "animations" 做什么,但听起来你想在viewDidAppear()中启动任何动画。 -
@DonMag 完全理解。基本上我使用框架而不是 UIStackView 和自动布局的原因是我通过框架宽度和数组中的项目数来计算框架。我还使用了一个名为segments 的结构,它包含两个UIViews / 底部和顶部视图。底部和顶部视图都被赋予相同的帧,但顶部视图宽度为 0。然后我将顶部视图从 0 设置为底部视图宽度。看起来框架在我制作动画和做动画的方式上会更好。你怎么看?
标签: ios swift uiview datasource subview