ios - UINavigationBar 底部边框消失

标签 ios swift overriding uinavigationbar draw

我正在对 UINavigationBar 进行子类化,在界面生成器中,我使用 Identity Inspector 将其设置为我的 UINavigationControllerNavigationBar 类>。问题是,当我覆盖 draw 方法时,我的 navigationBar 的底部边框消失了。这是我的代码:

class YC_NavigationBar: UINavigationBar {

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

        self.backIndicatorImage = UIImage(named: "TopBar_Button_Back")!.withRenderingMode(.alwaysOriginal)
        self.backIndicatorTransitionMaskImage = UIImage(named: "TopBar_Button_Back")!.withRenderingMode(.alwaysOriginal)
        UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -200.0), for: .default)

    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)

        for i in self.subviews {
            if NSStringFromClass(i.classForCoder) == "_UINavigationBarContentView" {
                for j in i.subviews {
                    for constraint in j.constraints {
                        if constraint.firstAttribute == .leading && NSStringFromClass(constraint.firstItem!.classForCoder) == "_UIModernBarButton"  {
                            constraint.constant = 0
                            break
                        }
                    }
                    if NSStringFromClass(j.classForCoder) == "_UIButtonBarStackView" {
                        let ctr = NSLayoutConstraint(item: j, attribute: .trailing, relatedBy: .equal, toItem: i, attribute: .trailing, multiplier: 1, constant: 0)
                        i.addConstraint(ctr)
                    }
                }
                break
            }
        }
    }
}

仅仅覆盖该方法就发生了这种事情,这太荒谬了。我该如何解决这个问题?

最佳答案

这里有两个主要选项:

  1. 像这样自己画一条线:

    override func draw(_ rect: CGRect) {
        super.draw(rect)
    
        // your other code here.
    
        if rect.maxY == self.bounds.maxY {
            if let context = UIGraphicsGetCurrentContext() {
                context.setStrokeColor(UIColor.red.cgColor)
                context.setLineWidth(1)
                context.move(to: CGPoint(x: 0, y: bounds.height))
                context.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
                context.strokePath()
            }
        }
    }
    
  2. 在 Interface Builder 的栏中添加一个 1px 高度的 subview 。

附言不要在 drawRect() 方法中执行布局代码。有一个特定的重写点正是为了这个目的而存在的:

open func layoutSubviews() // override point. called by layoutIfNeeded automatically. As of iOS 6.0, when constraints-based layout is used the base implementation applies the constraints-based layout, otherwise it does nothing.


    /* -layoutMargins returns a set of insets from the edge of the view's bounds that denote a default spacing for laying out content.
     If preservesSuperviewLayoutMargins is YES, margins cascade down the view tree, adjusting for geometry offsets, so that setting
     the left value of layoutMargins on a superview will affect the left value of layoutMargins for subviews positioned close to the
     left edge of their superview's bounds
       If your view subclass uses layoutMargins in its layout or drawing, override -layoutMarginsDidChange in order to refresh your 
     view if the margins change.
       On iOS 11.0 and later, please support both user interface layout directions by setting the directionalLayoutMargins property
     instead of the layoutMargins property. After setting the directionalLayoutMargins property, the values in the left and right
     fields of the layoutMargins property will depend on the user interface layout direction.
     */

关于ios - UINavigationBar 底部边框消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50247387/

相关文章:

java - 通过避免在特定场景中重写 java 父类(super class)方法来重新使用父类(super class)方法

ios - 点击区域时不显示本地通知

ios - 单击自定义 UITableView 部分标题调用 didSelectRow : on first row of the section

ios - 访问字典中的字典

iphone - 如何复制此用户界面设计?

iOS-Charts 分组条形图,大小适合

ios - Popover 适配内容大小 IOS

c# - 实现接口(interface)返回类型协方差可能存在哪些困难?

具有通用类型的快速扩展函数 - isEmpty for FetchedResults

c# - 为什么我重写的 Dispose 没有被调用?