Использование Swift 4 и Xcode 10.1
Моя цель - использовать стек массивов для отслеживания моих UIViewControllers, когда я анимирую между ними.Я получил большую часть его работы, однако, когда я перехожу ViewController в представление во второй раз, он, кажется, меняет местами с текущим контроллером представления ниже.
Базовая настройка (раскадровка) - это UIViewController, которыйимеет ContainerView (MainContainer) и 4 отдельных ViewControllers (VC1, VC2, VC3, VC4).У каждого VC также есть идентификатор восстановления, чтобы я мог распечатать его и отследить положение в массиве стека.
В начале я отображаю VC1, затем использую кнопки для проверки обработки каждого VC.
Вот код:
@IBOutlet weak var MainContainer: UIView!
var vc1:UIViewController!
var vc2:UIViewController!
var vc3:UIViewController!
var vc4:UIViewController!
var vcStack = Stack<UIViewController>()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
vc1 = self.storyboard?.instantiateViewController(withIdentifier: "VC1")
vc2 = self.storyboard?.instantiateViewController(withIdentifier: "VC2")
vc3 = self.storyboard?.instantiateViewController(withIdentifier: "VC3")
vc4 = self.storyboard?.instantiateViewController(withIdentifier: "VC4")
vcStack.push(vc1)
displayVC(content: vc1!)
}
func displayVC(content: UIViewController) {
// Works to change VCs - no transition
self.addChild(content)
content.view.translatesAutoresizingMaskIntoConstraints = false
self.MainContainer.addSubview(content.view)
NSLayoutConstraint.activate([
content.view.leftAnchor.constraint(equalTo: self.MainContainer.leftAnchor, constant: 0),
content.view.topAnchor.constraint(equalTo: self.MainContainer.topAnchor, constant: 0),
content.view.bottomAnchor.constraint(equalTo: self.MainContainer.bottomAnchor, constant: 0),
content.view.rightAnchor.constraint(equalTo: self.MainContainer.rightAnchor, constant: 0)
])
content.didMove(toParent: self)
}
func slideINTransition(newVC: UIViewController){
print("slide IN stack newVC: \(newVC.restorationIdentifier ?? "novalue")")
print("slide IN stack stack top: \(vcStack.top!.restorationIdentifier ?? "novalue")")
newVC.view.frame = vcStack.top!.view.frame;
vcStack.top!.view.superview?.insertSubview(newVC.view, aboveSubview: vcStack.top!.view)
newVC.view.transform = CGAffineTransform(translationX: vcStack.top!.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.5,
delay: 0.0,
options: UIView.AnimationOptions.curveEaseInOut,
animations: {
newVC.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion:nil// { finished in
//self.vcStack.top!.present(newVC, animated: false, completion: nil) //throws an error when uncommented
//}
)
vcStack.push(newVC)
for junk in vcStack.array{
print("slide IN stack: \(junk.restorationIdentifier ?? "novalue")")
}
}
@IBAction func But_Back_Pressed(_ sender: UIButton) {
for junk in vcStack.array{
print("-----back but stack: \(junk.restorationIdentifier ?? "novalue")")
}
slideOUTTransition()
}
func slideOUTTransition(){
print("slideOUT count: \(vcStack.count)")
if (vcStack.count > 1) {
let visibleVC = vcStack.pop()
visibleVC!.view.transform = CGAffineTransform(translationX: 0, y: 0)
UIView.animate(withDuration: 0.5,
delay: 0.0,
options: UIView.AnimationOptions.curveEaseInOut,
animations: {
visibleVC!.view.transform = CGAffineTransform(translationX: visibleVC!.view.frame.size.width, y: 0)
},
completion: { finished in
visibleVC!.dismiss(animated: false, completion: nil)
}
)
for junk in vcStack.array{
print("slideOUT stack: \(junk.restorationIdentifier ?? "novalue")")
}
print("BACK pop count: \(vcStack.count)")
}
}
@IBAction func But_VC1_Pressed(_ sender: UIButton) {
if vcStack.hasElement(vc1){
print("Trans vc1 exists - doing nothing")
}else{
print("Trans vc1 unique")
slideINTransition(newVC: vc1)
}
}
@IBAction func But_VC2_Pressed(_ sender: UIButton) {
if vcStack.hasElement(vc2){
print("Trans vc2 exists - doing nothing")
}else{
print("Trans vc2 unique")
slideINTransition(newVC: vc2)
}
}
@IBAction func But_VC3_Pressed(_ sender: UIButton) {
if vcStack.hasElement(vc3){
print("Trans vc3 exists - doing nothing")
}else{
print("Trans vc3 unique")
slideINTransition(newVC: vc3)
}
}
@IBAction func But_VC4_Pressed(_ sender: UIButton) {
if vcStack.hasElement(vc4){
print("Trans vc4 exists - doing nothing")
}else{
print("Trans vc4 unique")
slideINTransition(newVC: vc4)
}
}
public struct Stack<T> where T: Equatable {
fileprivate var array = [T]()
public var isEmpty: Bool {
return array.isEmpty
}
public var count: Int {
return array.count
}
public mutating func push(_ element: T) {
array.append(element)
}
public mutating func pop() -> T? {
return array.popLast()
}
public func hasElement(_ element: T) -> Bool {
return array.contains(element)
}
public var top: T? {
return array.last
}
}
Простой тест, который не проходит:
Добавьте VC2, нажав кнопку VC2, и он скользит справа налево по VC1, и VC2 помещается в стек,Нажмите кнопку «Назад», чтобы VC2 скользил назад, слева направо, чтобы снова открыть VC1, и VC2 выталкивается из стека.Пока это работает - только VC1 виден.
Однако, когда я затем нажимаю кнопку VC2 во второй раз, появляется возможность поменяться местами с VC1.VC1 немедленно заменяется на VC2, а затем VC1 скользит слева направо по верху.Каким-то образом это выглядит так, как будто VC2 и VC1 меняются местами перед анимацией.
Также следует отметить - я могу поместить VC2, VC3 и VC4 друг на друга и поместить их в стек, а затем нажать кнопку «Назад», чтобы удалить их изпосмотреть и все работает.Однако после повторного нажатия любого vc происходит перестановка с любым представлением, расположенным непосредственно ниже.
Я отслеживаю массив стека с помощью операторов печати, и он, кажется, работает правильно.Анимации также работают должным образом, поэтому я, должно быть, делаю что-то не так с тем, как я отображаю / добавляю VC ....
Любые идеи, почему каждый VC может быть анимирован в вид, затем удален, но не анимирован в видснова?