具有scaleAspectFill类似行为的UINavigationBar背景图像

时间:2018-02-08 11:48:54

标签: ios swift uiimage uinavigationbar

TL;博士

我试图为UINavigationBar设置背景图片。有没有办法配置导航栏以便它使用scaleAspectFill类行为(UIImageView contentMode设置为scaleAspectFill)?

目标

我的图像大致符合风景iPhone的导航栏尺寸(64pt高度,宽度约为800pt;但确切的尺寸在这里并不重要),我用navigationBar.setBackgroundImage(img, for: .default)设置。图像是模糊的照片,因此不需要像素完美。顺便说一下 - 我使用UINavigationBar.appearance一次设置所有导航栏的背景。

  1. 我喜欢它做什么:在纵向方向显示图像的中心部分,并在横向方向显示完整图像而不进行裁剪。如果高度没有完全匹配(正如在iPhone X上预期的那样),它应该向上扩展一点以填充额外的高度。

  2. 作为后备解决方案,如果宽度较小的图像居中显示并通过拉伸第一个和最后一个像素列填充额外的水平空间,我也会接受。

  3. 到目前为止我尝试了什么

    • 目标1:设置contentMode的{​​{1}} - 渲染图片时似乎被忽略
    • 目标2:使用较小的图像并使其可以使用UINavigationBar进行拉伸 - 填充导航栏但图像被推到右下角(显然因为此方法仅将左侧和顶部视为可拉伸的边距)
    • 目标2:使用较小的图片,并使stretchableImage(withLeftCapWidth:topCapHeight:) resizableImage(withCapInsets:resizingMode:)设置为resizingMode,使其可调整大小 - 在横向中,它只是将图像拉伸到全宽,忽略了上限(可能这种方法不符合我的想法。)

2 个答案:

答案 0 :(得分:2)

通过向UINavigationController视图添加图片视图解决问题,如here所述。图像视图附加到导航控制器视图的顶部,左侧和右侧以及导航栏的底部。

与文章中的示例相比,我不使用自定义导航栏;相反,我将图像视图插入现有导航栏后面。请注意,导航栏必须透明才能使其正常工作。此外,图像视图必须被剪裁,否则奇怪地延伸到导航栏的底部。

也许这对其他人有帮助,所以这里有一些代码(这应该只是一次应用到一个导航控制器,所以也许你最好把这个代码放在子类中而不是延期):

extension UINavigationController {
  func setBackgroundImage(_ image: UIImage) {
    navigationBar.isTranslucent = true
    navigationBar.barStyle = .blackTranslucent

    let logoImageView = UIImageView(image: image)
    logoImageView.contentMode = .scaleAspectFill
    logoImageView.clipsToBounds = true
    logoImageView.translatesAutoresizingMaskIntoConstraints = false

    view.insertSubview(logoImageView, belowSubview: navigationBar)
    NSLayoutConstraint.activate([
      logoImageView.leftAnchor.constraint(equalTo: view.leftAnchor),
      logoImageView.rightAnchor.constraint(equalTo: view.rightAnchor),
      logoImageView.topAnchor.constraint(equalTo: view.topAnchor),
      logoImageView.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor)
    ])
  }
}

答案 1 :(得分:1)

您可以尝试直接在UIImageView内添加contentMode = .scaleAspectFillUINavigationBar,这样做:

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let imgView = UIImageView(image: UIImage(named: "desert"))
        imgView.contentMode = .scaleAspectFill
        imgView.frame = self.navigationController!.navigationBar.frame
        self.navigationController?.navigationBar.addSubview(imgView)
        self.navigationController?.navigationBar.sendSubview(toBack: imgView)
    }
}

结果是:

enter image description here