提问人:Philipp 提问时间:9/13/2023 最后编辑:Philipp 更新时间:9/15/2023 访问量:47
对 UIImageView 高度和宽度更改进行动画处理
Animate UIImageView height and width changes
问:
我的目标是对从左上角到视图中心的 UIImageView 过渡进行动画处理。它还必须将其宽度和高度更改为屏幕宽度,并将角半径更改为零。
如何修改以下代码,以便 UIImageView 更改其宽度和高度:
private func imageAnimates() {
UIView.animate(
withDuration: 0.5,
delay: 0.0,
options: .curveLinear
) {
self.userImage.layer.cornerRadius = 0
self.userImage.center = CGPoint(x: self.view.center.x, y: self.view.center.y)
} completion: { finished in
print("Image animated")
}
}
UPD:在 vaibhav sharma 的回答之后,我将代码更新为:
UIView.animate(
withDuration: 0.5,
delay: 0.0,
options: .curveLinear
) {
self.userImage.alpha = 1.0
self.userImage.layer.cornerRadius = 0
self.userImage.frame = CGRect(
x: (screenWidth - finalWidth) / 2,
y: (self.view.frame.size.height - finalHeight) / 2,
width: finalWidth,
height: finalHeight
)
} completion: { finished in
print("Image animated")
}
但我得到的结果不是我所期望的。这是一段屏幕录像:https://sendvid.com/i1fxbf0y。现在,图像似乎从左上角的小图片变为原始帧和位置。它甚至没有移动到中心。
答:
0赞
vaibhav sharma
9/13/2023
#1
根据我的理解,可能是我错了,请尝试
private func imageAnimates() {
// Calculate the final width and height to match the screen width
let screenWidth = self.view.frame.size.width
let finalWidth = screenWidth
let finalHeight = screenWidth * (self.userImage.frame.size.height / self.userImage.frame.size.width)
UIView.animate(
withDuration: 0.5,
delay: 0.0,
options: .curveLinear
) {
self.userImage.alpha = 1.0
self.userImage.layer.cornerRadius = 0
self.userImage.frame = CGRect(
x: (self.view.frame.size.width - finalWidth) / 2,
y: (self.view.frame.size.height - finalHeight) / 2,
width: finalWidth,
height: finalHeight
)
} completion: { finished in
print("Image animated")
}
}
- 请看以下几点:
根据屏幕宽度计算 finalWidth 和 finalHeight,同时保持原始图像的纵横比。
将 UIImageView 的 frame 属性设置为计算出的 finalWidth 和 finalHeight,并将其置于屏幕的中心。
评论
0赞
Philipp
9/13/2023
尝试使用代码,但结果与我预期的不同。看看我的问题更新。
0赞
Philipp
9/13/2023
如果有帮助,这是我的完整项目: github.com/lord-anonymoose/social-media-app/tree/feature-8
0赞
Philipp
9/13/2023
动画在 ProfileViewController 中使用
1赞
DonMag
9/15/2023
#2
你需要从*简单开始 - 只处理这个图像视图动画,直到你让它正常工作。然后将其添加到复杂的控制器中。
您不能“混合搭配”约束和直接帧设置。UIKit 将自动重置框架以匹配约束。
相反,请仅对视图使用框架设置...您可以将自动布局约束用于其他所有内容。userImage
所以,看看这个 - 点击任意位置以显示和增长或缩小和隐藏图像视图:
class ProfileViewController: UIViewController {
private lazy var userImage: UIImageView = {
//let imageView = UIImageView(image: UIImage(named: me.login))
// I don't have your "me.login" so let's use SF Symbol
let imageView = UIImageView()
if let img = UIImage(systemName: "person.fill") {
imageView.image = img
}
imageView.layer.cornerRadius = 45
imageView.clipsToBounds = true
// we're going to set the frame directly, so
// use true (it's the default so we don't really need to set it)
imageView.translatesAutoresizingMaskIntoConstraints = true
imageView.alpha = 0.0
// while we're designing this,
// use a backgroundColor so we can see the framing
imageView.backgroundColor = .red
return imageView
}()
// these will be update in viewDidLayoutSubviews()
// when we know the view frame and safeAreaInsets
private var userImageStartFrame: CGRect = .zero
private var userImageFinalFrame: CGRect = .zero
private var screenWidth: CGFloat = 0.0
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// we'll adjust the origin in viewDidLayoutSubviews()
userImageStartFrame = CGRect(x: 0.0, y: 0.0, width: 90.0, height: 90.0)
view.addSubview(userImage)
// do NOT set constraints on userImage !!!
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// viewDidLayoutSubviews() will be called many times, so
// only set the userImage view frames when the view width changes
if screenWidth != view.frame.width {
screenWidth = view.frame.width
// get the safe area rect
let r: CGRect = self.view.bounds.inset(by:self.view.safeAreaInsets)
userImageStartFrame.origin = r.origin
// let's make the large-center frame 90% of the safe area width
let finalWidth: CGFloat = r.width * 0.9
userImageFinalFrame = CGRect(
x: r.origin.x + ((r.width - finalWidth) * 0.5),
y: r.origin.y + ((r.height - finalWidth) * 0.5),
width: finalWidth, height: finalWidth
)
userImage.frame = userImageStartFrame
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
UIView.animate(
withDuration: 0.5,
delay: 0.0,
options: .curveLinear
) {
//self.backgroundBlur.alpha = 0.5
//self.blurCloseButton.alpha = 1.0
if self.userImage.alpha == 0.0 {
// userImage is currently transparent (alpha: 0.0)
// so we want to show it
self.userImage.alpha = 1.0
self.userImage.layer.cornerRadius = 0
self.userImage.frame = self.userImageFinalFrame
} else {
self.userImage.alpha = 0.0
self.userImage.layer.cornerRadius = 45
self.userImage.frame = self.userImageStartFrame
}
} completion: { finished in
print("Background blur appeared")
}
}
}
评论
0赞
Philipp
9/19/2023
谢谢你的解释!我不知道不能同时使用 NSLayoutContraint 和框架。它真的很有帮助!
评论