UINavigationBar底部边框消失



我正在子类化UINavigationBar,在界面生成器中,我使用身份检查器将其设置为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. 在界面生成器中向栏添加 1px 高度的子视图。

附言:不要在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.
*/

最新更新