Swift - 显示带有动画的标题
Posted
技术标签:
【中文标题】Swift - 显示带有动画的标题【英文标题】:Swift - Display header with animation 【发布时间】:2019-07-11 15:15:34 【问题描述】:我对 Swift 编码有点陌生,我想通过寻找一些布局来训练自己并尝试使用 AutoLayout 来实现它们。
这是我尝试实现的屏幕截图
https://i.imgur.com/9yzvnzp.png
这里想要的行为是在滚动图片时应该消失并且标题应该这样设置
https://i.imgur.com/bLhyTGs.png
有人可以帮我解决这个问题吗? 我应该使用 ScrollView 吗?界面视图? UICollectionView ?
【问题讨论】:
【参考方案1】:我实际上正在开发一个做类似事情的应用程序。
所以,您要做的第一件事是为背景创建一个UIView
,即显示 Squirtle 的蓝色部分。这个视图可以占据整个视图控制器。通过IBOutlet
将其连接到您的UIViewController
并调用它backgroundView
。
接下来,我们要在backgroundView
上放置一个UIScrollView
。这个滚动视图应该被限制在超级视图的顶部、底部、前导和后沿,以便它覆盖整个视图控制器的框架。通过IBOutlet
将此UIScrollView
连接到您的UIViewController
并将其命名为scrollView
。另外,确保scrollView
的backgroundColor
设置为clear
。这样,我们就可以在scrollView
下方看到backgroundView
。
在您的UIViewController
中,您需要将scrollView
的委托设置为self
内部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
的底部有另一个视图,即显示STATS
、@987654351 的“内容视图” @、MOVES
、HP
等
所以,让我们添加另一个UIView
作为scrollView
的子视图。通过IBOutlet
将其连接到SquirtleViewController
并将其命名为contentView
。
现在,我们需要在contentView
的上边缘和scrollView
的上边缘之间创建一个约束。这个约束的常数需要等于backgroundView
的内容的高度。这样,我们的contentView
就不会掩盖我们想从backgroundView
看到的内容。我们还应该将此高度保存为backgroundViewContentHeight
,以便我们以后可以引用它。
我们还需要contentView
的leading
、trailing
和bottom
约束等于其父视图的约束,即scrollView
。这些不需要通过IBOutlet
s 连接。
另外,给contentView
一个height
和width
约束,并将它们分别作为contentViewHeight
和contentViewWidth
通过IBOutlet
连接到SquirtleViewController
。这将有助于我们稍后设置scrollView
的contentSize
。
您的代码现在应该如下所示:
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
布置其子视图时,我们将要设置contentViewHeight
和contentViewWidth
的constant
属性。这将为我们的scrollView
设置一个contentSize
。我们希望contentViewWidth
的大小与SquirtleViewController
的view
的宽度相同。我们的contentViewHeight
的constant
会有点不同,因为它取决于我们contentView
的子视图的高度。对于这个例子,我们会说 contentViewHeight
的 constant
应该是 1200。代码现在应该是这样的:
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
从这里,您可以根据需要向backgroundView
和contentView
添加子视图,以显示口袋妖怪 (backgroundView
) 以及口袋妖怪的统计数据 (contentView
)。但是,您仍然需要知道如何根据我们滚动scrollView
的次数来更改backgroundView
的内容。这就是UIScrollViewDelegate
帮助我们的地方。
UIScrollViewDelegate
中有一个方法,每次我们的scrollView
的contentOffset.y
更改时都会调用该方法。这基本上意味着每次我们更改 scrollView
的滚动量时,都会调用此方法。
在这个方法中,我们可以交叉引用我们滚动的量和背景视图的高度。当我们的scrollView
的contentOffset.y
接近我们backgroundView
的内容的高度时,我们可以淡出Squirtle 的图像并淡入简单地说“Squirtle”的UILabel
(就像在你的例子中一样)。
因此,在您的情况下,我建议将 Squirtle 的 UIImage
添加为 contentView
的子视图,并通过 IBOutlet
将其连接为 pokemonImageView
。 pokemonImageView
的框架应部分位于 contentView
之外(如您的示例中所示)。如果这样做,请确保 contentView
的 clipsToBounds
属性设置为 false
。
我还将添加一个UILabel
作为backgroundView
的子视图,并通过IBOutlet
作为pokemonNameLabel
将其连接到SquirtleViewController
。当我们的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
的高度。然后我们可以使用这个小数来设置我们各自的 alphas pokemonImageView
和 pokemonNameLabel
。
您的代码现在应该如下所示:
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
将淡入。在两者之间会有一个点0.5的阿尔法。您可以随意使用此 scrollViewDidScroll
方法,以使其最适合您。
【讨论】:
@ImadBenAbdeslam 让我知道它是怎么回事。我知道它有很多内容,我试图让它尽可能清楚以上是关于Swift - 显示带有动画的标题的主要内容,如果未能解决你的问题,请参考以下文章
(Swift)如何通过重新加载 UITableView 根据 UITextfield 输入(动画)显示/隐藏单元格?