如何在更改 UIView 大小时应用动画? + 斯威夫特 5
Posted
技术标签:
【中文标题】如何在更改 UIView 大小时应用动画? + 斯威夫特 5【英文标题】:How to Apply Animation while changing UIView size? + Swift 5 【发布时间】:2020-06-24 12:19:08 【问题描述】:我是 ios 开发新手,我在 UIView 中有两个按钮,当用户选择选项 portrait
或 landscape
时,更改 UIView 重新调整大小并更改背景颜色,我需要为那个过程。
例如:
用户选择portrait
,然后用户可以看到红色的 UIVIew。单击landscape
选项后,应该开始动画,看起来像,红色图像出现在前面并更改landscape
模式的大小(更改高度和宽度),然后转到上一个位置并将颜色更改为绿色。我在代码中添加了小的 UIView 动画,它有助于您确定我们应该从哪里开始动画并完成它。如果有人知道如何正确操作,请告诉我并感谢您的帮助。请参考下面的代码
import UIKit
class ViewController: UIViewController
let portraitWidth : CGFloat = 400
let portraitHeight : CGFloat = 500
let landscapeWidth : CGFloat = 700
let landscapeHeight : CGFloat = 400
var mainView: UIView!
var mainStackView: UIStackView!
let segment: UISegmentedControl =
let segementControl = UISegmentedControl()
return segementControl
()
override func viewDidLoad()
super.viewDidLoad()
self.view.translatesAutoresizingMaskIntoConstraints = false
mainStackView = UIStackView()
mainStackView.axis = .vertical
mainStackView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.alignment = .center
mainStackView.distribution = .equalCentering
self.view.addSubview(mainStackView)
self.segment.insertSegment(withTitle: "Portrait", at: 0, animated: false)
self.segment.insertSegment(withTitle: "Landscape", at: 1, animated: false)
self.segment.selectedSegmentIndex = 0
self.segment.addTarget(self, action: #selector(changeOrientation(_:)), for: .valueChanged)
self.segment.translatesAutoresizingMaskIntoConstraints = false
self.segment.selectedSegmentIndex = 0
mainStackView.addArrangedSubview(self.segment)
let safeAreaLayoutGuide = self.view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
self.mainStackView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 20),
self.mainStackView.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor, constant: 0),
])
NSLayoutConstraint.activate([
self.segment.heightAnchor.constraint(equalToConstant: 35),
self.segment.widthAnchor.constraint(equalToConstant: 300)
])
mainView = UIView(frame: .zero)
mainView.translatesAutoresizingMaskIntoConstraints = false
mainStackView.addArrangedSubview(mainView)
mainView.backgroundColor = UIColor.red
NSLayoutConstraint.activate([
mainView.heightAnchor.constraint(equalToConstant: portraitHeight),
mainView.widthAnchor.constraint(equalToConstant: portraitWidth),
mainView.topAnchor.constraint(equalTo: segment.bottomAnchor, constant: 30)
])
@IBAction func changeOrientation(_ sender: UISegmentedControl)
self.mainView.constraints.forEach (constraint) in
self.mainView.removeConstraint(constraint)
UIView.animate(withDuration: 1.0)
if (sender.selectedSegmentIndex == 0)
self.mainView.backgroundColor = UIColor.red
NSLayoutConstraint.activate([
self.mainView.heightAnchor.constraint(equalToConstant: self.portraitHeight),
self.mainView.widthAnchor.constraint(equalToConstant: self.portraitWidth),
self.mainView.topAnchor.constraint(equalTo: self.segment.bottomAnchor, constant: 30)
])
else
self.mainView.backgroundColor = UIColor.green
NSLayoutConstraint.activate([
self.mainView.heightAnchor.constraint(equalToConstant: self.landscapeHeight),
self.mainView.widthAnchor.constraint(equalToConstant: self.landscapeWidth),
self.mainView.topAnchor.constraint(equalTo: self.segment.bottomAnchor, constant: 30)
])
更新逻辑
@IBAction func changeOrientation(_ sender: UISegmentedControl)
UIView.animate(withDuration: 4.0)
if (sender.selectedSegmentIndex == 0)
self.mainView.backgroundColor = UIColor.red
self.widthConstraint.constant = self.portraitWidth
self.heightConstraint.constant = self.portraitWidth
else
self.mainView.backgroundColor = UIColor.green
self.widthConstraint.constant = self.landscapeWidth
self.heightConstraint.constant = self.landscapeHeight
self.mainView.layoutIfNeeded()
【问题讨论】:
仅供参考,viewDidLoad 和其他地方的所有“自我”都没有任何目的。 @Fattie 是的,为了测试,我已经在 viewDidLoad 方法下添加了所有这些,我想这是在这里提问的简单方法,所有东西都在一个方法中:) 嗨,迪丽热巴!我已经给出了答案。为了清楚我的意思是你可以删除“自我”。那里。self.view.addSubview
是错误的。它应该是view.addSubview
。祝你好运!
【参考方案1】:
有可能,基本问题是:
• 不可能在一个约束和另一个约束之间设置一个实际的变化。
要更改大小或形状,您只需为约束的长度设置动画即可。
在您学习的同时,我真的强烈建议您简单地为约束设置动画。
因此,不要尝试“更改”约束,只需为其中一个或另一个的长度设置动画。
yourConstraint.constant = 99 // it's that easy
我也真心建议你把它放在故事板上。
你必须先掌握它!
堆栈视图也没有任何理由,现在摆脱它。
只要有一个出口
@IBOutlet var yourConstraint: NSLayoutConstraint!
和动画
UIView.animateWithDuration(4.0)
self.yourConstraint.constant = 666
self.view.layoutIfNeeded()
请务必在 Stack Overflow 中搜索“iOS 动画约束”,因为要学习的内容很多。
在情节提要上执行此操作,这么简单的事情最多需要 20 秒。一旦你掌握了故事板,只有在有理由的情况下才能继续编写代码
忘记堆栈视图
只需对约束的常量进行动画处理,即可更改大小、形状或您喜欢的任何内容。
请务必在 SO 和其他网站上搜索许多精彩的文章“iOS 中的动画约束”!
【讨论】:
感谢您的评论和建议。我检查了这段代码,它与上面代码中的现有动画非常相似:),没什么特别的,我可以将动画应用到正常方式,但在这里我需要应用一些自定义动画。我认为您没有正确回答我的问题,当您有空时,如果您能再次查看我的任务描述,不胜感激:) 感谢您的帮助 嗨@DileepaChandrasekara,如果我不理解,对不起。您是否意识到您忘记调用 layoutIfNeeded ???例如,***.com/a/36626232/294884 在某些情况下您确实需要重新布局 我调用了它,但什么也没发生 :(,我试图找到一篇文章如何在 swift 5.1 中的动画中更改约束常量 我根据您的评论更新了逻辑,请在更新的逻辑标题下检查它 @DileepaChandrasekara 您无法将 CHANGE 从一个约束设置为另一个约束。以上是关于如何在更改 UIView 大小时应用动画? + 斯威夫特 5的主要内容,如果未能解决你的问题,请参考以下文章