2017-03-10 2 views
0

Ich versuche, ein Statusbanner über einer navigationBar zu animieren. Die Animation funktioniert einwandfrei, wenn ich das Banner in der viewControllers-Ansicht hinzufüge, aber hinter der Navigationsleiste lande. Wenn ich das Banner zur Navigationsleiste hinzufüge, "springt" das Banner in die Navigationsleiste, führt jedoch keine Animation durch. Dasselbe Problem, wenn ich die Banneransicht zum keyWindow hinzufüge. Ich habe auch versucht, die Banner-Ansicht und die NavigationBars Ebenen zPosition ohne Glück zu manipulieren. Wer hat eine Idee? Animiere UIView auf einer navigationBar in Swift

Hier ist mein Code ...

import UIKit 

class BellaBannerView : UIView { 
var view : UIView! 
var style : BannerStyle! 
var position : BannerTopAnchor! 

var bannerView : UIView! 
var messageLabel : UILabel! 
var dissmissButton : UIButton! 
var offsetConstraintConstant : CGFloat! 
var testconst : NSLayoutConstraint! 

override init(frame: CGRect) { 
    super.init(frame: frame) 
} 
convenience init(view: ViewController, style : BannerStyle, pos : BannerTopAnchor) { 
self.init(frame: CGRect.zero) 
    self.view = view.view 
    self.style = style 
    self.position = pos 
    self.offsetConstraintConstant = style.bannerSize() 
    self.translatesAutoresizingMaskIntoConstraints = false 
    self.clipsToBounds = true 

    if let isNavigation = view.navigationController?.view { 
     isNavigation.addSubview(self) 
    } else { 
     self.view.addSubview(self) 
    } 

    initViews(style: style, pos: pos) 
    addSubview(bannerView) 
    bannerView.addSubview(dissmissButton) 
    bannerView.addSubview(messageLabel) 

    setConstraints(view: view, pos: pos) 
} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

func initViews(style : BannerStyle, pos : BannerTopAnchor) { 

    bannerView = { 
     let view = UIView() 
     view.backgroundColor = style.backgroundColor() 
     view.translatesAutoresizingMaskIntoConstraints = false 
     return view 
    }() 

    dissmissButton = { 
     let btn = UIButton() 
     btn.translatesAutoresizingMaskIntoConstraints = false 
     btn.backgroundColor = style.backgroundColor() 
     btn.setImage(UIImage(named: "dissmiss"), for: .normal) 
     btn.addTarget(self, action: #selector(hide), for: .allTouchEvents) 
     return btn 
    }() 

    messageLabel = { 
     let label = UILabel() 
     label.text = "BESKJED beskjed Beskjed" 
     label.textColor = .lightGray 
     label.textAlignment = .center 
     label.translatesAutoresizingMaskIntoConstraints = false 
     return label 
    }() 

} 

func show() { 
    UIView.animate(withDuration: 0.5, animations: {() -> Void in 
     self.testconst.constant = 0 
     self.view.layoutIfNeeded() 
    }) 
} 

func hide() { 
    UIView.animate(withDuration: 0.5, animations: {() -> Void in 
     self.testconst.constant = -self.offsetConstraintConstant 
     self.view.layoutIfNeeded() 
    }) 
} 

func setConstraints(view : ViewController, pos : BannerTopAnchor) { 
    self.heightAnchor.constraint(equalToConstant: style.bannerSize()).isActive = true 
    self.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true 
    self.topAnchor.constraint(equalTo: self.view.topAnchor, constant: pos.topPosition()).isActive = true 
    self.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true 

    bannerView.heightAnchor.constraint(equalTo: self.heightAnchor).isActive = true 
    bannerView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true 
    bannerView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true 
    self.testconst = bannerView.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -self.offsetConstraintConstant) 
    self.testconst.isActive = true 

    dissmissButton.bottomAnchor.constraint(equalTo: bannerView.bottomAnchor).isActive = true 
    dissmissButton.trailingAnchor.constraint(equalTo: bannerView.trailingAnchor).isActive = true 
    dissmissButton.widthAnchor.constraint(equalToConstant: style.buttonSize()).isActive = true 
    dissmissButton.heightAnchor.constraint(equalToConstant: style.buttonSize()).isActive = true 

    messageLabel.leadingAnchor.constraint(equalTo: bannerView.leadingAnchor, constant: style.buttonSize()).isActive = true 
    messageLabel.trailingAnchor.constraint(equalTo: bannerView.trailingAnchor, constant: -style.buttonSize()).isActive = true 
    messageLabel.bottomAnchor.constraint(equalTo: bannerView.bottomAnchor).isActive = true 
    messageLabel.heightAnchor.constraint(equalToConstant: style.bannerSize()).isActive = true 
} 

enum BannerTopAnchor { 
    case top 
    case statusBar 
    case navbar 

    func topPosition() -> CGFloat { 
     switch self { 
     case .top: 
      return 0 
     case .statusBar: 
      return UIApplication.shared.statusBarFrame.height 
     case .navbar: 
      return 64 
     } 
    } 
} 


enum BannerStyle { 
    case success 
    case info 
    case offline 
    case online 

    func backgroundColor() -> UIColor { 
     switch self { 
     case .success, .online: 
      return UIColor.green//.bellaSuccessBannerBackground() 
     case .info: 
      return UIColor.blue//.bellaDarkishBlueColor() 
     case .offline: 
      return UIColor.red//.bellaLipstickColor() 
     } 
    } 

    func bannerSize() -> CGFloat { 
     switch self { 
     case .info: 
      return 50 
     case .online, .offline, .success: 
      return 25 
     } 
    } 

    func buttonSize() -> CGFloat { 
     switch self { 
     case .info: 
      return 50 
     default: 
      return 0 
     } 
    } 

    func textColor() -> UIColor { 
     switch self { 
     case .success, .online: 
      return UIColor.green//bellaDarkishGreenColor() 
     case .info: 
      return UIColor.brown//bellaBeigeColor() 
     case .offline: 
      return UIColor.white 
     } 
    } 

    func dismissable() -> Bool { 
     switch self { 
     case .success, .offline, .online: 
      return false 
     case .info: 
      return true 
     } 
    } 
} 
} 
+0

Müssen Sie die Navigationsleiste anzeigen? Sie möchten die Navigationsleiste, wenn Sie mehrere View-Controller haben, was nicht bedeutet, dass Sie sie anzeigen müssen. –

+0

Ja. Ich möchte die Navigationsleiste behalten. Eine Option könnte sein, die gesamte Logik zu ersetzen, die der Navigationscontroller gibt, aber ich suchte nach einer einfacheren Lösung;) –

Antwort

0

Also hier das Problem ist, dass die Navigationssteuerung Ihrer Ansicht Controller Sicht nehmen und fügt sie es ist Inhalt Ansicht, die hinter der Navigationsleiste ist. Sie müssen Ihr Banner zu etwas oberhalb der Navigationsleiste hinzufügen.

Sie haben ein paar Optionen hier, können Sie es zu den Navigationscontroller anzuzeigen direkt hinzufügen:

self.navigationController?.view.addSubview(bannerView) 

dies sollte gut funktionieren, obwohl ich immer zögerlich bin mit einer UINavigationController Ansicht Hierarchie zu spielen, wie ich manuell, immer als Managerhierarchie.

Meiner Meinung nach einem besseren Ansatz wäre es gerade zum Fenster hinzuzufügen, was den zusätzlichen Vorteil, dass Sie sicher, hat es am Anfang von allem ist:

self.view.window?.addSubview(bannerView) 

diese greift auf das Root-Fenster, das self Die Sicht ist in und fügt Ihr Banner zu allem hinzu.

+0

Ich habe beide Optionen versucht, aber das Problem ist, dass die Banneransicht einfach aufspringt. Die Animation funktioniert nicht. Aber danke :) –

+0

Kannst du einen Breakpoint in deine 'show' Methode setzen und die' testconst' am Anfang der Animation überprüfen? Um sicherzustellen, dass Sie von der Bildfläche starten, gibt es sonst keine Animation. –

+0

Danke, dass Sie mich in die richtige Richtung gedrängt haben @Georg Green Ich hatte ein layoutIfNeeded vor der Animation, um sicherzustellen, dass alles vor dem Start aktualisiert wurde Animation –

1

Problem behoben. Aktualisiertes Layout vor Beginn der Animation

func show() { 
    self.layoutIfNeeded() 
    self.testconst.constant = 0 
    UIView.animate(withDuration: 0.5, animations: {() -> Void in 
     self.layoutIfNeeded() 
    }) 
} 

func hide() { 
    self.layoutIfNeeded() 
    self.testconst.constant = -self.offsetConstraintConstant 
    UIView.animate(withDuration: 0.5, animations: {() -> Void in 
     self.layoutIfNeeded() 
    }) 
} 
Verwandte Themen