首页 > 解决方案 > Swift - 显示带有动画的标题

问题描述

我对 Swift 编码有点陌生,我想通过寻找一些布局来训练自己并尝试使用 AutoLayout 来实现它们。

这是我尝试实现的屏幕截图

https://i.imgur.com/9yzvnzp.png

这里想要的行为是在滚动图片时应该消失并且标题应该像这样设置

https://i.imgur.com/bLhyTGs.png

有人可以帮我解决我应该怎么做吗?我应该使用 ScrollView 吗?界面视图?UICollectionView ?

标签: swiftuitableviewuicollectionviewuiscrollviewscrollview

解决方案


我实际上正在开发一个执行类似操作的应用程序。

在此处输入图像描述

因此,您要做的第一件事是UIView为背景创建一个,即显示 Squirtle 的蓝色部分。这个视图可以占据整个视图控制器。将其连接到您的UIViewControllerviaIBOutlet并调用它backgroundView

接下来,我们要放置一个UIScrollViewover backgroundView。这个滚动视图应该被限制在超级视图的顶部、底部、前导和后沿,以便它覆盖整个视图控制器的框架。将此连接UIScrollView到您的UIViewControllerviaIBOutlet并命名scrollView。此外,请确保scrollView'backgroundColor设置为clear。这样,我们就可以看到backgroundView我们的scrollView.

在您的内部UIViewController,您需要将scrollView'delegate 设置为selfinside of viewDidLoad。你UIViewController的代码现在应该是这样的:

class SquirtleViewController: UIViewController {
    @IBOutlet var backgroundView: UIView!
    @IBOutlet var scrollView: UIScrollView!

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
    }
}

extension SquirtleViewController: UIScrollViewDelegate {

}

我们稍后会设置委托方法scrollView。这些将帮助我们知道滚动视图何时开始滚动到SquirtleViewController.

现在,我们scrollView有一个清晰的背景,实际上并没有向我们的用户显示任何内容。这就是我们现在想要的。我们希望我们的顶部scrollView清晰,以便我们可以看到backgroundView它的后面,而我们的底部scrollView有另一个视图,即显示STATSEVOLUTIONSMOVESHP等的“内容视图”。

所以,让我们添加另一个UIView作为我们的scrollView. 将其连接到SquirtleViewControllerviaIBOutlet并命名contentView

现在,我们需要在contentView' 顶部边缘和scrollView' 顶部边缘之间创建一个约束。此约束的常数需要等于backgroundView' 内容的高度。这样,我们contentView就不会掩盖我们想从中看到的内容backgroundView。我们还应该保存这个高度,backgroundViewContentHeight以便我们以后可以参考它。

我们还需要contentView's leading, trailing, andbottom约束与它的父视图相同,即scrollView。这些不需要通过IBOutlets 连接。

另外,给出contentView一个heightandwidth约束并将它们contentViewHeight分别连接contentViewWidthSquirtleViewControllervia IBOutlet。这将帮助我们设置contentSize我们scrollView以后的。

您的代码现在应该如下所示:

class SquirtleViewController: UIViewController {
    @IBOutlet var backgroundView: UIView!
    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var contentView: UIView!

    //New lines of code
    //Our constraints
    @IBOutlet var contentViewTop: NSLayoutConstraint!
    @IBOutlet var contentViewHeight: NSLayoutConstraint!
    @IBOutlet var contentViewWidth: NSLayoutConstraint!

    var backgroundViewContentHeight = 400

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
    }
}

extension SquirtleViewController: UIScrollViewDelegate {

}

现在,当SquirtleViewController布置其子视图时,我们将要设置 和的constant属性。这将为我们的. 我们希望我们简单地成为我们的宽度的大小。我们的 's会有点不同,因为它取决于我们的子视图的高度。对于这个例子,我们会说's应该是 1200。代码现在应该是这样的:contentViewHeightcontentViewWidthcontentSizescrollViewcontentViewWidthSquirtleViewControllerviewcontentViewHeightconstantcontentViewcontentViewHeightconstant

class SquirtleViewController: UIViewController {
    @IBOutlet var backgroundView: UIView!
    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var contentView: UIView!

    //Our constraints
    @IBOutlet var contentViewTop: NSLayoutConstraint!
    @IBOutlet var contentViewHeight: NSLayoutConstraint!
    @IBOutlet var contentViewWidth: NSLayoutConstraint!

    var backgroundViewContentHeight = 400

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self
    }

    //New lines of code
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        contentViewWidth.constant = view.frame.width
        contentViewHeight.constant = 1200
    }
}

extension SquirtleViewController: UIScrollViewDelegate {

}

从这里,您可以将子视图添加到backgroundViewcontentView认为合适的位置,以显示口袋妖怪 ( backgroundView) 以及口袋妖怪的统计数据 ( contentView)。但是,您仍然需要知道如何backgroundView根据我们滚动了多少来更改您的内容scrollView。这就是UIScrollViewDelegate帮助我们的地方。

UIScrollViewDelegate每次更改时都会调用其中scrollView的一个方法。contentOffset.y这基本上意味着每次我们更改scrollView滚动量时,都会调用此方法。

在这个方法中,我们可以交叉引用我们滚动的量和背景视图的高度。当我们scrollView的内容contentOffset.y接近我们的内容的高度时backgroundView,我们可以淡出 Squirtle 的图像并淡入一个UILabel简单的“Squirtle”(如您的示例中)。

所以,在你的情况下,我建议添加一个UIImageSquirtle 作为子视图并通过ascontentView连接它。应该将其框架部分放在外部(如您的示例中)。如果这样做,请确保' 的属性设置为。IBOutletpokemonImageViewpokemonImageViewcontentViewcontentViewclipsToBoundsfalse

我还将添加 aUILabel作为子视图backgroundView并将其连接到SquirtleViewControllervia IBOutletas pokemonNameLabel。当我们SquirtleViewController的视图加载时,我们应该设置pokemonNameLabel.alpha为零,以便它最初是隐藏的。

您的代码现在应该如下所示:

class SquirtleViewController: UIViewController {
    @IBOutlet var backgroundView: UIView!

    //New line of code
    @IBOutlet var pokemonNameLabel: UILabel!
    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var contentView: UIView!

    //New line of code
    @IBOutlet var pokemonImageView: UIImageView!

    //Our constraints
    @IBOutlet var contentViewTop: NSLayoutConstraint!
    @IBOutlet var contentViewHeight: NSLayoutConstraint!
    @IBOutlet var contentViewWidth: NSLayoutConstraint!

    var backgroundViewContentHeight = 400

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self

        //New line of code
        pokemonNameLabel.alpha = 0
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        contentViewWidth.constant = view.frame.width
        contentViewHeight.constant = 1200
    }
}

extension SquirtleViewController: UIScrollViewDelegate {

}

现在我们只需要在scrollViewDidScroll类扩展中添加方法。这是告诉我们scrollView'contentOffset.y属性的方法,以便我们知道我们滚动了多少。随着这个数字的增加,我们pokemonImageView的 alpha 应该减小到零,我们pokemonNameLabel的 alpha 应该增加到 1。

在这个方法中,我将我们除以我们scrollView.contentOffset.y的高度backgroundView减去pokemonNameLabel. 然后我们可以使用这个小数来设置我们各自的 alphapokemonImageViewpokemonNameLabel

您的代码现在应该如下所示:

class SquirtleViewController: UIViewController {
    @IBOutlet var backgroundView: UIView!

    //New line of code
    @IBOutlet var pokemonNameLabel: UILabel!
    @IBOutlet var scrollView: UIScrollView!
    @IBOutlet var contentView: UIView!

    //New line of code
    @IBOutlet var pokemonImageView: UIImageView!

    //Our constraints
    @IBOutlet var contentViewTop: NSLayoutConstraint!
    @IBOutlet var contentViewHeight: NSLayoutConstraint!
    @IBOutlet var contentViewWidth: NSLayoutConstraint!

    var backgroundViewContentHeight = 400

    override func viewDidLoad() {
        super.viewDidLoad()
        scrollView.delegate = self

        //New line of code
        pokemonNameLabel.alpha = 0
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        contentViewWidth.constant = view.frame.width
        contentViewHeight.constant = 1200
    }
}

extension SquirtleViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        //Subtracting contentView.frame.height from scrollView.frame.height
        let alphaDecimal = scrollView.contentOffset.y / (backgroundViewContentHeight - pokemonNameLabel.frame.height)
        pokemonNameLabel.alpha = alphaDecimal
        pokemonImageView.alpha = 1 - alphaDecimal
    }
}

现在,当我们向上滚动并可以看到backgroundView收缩时,我们的pokemonImageView意志会淡出,我们的pokemonNameLabel意志会淡入。将有一个介于两者之间的点,两者的 alpha 均为 0.5。您可以随意使用此scrollViewDidScroll方法,以使此方法最适合您。


推荐阅读