【问题标题】:UIToolBar position to top of UINavigationControllerUIToolBar 到 UINavigationController 顶部的位置
【发布时间】:2016-09-02 09:55:07
【问题描述】:

如何将UIToolBar 移到顶部(坚持UINavigationBar)?

我在这件事上挣扎了很长时间,我尝试了一些类似的东西:

  • 符合UIToolbarDelegate(UIBarPosition)positionForBar:(id <UIBarPositioning>)bar 的自定义UIToolBar 被调用 我返回UIBarPositionTop,但工具栏停留在底部。
  • 更改工具栏框架:self.navigationController.toolbar.frame = CGRectMake(0, NAV_BAR_Y, self.view.bounds.size.width, NAV_BAR_HEIGHT);
  • 具有此委托功能的自定义UINaviagtionController(UIBarPosition)positionForBar:(id <UIBarPositioning>)bar { return UIBarPositionTop; }

所有的斗争都不顺利,同样的样子:

任何帮助都会很棒。

(我想让导航看起来像 Apple App store 导航)

【问题讨论】:

  • 您可以在导航栏中添加。

标签: ios iphone uinavigationcontroller uinavigationbar uitoolbar


【解决方案1】:

我知道有 2 个选项。

1) 与Move UINavigationController's toolbar to the top to lie underneath navigation bar相关

您可以继承UINavigationController,并在设置值时更改工具栏的Y轴位置。

import UIKit

private var context = 0

class NavigationController: UINavigationController {
    private var inToolbarFrameChange = false
    var observerBag: [NSKeyValueObservation] = []

    override func awakeFromNib() {
        super.awakeFromNib()
        self.inToolbarFrameChange = false
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        observerBag.append(
            toolbar.observe(\.center, options: .new) { toolbar, _ in
                if !self.inToolbarFrameChange {
                    self.inToolbarFrameChange = true
                    toolbar.frame = CGRect(
                        x: 0,
                        y: self.navigationBar.frame.height + UIApplication.shared.statusBarFrame.height,
                        width: toolbar.frame.width,
                        height: toolbar.frame.height
                    )
                    self.inToolbarFrameChange = false
                }
            }
        )
    }

    override func setToolbarHidden(_ hidden: Bool, animated: Bool) {
        super.setToolbarHidden(hidden, animated: false)

        var rectTB = self.toolbar.frame
        rectTB = .zero
    }
}

2) 您可以创建自己的UIToolbar 并将其添加到UIViewController 的视图中。然后,将约束添加到安全区域的前导、尾随和顶部。

import UIKit

final class ViewController: UIViewController {
    private let toolbar = UIToolbar()
    private let segmentedControl: UISegmentedControl = {
        let control = UISegmentedControl(items: ["Op 1", "Op 2"])
        control.isEnabled = false
        return control
    }()

   override func loadView() {
        super.loadView()
        setupToolbar()
   }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.navigationBar.hideBorderLine()
    }

    private func setupToolbar() {
        let barItem = UIBarButtonItem(customView: segmentedControl)
        toolbar.setItems([barItem], animated: false)
        toolbar.isTranslucent = false
        toolbar.isOpaque = false

        view.addSubview(toolbar)

        toolbar.translatesAutoresizingMaskIntoConstraints = false
        toolbar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
        toolbar.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
        toolbar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
    }
}

private extension UINavigationBar {

    func showBorderLine() {
        findBorderLine().isHidden = false
    }

    func hideBorderLine() {
        findBorderLine().isHidden = true
    }

    private func findBorderLine() -> UIImageView! {
        return self.subviews
            .flatMap { $0.subviews }
            .compactMap { $0 as? UIImageView }
            .filter { $0.bounds.size.width == self.bounds.size.width }
            .filter { $0.bounds.size.height <= 2 }
            .first
    }
}

【讨论】:

    【解决方案2】:

    试试这个解决方案

    @interface ViewController () <UIToolbarDelegate>
    {
        UIToolbar * lpToolbar;
    }
    @end
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        lpToolbar = [[UIToolbar alloc] initWithFrame :CGRectZero];
        lpToolbar.delegate = self;
        self.navigationItem.title = @"Title";
    }
    
    -(void) viewWillAppear :(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        [self.navigationController.view addSubview :lpToolbar];
        CGRect rFrame = self.navigationController.navigationBar.frame;
        lpToolbar.frame = CGRectMake( 0.0, rFrame.origin.y + rFrame.size.height, rFrame.size.width, 50.0 );
    }
    
    -(void) viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
        [lpToolbar removeFromSuperview];
    }
    
    -(UIBarPosition) positionForBar:(id <UIBarPositioning>)bar
    {
        return UIBarPositionTop;
    }
    

    【讨论】:

    • 谢谢,我之前已经试过了,但不是很好的解决方案,尝试再推一个 View Controller ,Bar 按钮项会粘在底部。为了让他们坚持下去,你需要破解导航栏(使用一些私有 API),我真的不想进入那里
    • 您是否希望导航堆栈中所有视图控制器的导航栏都使用相同的段控制器?
    • 不一定,我希望 View 控制器决定是否如此。
    • 您将创建自己的 UIToolbar 并使用 addSubview 将其添加到 UINavigationController 视图中,设置框架 y 波纹管导航栏 y + height - 1,并使用您的工具栏位置方法设置委托 UIToolbarDelegate。可能也是不好的解决方案,但很容易。您将在 viewWillAppear 中添加它并在 viewWillDisappear 中从 superview 中删除
    猜你喜欢
    • 2011-12-25
    • 1970-01-01
    • 2012-05-25
    • 2015-06-03
    • 2011-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多