我正在尝试为代码中的封面视图制作动画。本质上,外盖从屏幕外滑到(关闭)屏幕,并且在用户按下按钮后,外盖在屏幕外一直滑下(打开)。
我的将封面视图向上滑动到屏幕上并进入视图的代码运行正常。但是,将封面视图向下滑动到屏幕之外的代码不起作用!盖子滑落的起始位置似乎不正确。封面会按预期的方式向下滑动,但开始时的位置过高,导致动画在应开始的位置结束。
我已经在屏幕上记录了操作中的错误(显然放慢了动画的速度,因此您可以看到错误的含义)。向下滑动的盖板应从其向上滑动的原始位置向下滑动。 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并将hideScoresCover()包含在startTeamB函数中。这导致了原始问题,其中盖子无法正确隐藏(在屏幕上开始过高)。因此,我将其分为上述两个.addTargets,这也导致了相同的问题。但是,如果我注释掉上面与startTeamB选择器相关的整个.addTarget行,并保留与hideScoresCover相关的选择器,那么将显示封面并按照我的意愿完全隐藏,该动画是完美的。这意味着hideScoresCover()中的基础代码可以正常工作,但是在按继续按钮时,以某种方式引起了hideScoresCover的运行方式的问题。
您知道为什么会这样吗?无论何时有两个addTarget,或者只有一个目标,但startTeamB()中包含hideScoresCover()时,continueButton目标都会不正确地触发。
我为为什么会如此而感到困惑。 startTeamB()根本不是一个复杂的函数,因此不应干扰hideScoresCover()。因此,这只能使我得出结论,当它既是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.")
}
答案 0 :(得分:0)
我将其带入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.")
}
}
}
编辑
如果您想更改按钮的功能,请确保在添加新目标之前删除先前的目标。
例如,如果要从显示/隐藏切换到 teamB,请 删除 显示/隐藏并添加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)
答案 1 :(得分:0)
我只想说一件事,也许+=
在这里不是必需的。
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`