比例高度值取自xib文件,而不是来自设备

时间:2018-01-11 15:19:13

标签: ios iphone swift xcode

这是我第一次面对这个陌生人的问题。我使用UIViewController文件创建了XIB。屏幕有两个视图viewA和viewB。 viewA具有top = 0leading = 0trailing = 0这些值。 viewA.height = safeArea.height/2top = 0。 viewB约束为leading = 0trailing = 0bottom = 0viewA。在view内,我有一个名为viewAbackground的{​​{1}},top = 0leading = 0trailing = 0bottom = 0限制其容器( viewA)我在labels中也有一些viewA。我使用此viewAbackground添加gradient,因为如果我将其直接添加到viewA,它会出现在标签前面。这是我添加渐变的方式:

func createGradientLayer(theView: UIView) {
    let gradientLayer = CAGradientLayer()
    gradientLayer.frame = theView.frame
    gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
    gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
    gradientLayer.colors = [UIColor(hexString: Colors.startColor)?.cgColor, UIColor(hexString: Colors.endColor)?.cgColor]
    //add the gradient to the view
    theView.layer.addSublayer(gradientLayer)
}

然后在viewDidLoad中,我调用createGradientLayer(theView: viewA)

添加了gradient,但问题是它与size的{​​{1}}不同。在尝试了解错误的几个小时之后,我发现应用的viewA值与我在size device中选择的interface Builder相同不是我的设备屏幕的值。例如:如果我在view as xib的{​​{1}}中,当我在view as中运行时,我的iPhone SE大小为iPhone 6 gradient中的viewA。 我有iPhone SE 9.2,我正在使用Xcode

任何人都可以解释我为什么会遇到这个尺码问题吗?

编辑更多信息:这是视图的层次结构。 Swift 4ScrollView <- MainView <- viewA and viewB高度等于safeArea高度。 scrollView的实用程序适用于iPhone 4等小型设备。在这种情况下,我为mainView提供了一个定义的高度值,以获得滚动效果。

2 个答案:

答案 0 :(得分:0)

此问题与UIViewController生命周期的误解有关。

ViewDidLoad - 在创建类并从xib加载时调用。所有视图都将具有您在xib中设置的大小。

ViewWillAppear - 在你的观点出现之前调用。此时,您的所有视图都将具有正确的大小,因此您可以使用它们的大小和位置。

此外,CALayer不支持自动调整大小,因此,您可能需要在didLayoutSubviews更新其大小。

答案 1 :(得分:0)

当您从xib或storyboard加载视图时,布局将与加载的内容相匹配。正如您所注意到的那样,它不一定与它正在运行的设备相同。

因此,在viewDidLoad中,您将从数据中加载大小。

在第一次调用viewWillAppear时,您会看到相同的尺寸。

每次视图边界发生变化时都会调用

viewDidLayoutSubviews。这将是第一次获得您正在运行的设备所期望的视图的机会。

请注意,因为每次调用此方法时都不想添加渐变。但是,如果尺寸因设备旋转而发生变化,您可能需要更新它。

<强>更新 由于您使用的是滚动视图,因此viewDidLayoutSubviews可能无法报告正确的值。可能是SDK中的错误。您可以尝试从viewDidAppear获取正确的值,或者如果为时已晚,请尝试以下解决方案。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    scrollView.setNeedsLayout()
    scrollView.layoutIfNeeded()
    createGradientLayer(theView: viewA)
}