2014-10-31 11 views
20

Quindi voglio nascondere la barra di navigazione quando si scorre verso il basso e riportarla indietro durante lo scorrimento verso l'alto. Nascondere funziona perfettamente conhidesBarsOnSwipe non mostra mai di nuovo la barra di navigazione quando si scorre su

self.navigationController?.hidesBarsOnSwipe = true 

Ma mi aspetto che venga mostrato di nuovo quando si scorre. Ho realizzato un progetto di test in cui il controller di visualizzazione ha solo un singolo UICollectionView che copre l'intero schermo. Poi mostra la barra di navigazione è dimostrato ancora una volta come previsto fino a quando ho aggiungere questa riga alle (cellule aggiungendo alla vista di raccolta) viewDidLoad:

self.collectionView.delegate = self 

E questo è ciò che l'intero controller della vista assomiglia

class ViewController: UIViewController,UICollectionViewDataSource, UICollectionViewDelegate { 

@IBOutlet var collectionView: UICollectionView! 
override func viewDidLoad() { 
    super.viewDidLoad() 
    self.collectionView.dataSource = self 
    self.collectionView.delegate = self 
    self.collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "Test") 
    self.navigationController?.hidesBarsOnSwipe = true 
} 

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return 3 
} 

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { 
    return 1 
} 

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell { 
    return collectionView.dequeueReusableCellWithReuseIdentifier("Test", forIndexPath: indexPath) as UICollectionViewCell 
} 

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
    return CGSizeMake(300, 300) 
} 
} 

Allora perché mostrare la barra di navigazione smette di funzionare quando aggiungo le celle alla mia vista collezione?

risposta

36

Ho avuto lo stesso problema ma con una visualizzazione Web. Il problema era che il vincolo principale della vista Web era "Top Layout Guide.Top", dopo aver modificato il vincolo principale in "Superview.Top" il problema era risolto.

+0

Questa era l'unica soluzione che ho trovato che funzionasse. Il mio caso era un UITableViewController incorporato in un UIViewController. –

+0

Wow, ben chiazzato! Comportamento molto strano ... – Martin

+0

Penso che la risposta significasse "Top Layout Guide.Bottom" invece di "Top Layout Guide.Top" – pshah

2

Ho archiviato un bug report con Apple e ho finito per utilizzare AMScrollingNavbar invece che funziona davvero bene ed è facile da configurare.

8

Per espandere il Oleg's answer ...

Se si utilizza Interface Builder per impostare un vincolo alla visualizzazione primario di un controller della vista, per default Xcode a mostrare le opzioni per impostare il vincolo verticale contro la guida di layout in alto. Tuttavia, se premi "Opzione", vedrai una serie alternativa di vincoli. Il vincolo per "Top Space to Container" è quello che stai cercando.

+0

Grazie. Funziona perfettamente con Xcode 8. Cheers – Babac

2

Ho avuto lo stesso problema. Quando ho aggiunto il codice per nascondere la barra di stato insieme alla barra di navigazione, ha funzionato.

- (BOOL)prefersStatusBarHidden { 
    return self.navigationController.isNavigationBarHidden; 
} 
+0

Funziona, ma non se non faccio finta di nascondere la barra di stato insieme. – Lucien

0

Come per i commenti precedenti - questo sembra un bug come di ios 10.3

come si utilizza un uicollectionview - Vorrei attirare la vostra attenzione su un codice ho ri-scritto da APDynamicHeaderTableViewController https://github.com/aaronpang/APDynamicHeaderTableViewController/issues/4

sta usando snapkit https://github.com/SnapKit/SnapKit

(Mi scuso con tutti gli amanti IB + NSLayout vincolo.)

class APDynamicHeaderTableViewController : UIViewController { 

    var largeWideSize = CGSize(width: UIScreen.main.bounds.width , height: 285) 
    let headerView = APDynamicHeaderView() // Change your header view here 

    let cellLayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
    var feedCV:UICollectionView! 

    fileprivate var headerViewHeight:CGFloat = 80 // this will be updated by scrolling 
    fileprivate var headerBeganCollapsed = false 
    fileprivate var collapsedHeaderViewHeight : CGFloat = UIApplication.shared.statusBarFrame.height 
    fileprivate var expandedHeaderViewHeight : CGFloat = 100 
    fileprivate var headerExpandDelay : CGFloat = 100 
    fileprivate var tableViewScrollOffsetBeginDraggingY : CGFloat = 0.0 


    init(collapsedHeaderViewHeight : CGFloat, expandedHeaderViewHeight : CGFloat, headerExpandDelay :CGFloat) { 
    self.collapsedHeaderViewHeight = collapsedHeaderViewHeight 
    self.expandedHeaderViewHeight = expandedHeaderViewHeight 
    self.headerExpandDelay = headerExpandDelay 
    super.init(nibName: nil, bundle: nil) 


    } 


    init() { 
    super.init(nibName: nil, bundle: nil) 

    } 

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

    override func loadView() { 
    super.loadView() 
    self.view.backgroundColor = .green 

    // Cell Layout Sizes 
    cellLayout.scrollDirection = .vertical 
    cellLayout.sectionInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10) 
    cellLayout.itemSize = CGSize(width: UIScreen.main.bounds.width, height: 185 + 80) 


    // Header view 
    self.view.addSubview(headerView) 
    headerView.snp.remakeConstraints { (make) -> Void in 
     make.top.left.equalToSuperview() 
     make.width.equalToSuperview() 
     make.height.equalTo(headerViewHeight) 
    } 

    // CollectionView 
    feedCV = UICollectionView(frame: .zero, collectionViewLayout: cellLayout) 
    self.view.addSubview(feedCV) 
    self.feedCV.snp.remakeConstraints { (make) -> Void in 
     make.top.equalTo(headerView.snp.bottom) // this is pegged to the header view which is going to grow in height 
     make.left.equalToSuperview() 
     make.width.equalToSuperview() 
     make.bottom.equalToSuperview() 
    } 



    feedCV.backgroundColor = .red 
    feedCV.showsVerticalScrollIndicator = true 
    feedCV.isScrollEnabled = true 
    feedCV.bounces = true 
    feedCV.delegate = self 
    feedCV.dataSource = self 

    // YOUR COLLECTIONVIEW CELL HERE!!!!! 
    feedCV.register(VideoCollectionViewCell.self, forCellWithReuseIdentifier: VideoCollectionViewCell.ID) 


    } 

    // Animate the header view to collapsed or expanded if it is dragged only partially 
    func animateHeaderViewHeight() -> Void { 
    Logger.verbose("animateHeaderViewHeight") 

    var headerViewHeightDestinationConstant : CGFloat = 0.0 
    if (headerViewHeight < ((expandedHeaderViewHeight - collapsedHeaderViewHeight)/2.0 + collapsedHeaderViewHeight)) { 
     headerViewHeightDestinationConstant = collapsedHeaderViewHeight 
    } else { 
     headerViewHeightDestinationConstant = expandedHeaderViewHeight 
    } 

    if (headerViewHeight != expandedHeaderViewHeight && headerViewHeight != collapsedHeaderViewHeight) { 
     let animationDuration = 0.25 
     UIView.animate(withDuration: animationDuration, animations: {() -> Void in 
     self.headerViewHeight = headerViewHeightDestinationConstant 
     let progress = (self.headerViewHeight - self.collapsedHeaderViewHeight)/(self.expandedHeaderViewHeight - self.collapsedHeaderViewHeight) 
     self.headerView.expandToProgress(progress) 
     self.view.layoutIfNeeded() 
     }) 
    } 
    } 
} 

extension APDynamicHeaderTableViewController : UICollectionViewDelegate { 

} 

extension APDynamicHeaderTableViewController : UIScrollViewDelegate { 
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { 
    // Clamp the beginning point to 0 and the max content offset to prevent unintentional resizing when dragging during rubber banding 
    tableViewScrollOffsetBeginDraggingY = min(max(scrollView.contentOffset.y, 0), scrollView.contentSize.height - scrollView.frame.size.height) 

    // Keep track of whether or not the header was collapsed to determine if we can add the delay of expansion 
    headerBeganCollapsed = (headerViewHeight == collapsedHeaderViewHeight) 
    } 

    func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    // Do nothing if the table view is not scrollable 
    if feedCV.contentSize.height < feedCV.bounds.height { 
     return 
    } 
    var contentOffsetY = feedCV.contentOffset.y - tableViewScrollOffsetBeginDraggingY 
    // Add a delay to expanding the header only if the user began scrolling below the allotted amount of space to actually expand the header with no delay (e.g. If it takes 30 pixels to scroll up the scrollview to expand the header then don't add the delay of the user started scrolling at 10 pixels) 
    if tableViewScrollOffsetBeginDraggingY > ((expandedHeaderViewHeight - collapsedHeaderViewHeight) + headerExpandDelay) && contentOffsetY < 0 && headerBeganCollapsed { 
     contentOffsetY = contentOffsetY + headerExpandDelay 
    } 
    // Calculate how much the header height will change so we can readjust the table view's content offset so it doesn't scroll while we change the height of the header 
    let changeInHeaderViewHeight = headerViewHeight - min(max(headerViewHeight - contentOffsetY, collapsedHeaderViewHeight), expandedHeaderViewHeight) 
    headerViewHeight = min(max(headerViewHeight - contentOffsetY, collapsedHeaderViewHeight), expandedHeaderViewHeight) 
    let progress = (headerViewHeight - collapsedHeaderViewHeight)/(expandedHeaderViewHeight - collapsedHeaderViewHeight) 
// Logger.verbose("headerViewHeight:",headerViewHeight) 
    headerView.expandToProgress(progress) 
    headerView.snp.updateConstraints { (make) -> Void in 
     make.height.equalTo(headerViewHeight) 
    } 

    // When the header view height is changing, freeze the content in the table view 
    if headerViewHeight != collapsedHeaderViewHeight && headerViewHeight != expandedHeaderViewHeight { 
     feedCV.contentOffset = CGPoint(x: 0, y: feedCV.contentOffset.y - changeInHeaderViewHeight) 
    } 
    } 

    // Animate the header view when the user ends dragging or flicks the scroll view 
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    animateHeaderViewHeight() 
    } 

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
    animateHeaderViewHeight() 
    } 
} 

extension APDynamicHeaderTableViewController : UICollectionViewDataSource { 
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 100 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: VideoCollectionViewCell.ID, for: indexPath) as! VideoCollectionViewCell 

     return cell 
    } 


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

    } 



    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     return largeWideSize 
    } 




} 
Problemi correlati