- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
更新:我添加了一个显式调用,以在转换的完成处理程序中设置“to” View 的框架。 这解决了“问题”,但没有回答有关为什么帧在隐藏时发生变化的问题。这是新的动画调用。注意 - 我通过创建一个处理 spanSuperView() 和动画的函数稍微清理了代码,所以这与原始代码不完全匹配。要点已更新。我希望它可以帮助某人,也许其他人知道为什么。
这是多次运行的动画:
func animateView(_ new: UIView) {
UIView.transition(from: self.currentView, to: new, duration: 1, options: UIViewAnimationOptions.transitionFlipFromRight, completion: { finished in
new.spanSuperView()
new.isHidden = false
self.currentView.isHidden = true
self.currentView = new
self.container.layoutIfNeeded()
})
}
动画现在在按钮切换方法中调用,而不是重复:
@objc func viewChange(_ sender: UIButton) {
print(sender.tag)
switch sender.tag {
case 1 :
print("should look at view1")
print(currentView)
animateView(viewone)
case 2 :
print(currentView)
animateView(viewtwo)
case 3 :
print(currentView)
animateView(viewthree)
case 4 :
print(currentView)
animateView(viewfour)
default:
animateView(viewone)
}
}
这里是spanSuperView():
extension UIView {
func spanSuperView() {
guard superview != nil else { return }
self.topAnchor.constraint(equalTo: superview!.topAnchor).isActive = true
self.leadingAnchor.constraint(equalTo: superview!.leadingAnchor).isActive = true
self.widthAnchor.constraint(equalTo: superview!.widthAnchor, multiplier: 1.0).isActive = true
self.heightAnchor.constraint(equalTo: superview!.heightAnchor, multiplier: 1.0).isActive = true
self.translatesAutoresizingMaskIntoConstraints = false
}
}
另一个更新:如果没有 UIView.transition (只是显示 | 隐藏),则根本不会出现该问题:
func animateView(_ new: UIView) {
if new == currentView { return }
new.spanSuperView()
new.isHidden = false
self.currentView.isHidden = true
self.currentView = new
}
原始问题:我正在尝试创建一个带有动画 subview 的 View ,用户可以通过单击按钮在它们之间进行切换。第一次显示 View 时效果很好,但 subview 的框架在第一次后发生变化,然后 View 在没有 subview 的情况下进行动画处理。
这是 Playground 的代码。我还创建了一个 GIST
import UIKit
import PlaygroundSupport
class ButtonRow: UIView {
var button1 = UIButton()
var button2 = UIButton()
var button3 = UIButton()
var button4 = UIButton()
var stackView = UIStackView()
func updateButtonLabels(_ texts:[String]? = ["1", "2", "3", "4"]) {
guard let texts = texts else { return }
let buttons = [button1, button2, button3, button4]
var i = 0
for btn in buttons {
btn.setTitle(texts[i], for: .normal)
i += 1
}
}
override init(frame: CGRect){
super.init(frame: frame)
makeStack()
stackView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(stackView)
stackView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1.0).isActive = true
stackView.heightAnchor.constraint(equalTo: self.heightAnchor, multiplier: 1.0).isActive = true
stackView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
}
func makeStack() {
let buttons = [button1, button2, button3, button4]
for btn in buttons {
btn.backgroundColor = .gray
btn.setTitleColor(.white, for: .normal)
btn.titleLabel?.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.headline)
btn.translatesAutoresizingMaskIntoConstraints = false
}
stackView = UIStackView(arrangedSubviews: buttons)
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.alignment = .fill
stackView.spacing = 10
}
override func layoutSubviews() {
super.layoutSubviews()
stackView.frame = bounds
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyViewController : UIViewController {
// MARK: - Properties
var viewone = UIView()
var viewtwo = UIView()
var viewthree = UIView()
var viewfour = UIView()
var container = UIView()
var stackView = UIStackView()
var buttonRow = ButtonRow()
var currentView = UIView()
override func loadView() {
let view = UIView()
view.backgroundColor = .white
self.view = view
setupStack()
}
override func viewWillLayoutSubviews() {
print("will layout subviews")
//autolayout the stack view
let hSpacing: CGFloat = UIScreen.main.bounds.width/8
let wSpacing: CGFloat = UIScreen.main.bounds.width/10
if #available(iOS 11.0, *) {
let guide = self.view.safeAreaLayoutGuide
stackView.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: -wSpacing).isActive = true
stackView.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: wSpacing).isActive = true
stackView.topAnchor.constraint(equalTo: guide.topAnchor, constant: hSpacing).isActive = true
stackView.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: -hSpacing).isActive = true
}
else {
let margins = view.layoutMarginsGuide
stackView.trailingAnchor.constraint(equalTo: margins.trailingAnchor, constant: -wSpacing).isActive = true
stackView.leadingAnchor.constraint(equalTo: margins.leadingAnchor, constant: wSpacing).isActive = true
stackView.topAnchor.constraint(equalTo: margins.topAnchor, constant: hSpacing).isActive = true
stackView.bottomAnchor.constraint(equalTo: margins.bottomAnchor, constant: -hSpacing).isActive = true
}
}
func setupContainer() {
container.backgroundColor = .yellow
viewone.backgroundColor = .blue
viewtwo.backgroundColor = .red
viewthree.backgroundColor = .green
viewfour.backgroundColor = .black
for vl in [viewone, viewtwo, viewthree, viewfour] as [UIView] {
container.addSubview(vl)
vl.isHidden = true
vl.topAnchor.constraint(equalTo: container.topAnchor).isActive = true
vl.leadingAnchor.constraint(equalTo: container.leadingAnchor).isActive = true
vl.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 1.0).isActive = true
vl.heightAnchor.constraint(equalTo: container.heightAnchor, multiplier: 1.0).isActive = true
vl.translatesAutoresizingMaskIntoConstraints = false
}
currentView = viewone
viewone.isHidden = false
}
func setupButtons() {
buttonRow.updateButtonLabels()
var i = 1
for btn in [buttonRow.button1, buttonRow.button2, buttonRow.button3, buttonRow.button4] {
btn.tag = i
btn.addTarget(self, action: #selector(viewChange), for: .touchUpInside)
i += 1
}
}
func setupStack() {
setupButtons()
setupContainer()
stackView = UIStackView(arrangedSubviews: [container, buttonRow])
stackView.axis = .vertical
stackView.distribution = .fill
stackView.alignment = .fill
stackView.spacing = 10
stackView.translatesAutoresizingMaskIntoConstraints = false
// add some component constraints
let bHeight = buttonRow.heightAnchor.constraint(equalToConstant: 50)
stackView.addConstraints([bHeight])
view.addSubview(stackView)
}
// MARK: - Methods
@objc func viewChange(_ sender: UIButton) {
print(sender.tag)
switch sender.tag {
case 1 :
print("should look at view1")
print(currentView)
UIView.transition(from: self.currentView, to: self.viewone, duration: 1, options: UIViewAnimationOptions.transitionFlipFromRight, completion: nil)
currentView = viewone
viewone.isHidden = false
viewtwo.isHidden = true
viewthree.isHidden = true
viewfour.isHidden = true
case 2 :
print(currentView)
UIView.transition(from: self.currentView, to: self.viewtwo, duration: 1, options: UIViewAnimationOptions.transitionFlipFromRight, completion: nil)
currentView = viewtwo
viewone.isHidden = true
viewtwo.isHidden = false
viewthree.isHidden = true
viewfour.isHidden = true
case 3 :
print(currentView)
UIView.transition(from: self.currentView, to: self.viewthree, duration: 1, options: UIViewAnimationOptions.transitionFlipFromRight, completion: nil)
currentView = viewthree
viewone.isHidden = true
viewtwo.isHidden = true
viewthree.isHidden = false
viewfour.isHidden = true
case 4 :
print(currentView)
UIView.transition(from: self.currentView, to: self.viewfour, duration: 1, options: UIViewAnimationOptions.curveEaseInOut, completion: nil)
currentView = viewfour
viewone.isHidden = true
viewtwo.isHidden = true
viewthree.isHidden = true
viewfour.isHidden = false
default:
currentView = viewone
viewone.isHidden = false
viewtwo.isHidden = true
viewthree.isHidden = true
viewfour.isHidden = true
}
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
打印语句显示仍然识别出一个currentview,但它的框架从“frame = (0 0; 221 416)”更改为“frame = (-77 -96; 0 0)”:
will layout subviews
will layout subviews
1
should look at view1
<UIView: 0x7f7f42100630; frame = (0 0; 221 416); layer = <CALayer: 0x600000221440>>
2
<UIView: 0x7f7f42100630; frame = (0 0; 221 416); layer = <CALayer: 0x600000221440>>
3
<UIView: 0x7f7f421031f0; frame = (0 0; 221 416); layer = <CALayer: 0x600000221340>>
4
<UIView: 0x7f7f421033d0; frame = (0 0; 221 416); layer = <CALayer: 0x600000220140>>
1
should look at view1
<UIView: 0x7f7f421035b0; frame = (0 0; 221 416); layer = <CALayer: 0x600000220de0>>
2
<UIView: 0x7f7f42100630; frame = (-77 -96; 0 0); layer = <CALayer: 0x600000221440>>
3
<UIView: 0x7f7f421031f0; frame = (-77 -96; 0 0); layer = <CALayer: 0x600000221340>>
4
<UIView: 0x7f7f421033d0; frame = (-77 -96; 0 0); layer = <CALayer: 0x600000220140>>
注意:我创建了一个视频,但我似乎无法将其上传到 SO 或我的 Gist。
我不明白为什么框架会改变。给出了什么?
最佳答案
我认为每次你在 NSLayoutAnchor
上调用 constraint
时,你都会创建一个新的约束,所以在 2 次迭代之后,UIKit 无法解决这个问题我不会感到惊讶。不再有任何限制。
您应该尝试为 UIViewAlertForUnsatisfiableConstraints
添加符号断点,看看这是否是您的问题。
关于swift - 为什么UIView动画会改变View框架?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47300310/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!