我对Swift编码有点陌生,我想通过找到一些布局来训练自己,并尝试使用AutoLayout实现它们。
这是我试图实现的屏幕截图
https://i.imgur.com/9yzvnzp.png
这里需要的行为是在滚动时图片会逐渐消失,标题应该设置成这样
https://i.imgur.com/bLhyTGs.png
有人能帮我怎么做吗?
我应该使用滚动视图吗?UITableView?u集合视图?
最佳答案
我正在开发一个类似的应用程序。
所以,你要做的第一件事是为背景创建一个UIView
,也就是说,蓝色的部分显示了喷射器。此视图可以占据整个视图控制器。通过UIViewController
将其连接到您的IBOutlet
并将其命名为backgroundView
。
接下来,我们要在UIScrollView
上放置一个backgroundView
。此滚动视图应限制在超级视图的顶部、底部、前边和后边,以便覆盖整个视图控制器的框架。通过UIScrollView
将此UIViewController
连接到您的IBOutlet
并将其命名为scrollView
。另外,确保scrollView
的backgroundColor
设置为clear
。这样,我们就可以在backgroundView
下面看到scrollView
。
在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
、EVOLUTIONS
、MOVES
、HP
等的“内容视图”。因此,让我们添加另一个
UIView
作为scrollView
的子视图。通过SquirtleViewController
将其连接到IBOutlet
并将其命名为contentView
。现在,我们需要在
contentView
的上边缘和scrollView
的上边缘之间创建一个约束。此约束的常数必须等于backgroundView
内容的高度。这样,我们的contentView
就不会掩盖我们想从backgroundView
看到的东西。我们还应该将这个高度保存为backgroundViewContentHeight
,以便以后可以引用它。我们还需要
contentView
的leading
、trailing
和bottom
约束与它的superview的约束相等,即scrollView
。这些不需要通过IBOutlet
s连接。此外,给出
contentView
aheight
和width
约束,并通过contentViewHeight
将它们分别连接为contentViewWidth
和SquirtleViewController
。这将帮助我们以后设置IBOutlet
的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 {
}
现在,当
scrollView
布局其子视图时,我们要设置SquirtleViewController
和constant
的contentViewHeight
属性。这将为我们的contentViewWidth
设置contentSize
。我们希望我们的scrollView
只是我们的contentViewWidth
宽度的大小。不过,我们的SquirtleViewController
的view
会有点不同,因为这取决于我们的contentViewHeight
子视图的高度。对于这个例子,我们会说constant
的contentView
应该是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 {
}
从这里,您可以根据需要将子视图添加到
contentViewHeight
和constant
中,以便显示pokemon(backgroundView
)和pokemon的统计信息(contentView
)。但是,您仍然需要知道如何根据我们滚动了多少backgroundView
来更改contentView
的内容。这就是backgroundView
帮助我们解决问题的地方。scrollView
中有一个方法,每当我们的UIScrollViewDelegate
的UIScrollViewDelegate
发生变化时都会调用它。这基本上意味着每次我们更改scrollView
滚动的量时,都会调用此方法。在这个方法内部,我们可以交叉引用我们滚动的数量和背景视图的高度。当我们的
contentOffset.y
'sscrollView
接近我们的scrollView
内容的高度时,我们可以淡出喷射器的图像并淡入到一个简单地称为“喷射器”的contentOffset.y
中(如您的示例)。因此,在您的情况下,我建议添加一个
backgroundView
的喷射器作为UILabel
的子视图,并通过UIImage
作为contentView
连接它。IBOutlet
的框架应该部分位于pokemonImageView
之外(如您的示例中所示)。如果这样做,请确保pokemonImageView
的contentView
属性设置为contentView
。我还将添加一个
clipsToBounds
作为false
的子视图,并通过UILabel
asbackgroundView
将其连接到SquirtleViewController
。当我们的IBOutlet
视图加载时,我们应该将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 {
}
现在我们只需要在类扩展中添加
SquirtleViewController
方法。这个方法将告诉我们pokemonNameLabel.alpha
的scrollViewDidScroll
属性,以便我们知道滚动了多少。随着这个数字的增加,我们的α应该减少到零,我们的α应该增加到一。在这个方法中,我将把我们的
scrollView
除以contentOffset.y
的高度减去pokemonImageView
的高度。然后我们可以使用这个十进制设置我们各自的字母pokemonNameLabel
和scrollView.contentOffset.y
。您的代码现在应该如下所示:
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
收缩时,我们的pokemonNameLabel
将淡出,而我们的pokemonImageView
将淡入。两者之间会有一个点α值为0.5。您可以随意使用这个pokemonNameLabel
方法,使其最适合您。
关于swift - Swift-显示带有动画的标题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56992451/