我试图在我的代码中为封面视图设置动画。基本上,封面从屏幕外滑动(关闭)到屏幕上,并且在用户按下按钮之后,封面滑下(打开)一直在屏幕外。
将封面视图向上滑动到屏幕上并进入视图的代码工作正常。但是,将封面视图向下滑动到屏幕外的代码不起作用!盖子滑落的起始位置似乎是不正确的。封面按预期向下滑动,但开始太高,以至于动画结束它应该开始的地方。
我有一个错误的屏幕录制(显然减慢了动画速度,所以你可以看到错误的意思)。向下滑动的盖子应该从其向上滑动的原始位置向下滑动。 Link to recording。
任何人都可以在我的代码中发现我出错的地方吗?
func showScoresCover() {
verticalDistance = ScoresCoverView.frame.size.height
self.ScoresCoverView.frame.origin.y += verticalDistance
UIView.animate(
withDuration: 0.5,
delay: 0.25,
options: .curveEaseOut,
animations:
{ self.ScoresCoverView.frame.origin.y -= self.verticalDistance},
completion:
{ finished in
print("Score cover closed.")
})
}
func hideScoresCover() {
verticalDistance = ScoresCoverView.frame.size.height
UIView.animate(
withDuration: 0.5,
delay: 0.25,
options: .curveEaseIn,
animations:
{ self.ScoresCoverView.frame.origin.y += self.verticalDistance},
completion:
{ finished in
print("Score cover opened.")
})
}
嘿@Nickolans感谢你对这个问题的帮助。所以...我对此查询有一个奇怪的更新。我实现了你的代码,如果我有一个预先编程的按钮来激活showScoreCover和hideScoresCover,它就可以工作。事实证明,即使我的原始代码有效,但是,只有当我有一个预先编程的按钮来激活显示/隐藏功能时。
但是,我需要使用一个按钮来启动该功能,在该按钮中我以编程方式重新配置按钮的功能。我如何实现这一点是通过.addTarget和一些选择器,这些选择器将根据用户在游戏中的位置而有所不同。
无论如何,这是我的代码的样子:
self.continueButton.addTarget(self, action: #selector(self.hideScoresCover), for: UIControlEvents.touchUpInside)
self.continueButton.addTarget(self, action: #selector(self.startTeamB), for: UIControlEvents.touchUpInside)
最初我只使用了一个.addTarget并在startTeamB函数中包含了hideScoresCover()。这导致原始问题,即封面无法正确隐藏(在屏幕上开始太高)。所以我把它分成了上面两个.addTargets,这也导致了同样的问题。但是,如果我注释掉上面与startTeamB选择器相关的整个.addTarget行并保留与hideScoresCover相关的选择器,那么封面会显示并且完全隐藏,就像我想要的那样,动画是完美的。这意味着hideScoresCover()中的底层代码工作正常,但是在按下继续按钮时,hideScoresCover的运行方式出现了问题。
你知道为什么会这样吗?不知何故,只要有两个addTargets,或者当只有一个目标但startTeamB()中包含hideScoresCover()时,continueButton目标就会不正确地触发。
我很难过为什么会这样。 startTeamB()根本不是一个复杂的函数,因此不应该干扰hideScoresCover()。所以这导致我得出的结论是,当startButton除了将startTeamB作为目标之外还有一个单独的目标,或者当startTeamB本身包含hideScoresCover()时,它必须是continueButton触发hideScoresCover()的方式。当唯一的.addTarget是一个调用hidesScoresCover的选择器时,它是否正常工作?
@objc func startTeamB() {
self.UpdateTeam() //Just changes the team name
self.TeamBTimer() //Starts a timer to countdown teamB's remaining time
self.TeamAIndicator.isHidden = true //Just hides teamA image
self.TeamBIndicator.isHidden = false //Just shows teamB image
print("Hintify: ","-----Start Team B.")
}
我将它带入Xcode并自行设置。我相信问题可能在于您如何更改Y值,而不是更改视图图层y位置的原点更改。
以下代码有效,您可以随意使用!确保将框架更改为第一次启动时所需的框架。
class ViewController: UIViewController {
//Bool to keep track if view is open
var isOpen = false
var verticalDistance: CGFloat = 0
var ScoresCoverView = UIView()
var button = UIButton()
override func viewDidLoad() {
//Setup Score view
ScoresCoverView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.width)
ScoresCoverView.backgroundColor = .blue
view.addSubview(ScoresCoverView)
//Set vertical distance
verticalDistance = ScoresCoverView.frame.height
//TEST button to test view animations
button.frame = CGRect(x: 200, y: 500, width: 100, height: 100)
button.backgroundColor = .purple
button.addTarget(self, action: #selector(hasBeenFired), for: .touchUpInside)
self.view.addSubview(button)
}
//When button pressed
@objc func hasBeenFired() {
if isOpen {
self.hideScoresCover()
self.isOpen = false
} else {
self.showScoresCover()
self.isOpen = true
}
}
//Show
func showScoresCover() {
self.ScoresCoverView.isHidden = false
UIView.animate(withDuration: 0.5, delay: 0.25, options: .curveEaseOut, animations: {
self.ScoresCoverView.layer.position.y -= self.verticalDistance
}) { (finished) in
print("Score cover closed.")
}
}
//Hide
func hideScoresCover() {
UIView.animate(withDuration: 0.5, delay: 0.25, options: .curveEaseIn, animations: {
self.ScoresCoverView.layer.position.y += self.verticalDistance
}) { (finished) in
self.ScoresCoverView.isHidden = true
print("Score cover Opened.")
}
}
}
编辑
如果您想更改按钮的功能,请确保在添加新目标之前删除之前的目标。
例如,如果要从show / hide切换到teamB,请删除show / hide并添加teamB--反之亦然。
首次启动时,添加初始目标:
self.continueButton.addTarget(self, action: #selector(self.hideScoresCover), for: UIControlEvents.touchUpInside)
切换到startTeamB:
self.continueButton.removeTarget(self, action: #selector(self.hideScoresCover), for: UIControlEvents.touchUpInside)
self.continueButton.addTarget(self, action: #selector(self.startTeamB), for: UIControlEvents.touchUpInside)
切换到hideScoreCover:
self.continueButton.removeTarget(self, action: #selector(self.startTeamB), for: UIControlEvents.touchUpInside)
self.continueButton.addTarget(self, action: #selector(self.hideScoresCover), for: UIControlEvents.touchUpInside)
我只想说一件事,也许这里不需要+=
。
func showScoresCover() {
verticalDistance = ScoresCoverView.frame.size.height
self.ScoresCoverView.frame.origin.y += verticalDistance
UIView.animate(
withDuration: 0.5,
delay: 0.25,
options: .curveEaseOut,
animations:
{ self.ScoresCoverView.frame.origin.y -= self.verticalDistance},
completion:
{ finished in
print("Score cover closed.")
})
}
应该
`self.ScoresCoverView.frame.origin.y = verticalDistance`