简体   繁体   English

导航栏后面的搜索栏

[英]Searchbar behind Navigationbar

Given 3 Controllers: A,B,CA has a hidden navigationbar. 给定3个控制器:A,B,CA具有隐藏的导航栏。 Calls Controller B via a StoryboardReference. 通过StoryboardReference调用控制器B。 Controller B shows Navigationbar on viewDidLoad. 控制器B在viewDidLoad上显示导航栏。 It has a searchbar and a collectionView. 它具有一个搜索栏和一个collectionView。 See screenshot A of my storyboard. 请参阅我的情节提要的屏幕快照A。 Calls controller C if a cell is clicked. 如果单击一个单元格,则调用控制器C。

Problem: If A calls B the searchbar is behind the navigationbar (Screenshot B). 问题:如果A呼叫B,则搜索栏位于导航栏的后面(屏幕快照B)。 It appears with the transition from C to B (Screenshot C). 出现从C到B的过渡(屏幕截图C)。

Navigationbar is already translucent. 导航栏已经是半透明的。 Any ideas? 有任何想法吗?

EDIT 编辑

I realized that my animated transitioning is causing my problem. 我意识到动画过渡导致了我的问题。

Perhaps you can spot the error? 也许您可以发现错误?

class ZoomInCircleViewTransition: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate {

    var transitionContext: UIViewControllerContextTransitioning?

    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.6
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        self.transitionContext = transitionContext

        guard let toViewController: UIViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else {
            return
        }

        guard let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) else {            return
        }

        guard let fromViewTransitionFromView = fromViewController as? TransitionFromViewProtocol else {
            return
        }

        let imageViewSnapshot = fromViewTransitionFromView.getViewForTransition()

        let endFrame = CGRectMake(-CGRectGetWidth(toViewController.view.frame)/2, -CGRectGetHeight(toViewController.view.frame)/2, CGRectGetWidth(toViewController.view.frame)*2, CGRectGetHeight(toViewController.view.frame)*2)

        if let containerView = transitionContext.containerView(){
            containerView.addSubview(fromViewController.view)
            containerView.addSubview(toViewController.view)
            containerView.addSubview(imageViewSnapshot)
        }


        let maskPath = UIBezierPath(ovalInRect: imageViewSnapshot.frame)
        let maskLayer = CAShapeLayer()
        maskLayer.frame = toViewController.view.frame
        maskLayer.path = maskPath.CGPath
        toViewController.view.layer.mask = maskLayer

        let quadraticEndFrame = CGRect(x: endFrame.origin.x - (endFrame.height - endFrame.width)/2, y: endFrame.origin.y, width: endFrame.height, height: endFrame.height)
        let bigCirclePath = UIBezierPath(ovalInRect: quadraticEndFrame)

        let pathAnimation = CABasicAnimation(keyPath: "path")
        pathAnimation.delegate = self
        pathAnimation.fromValue = maskPath.CGPath
        pathAnimation.toValue = bigCirclePath
        pathAnimation.duration = transitionDuration(transitionContext)
        maskLayer.path = bigCirclePath.CGPath
        maskLayer.addAnimation(pathAnimation, forKey: "pathAnimation")


        let hideImageViewAnimation =  {
            imageViewSnapshot.alpha = 0.0
        }

        UIView.animateWithDuration(0.2, delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: hideImageViewAnimation) { (completed) -> Void in
        }

        let scaleImageViewAnimation = {
            imageViewSnapshot.frame = quadraticEndFrame
        }
        UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: scaleImageViewAnimation) { (completed) -> Void in
            // After the complete animations have endet
            imageViewSnapshot.removeFromSuperview()
            toViewController.view.layer.mask = nil
        }
    }

    override func animationDidStop(anim: CAAnimation, finished flag: Bool) {
        if let transitionContext = self.transitionContext {
            transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
        }
    }

    // MARK: UIViewControllerTransitioningDelegate protocol methods

    // return the animataor when presenting a viewcontroller
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }

    // return the animator used when dismissing from a viewcontroller
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self
    }
}

I believe I was running in to some similar problems in my app, but running in to difficulties because of all the things you don't have control over. 我相信我在应用程序中遇到了一些类似的问题,但是由于所有您无法控制的事情而遇到了困难。 My solution was to put a search icon in the navigationbar, then have the search controller slide down over the navigationbar, keeping it out of the table/scroll view. 我的解决方案是在导航栏中放置一个搜索图标,然后使搜索控制器在导航栏上向下滑动,以使其保持在表格/滚动视图之外。 Here is my implementation (should be complete) 这是我的实现(应该完整)

import UIKit

class tvc: UITableViewController, UISearchBarDelegate, UISearchControllerDelegate {

var searchController:UISearchController!

@IBAction func startSearch() {
    self.navigationController?.presentViewController(self.searchController, animated: true, completion: {})
}

override func viewDidDisappear(animated: Bool) {
    cancelSearch(self)
}

override func viewDidLoad() {
    super.viewDidLoad()

    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    searchController.delegate = self
    searchController.hidesNavigationBarDuringPresentation = false
    searchController.loadViewIfNeeded()  /* Fixes bug in iOS http://stackoverflow.com/questions/32675001/uisearchcontroller-warning-attempting-to-load-the-view-of-a-view-controller */
    definesPresentationContext = true
    tableView.sectionIndexBackgroundColor = UIColor.clearColor()
    tableView.sectionIndexTrackingBackgroundColor = UIColor.clearColor()
}

extension tvc: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResultsForSearchController(searchController: UISearchController) {
    filterContentForSearchText(searchController.searchBar.text!)
    }
}

func cancelSearch(sender: AnyObject?) {
if sender!.searchController.active == true {
sender?.searchController.resignFirstResponder()
sender!.navigationController!!.dismissViewControllerAnimated(false, completion: {})
sender!.searchController.searchBar.text = ""
sender!.searchController.active = false
    }
}

I think problem is your are either you are not setting frame for imageViewSnapshot or setting wrong frame. 我认为问题是您是不是为imageViewSnapshot设置框架还是设置了错误的框架。 As imageViewSnapshot includes the search bar, your have to set the frame such are it goes behind the navigation bar. 由于imageViewSnapshot包含搜索栏,因此您必须设置框架,使其位于导航栏的后面。 or imageViewSnapshot should contain only visible area of the fromViewTransitionFromView. 或imageViewSnapshot应该只包含fromViewTransitionFromView的可见区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM