gpt4 book ai didi

ios - 自定义 UINavigationBar 的外观

转载 作者:可可西里 更新时间:2023-11-01 01:24:17 24 4
gpt4 key购买 nike

我是 iOS UI 设计的新手,我正在编写显示高度自定义导航栏的代码,我的交通应用程序将使用它。

这是我的导航栏的特点(见下图): Custom UINavigationBar Blueprint

  1. Layout Margins18, subview 之间的 Space9
  2. 它的所有 subview 的高度都是44,所有的UIBarButtonItem都是矩形。
  3. backBarButtonItem 的位置应与 leftBarButtonItem 相同。
  4. 正常状态,它的高度80
  5. 展开状态(例如 map 应用中的方向字段 View ),其titleView 将包含两个UITextFields,所以它的高度应该是136

查看真实设计截图 See Real Design Screenshots所以我声明了 UINavigationBar 的子类,并使用 Identity Inspector 将自定义类连接到 Storyboard中的 Navigation Bar 对象。但是,我不确定从哪里开始。虽然我暂时覆盖了 sizeThatFits(_ size:) 函数以使其 height 变长,但 subview 接近底部。我找不到自定义 UINavigationBar 的最佳实践,例如 Google map 、Uber 等。

如何通过子类化 UINavigationBar 来实现这样的导航栏?或者还有其他解决方案吗?

最佳答案

您可以通过以下步骤子类化 UINavigationBar..

  1. 添加一个新类(UINavigationBar 的子类),选择您的 ViewController 的 NavigationController。从 Document Outline 中选择 ViewController Navigation Bar。将类(class)设置为您的自定义类(class)。

  2. 在您的自定义类中,执行以下操作..

    override func sizeThatFits(_ size: CGSize) -> CGSize {
    var bound = super.sizeThatFits(size)
    bound.height += sizeToAdd //The height you want
    return bound
    }

    override init(frame: CGRect) {
    super.init(frame: frame)
    self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.setup()
    }

    override func layoutSubviews() {
    super.layoutSubviews()

    //If you don't override this function and do as follows, you'll
    //find that all NavigationButtons and the Title positioned at the
    //bottom of your navigation bar.(for the Title, we still need to
    //add one line in setup())

    let classes = ["UIButton", "UINavigationItemView",
    "UINavigationButton"]

    for object in self.subviews{

    let classOfObject = String(describing: type(of: object))

    if classes.contains(classOfObject){
    var objectFrame = object.frame
    objectFrame.origin.y -= self.sizeToAdd
    object.frame = objectFrame
    }
    }

    }
  3. 现在在 setup() 中,添加以下代码以根据需要提升标题(通常!)

    func setup() -> Void {
    self.setTitleVerticalPositionAdjustment(-self.sizeToAdd, for:
    .default)
    }
  4. 现在,您可以根据需要设计一个 View (在这里,我已经使用 XIB 加载了一个自定义 View ,您也可以使用代码来完成。)并在您的 ViewController 中将其作为 subview 添加到您的导航栏.例如,在您的 viewDidLoad..

    YOURVIEW.frame = CGRect(x: 0, y: 44, width: 
    (self.navigationController?.navigationBar.bounds.width)!, height:
    (self.navigationController?.navigationBar.bounds.height)! +
    self.sizeToAdd)//The height
    self.navigationController?.navigationBar.
    addSubview(YOURVIEW)
  5. 因此,您可以通过这种方式对导航栏进行子类化。但是当你将任何其他 viewController 推到这个 viewController 上时,你会看到(如果你没有将另一个 NavigationController 嵌入到你正在推的 viewController 中) View 也保持在推送的 viewController 中。您可以在推送任何其他 viewController 之前将其从 super View 中删除。仅仅删除它不会提供良好的用户体验,因为其他系统元素(如果有的话)会很好地淡出。因此,请执行以下操作以提供良好的用户体验...

    override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(true)

    if(!(self.navigationController?.navigationBar.subviews.contains
    (YOURVIEW))!){ //Either get it working with setting a tag to
    //your view and checking it against all subviews
    //if you haven't use XIB
    self.navigationController?.navigationBar.
    addSubview(YOURVIEW)
    }else {
    UIView.transition(with: YOURVIEW,
    duration: 0.5, options: [ANYOPTIONS], animations: {
    self.profileNavigationView.alpha = 1.0
    }) { (success) in

    }
    }

    override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(true)

    UIView.transition(with: YOURVIEW, duration:
    0.5,
    options: [ANYOPTIONS], animations: {
    self.profileNavigationView.alpha = 0.0
    }) { (success) in
    //remove it here if you want
    }

关于ios - 自定义 UINavigationBar 的外观,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42265627/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com