Last active
November 15, 2017 22:14
-
-
Save monkeywithacupcake/b4a90f6bb6662637d7d4295aede94318 to your computer and use it in GitHub Desktop.
UIView animation moves frame after animate
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: A UIKit based Playground for presenting user interface | |
import UIKit | |
import PlaygroundSupport | |
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 | |
} | |
} | |
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.spanSuperView() | |
} | |
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 | |
func animateView(_ new: UIView) { | |
UIView.transition(from: self.currentView, to: new, duration: 1, options: UIViewAnimationOptions.transitionFlipFromRight, completion: { finished in | |
//new.frame = CGRect(x: 0, y: 0, width: 220, height: 220) | |
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: | |
canimateView(viewone) | |
} | |
} | |
} | |
// Present the view controller in the Live View window | |
PlaygroundPage.current.liveView = MyViewController() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This playground works for the first time a view is unhidden, but the frame bounds change and it does not work after the first time.