如何在导航栏内添加页面指示器?

Posted

技术标签:

【中文标题】如何在导航栏内添加页面指示器?【英文标题】:How to add a page indicator inside the navigation bar? 【发布时间】:2014-01-12 11:05:55 【问题描述】:

就像推特一样:

我在 UITabBarController 中有一个 PageViewController,它又在 UINavigationController 中。

谁能告诉我如何在导航栏中显示页面指示器?

【问题讨论】:

他们很可能会写自己的观点。 可以使用self.navigationController.navigationItem.titleView,它是一个UIView。创建页面指示器的自定义实现并将其设置为 titleView。但是,您还需要注意自定义标题页指示器视图与其他组件之间的交互将如何发生? 【参考方案1】:

编辑:我刚刚发现 navigationController.viewControllers 只包含堆栈。 我会在一分钟内发布一个编辑

编辑 2:好吧,看来您必须事先知道视图控制器的数量。

也许不是最好的解决方案,但它对我有用。刚试过:)

@interface ViewController () <UINavigationControllerDelegate>
@property (nonatomic, strong) UIPageControl *pageControl;
@end

@implementation ViewController

- (void)viewDidLoad

    [super viewDidLoad];

    UINavigationController *navController = self.navigationController;
    navController.delegate = self;

    navController.navigationBar.barTintColor = [UIColor colorWithRed:.2
                                                               green:.4
                                                                blue:.9
                                                               alpha:1];

    CGSize navBarSize = navController.navigationBar.bounds.size;
    CGPoint origin = CGPointMake( navBarSize.width/2, navBarSize.height/2 );

    self.pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(origin.x, origin.y,
                                                                       0, 0)];

    //Or whatever number of viewcontrollers you have
    [self.pageControl setNumberOfPages:2];

    [navController.navigationBar addSubview:self.pageControl];

    navController.delegate = self;


- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated

    int index = [navigationController.viewControllers indexOfObject:viewController];
    self.pageControl.currentPage = index;


@end

这里有一些截图。

【讨论】:

对 UIPageViewControllers 进行这项工作应该不难【参考方案2】:

这是寻找 Swift 解决方案的人的答案。

(根据自己的需要调整格式)

class NavigationControllerWithPageControl: UINavigationController, UINavigationControllerDelegate 

    let numberOfPages: Int

    init(rootViewController: UIViewController, numberOfPages: Int) 
        self.numberOfPages = numberOfPages
        super.init(rootViewController: rootViewController)
    

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

    override func viewDidLoad() 
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        delegate = self
        navigationBar.addSubview(pageControl)
        pageControl.centerXAnchor.constraint(equalTo: navigationBar.centerXAnchor).isActive = true
        pageControl.centerYAnchor.constraint(equalTo: navigationBar.centerYAnchor).isActive = true
    

    lazy var pageControl: UIPageControl = 
        let navBarsize = navigationBar.bounds.size
        let origin = CGPoint(x: navBarsize.width/2, y: navBarsize.height/2)
        let pc = UIPageControl(frame: CGRect(x: origin.x, y: origin.y, width: 100, height: 20))
        pc.translatesAutoresizingMaskIntoConstraints = false
        pc.numberOfPages = numberOfPages
        pc.currentPageIndicatorTintColor = .black
        pc.pageIndicatorTintColor = UIColor.white//.withAlphaComponent(0.3)
        pc.isUserInteractionEnabled = false
        return pc
    ()

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) 
        let index = navigationController.viewControllers.firstIndex(of: viewController) ?? NSNotFound
        DispatchQueue.main.async  [weak self] in
            self?.pageControl.currentPage = index
            guard let pageControlSubviews = self?.pageControl.subviews.enumerated() else return
            for (_, dotView) in pageControlSubviews 
                dotView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
                dotView.layer.borderColor = UIColor.black.cgColor
                dotView.layer.borderWidth = 1
            
        
    


用法:

let navigationViewController = NavigationControllerWithPageControl(rootViewController: SomeViewController(), numberOfPages: 7)
present(navigationViewController, animated: true, completion: nil)

【讨论】:

以上是关于如何在导航栏内添加页面指示器?的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 导航栏内的动画不起作用

每个 ViewController 在标签栏内都有自己的导航栏(iOS)

Flutter 底部导航栏

如何在 Swift 的导航栏顶部显示自定义视图?

如何在导航控制器堆栈中将场景切换到几层?

想要导航菜单在初始页面上的背景图像上,但它在各种显示器上移动