UINavigationBar背景图像,具有scaleAspectFill行为 [英] UINavigationBar background image with scaleAspectFill-like behavior

查看:109
本文介绍了UINavigationBar背景图像,具有scaleAspectFill行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

tl;博士

我正在尝试为UINavigationBar设置背景图像.有没有办法配置导航栏,使其使用类似scaleAspectFill的行为(作为UIImageView,并且contentMode设置为scaleAspectFill)?

I'm trying to set a background image for a UINavigationBar. Is there a way to configure the navbar so that it uses scaleAspectFill-like behavior (as a UIImageView with contentMode set to scaleAspectFill)?

目标

我有一个图像大致适合横向iPhone的导航栏尺寸(64pt高度,约800pt宽度;不过确切的尺寸在这里应该无关紧要),这是我用navigationBar.setBackgroundImage(img, for: .default)设置的.图像是模糊的照片,因此不需要像素完美.顺便说一句-我正在使用UINavigationBar.appearance一次设置所有导航栏的背景.

I have an image roughly fitting the navbar dimension of a landscape iPhone (64pt height, about 800pt width; the exact dimension should not matter here though), which I set with navigationBar.setBackgroundImage(img, for: .default). The image is a blurred photo, so no need for pixel-perfection. Btw -- I'm using UINavigationBar.appearance to set the background for all navbars at once.

  1. 我想做的事情:在纵向显示时显示图像的中心部分,而在横向显示时显示完整图像而不会裁切.如果高度不完全匹配(如iPhone X预期的那样),则应将其向上扩展一点以填补额外的高度.

  1. What I'd like it to do: show the center part of the image when in portrait orientation, and show the full image without cropping when in landscape orientation. If the height doesn't match up exactly (as is to be expected on iPhone X) it should scale up a bit to fill the additional height.

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

As fallback solution I'd also accept if an image of lesser width is shown centered and fills up the additional horizontal space by stretching the first and last pixel column.

到目前为止我尝试过的事情

  • 目标1:设置UINavigationBarcontentMode –渲染图像时似乎被忽略
  • 目标2:使用较小的图像并通过stretchableImage(withLeftCapWidth:topCapHeight:)使其可拉伸-填充导航栏,但图像被推到右下角(显然是因为此方法仅将左和上边缘视为可拉伸的边距)
  • 目标2:使用较小的图像,并使其在resizableImage(withCapInsets:resizingMode:)resizingMode设置为stretch的情况下可调整大小-在横向中,它仅将图像拉伸到全宽,而忽略了帽盖嵌接(可能这种方法不会按照我的想法做.)
  • Goal 1: setting the contentMode of UINavigationBar -- seems to be ignored when rendering the image
  • Goal 2: using a smaller image and making it strechable with stretchableImage(withLeftCapWidth:topCapHeight:) -- fills the navbar but the image is pushed to the right bottom (apparently because this method only considers left and top as strechable margins)
  • Goal 2: using a smaller image and making it resizable with resizableImage(withCapInsets:resizingMode:) with resizingMode set to stretch -- in landscape it just stretches the image to full width, ignoring the cap insets (probably this method does not do what I think).

推荐答案

通过在UINavigationController的视图中添加图像视图来解决,如此处.图像视图分别附加在导航控制器视图的顶部,左侧和右侧以及导航条的底部.

Solved by adding an image view to the UINavigationController's view, as described here. The image view is attached to the top, left and right of the nav controller's view and to the bottom of the navbar.

与文章中的示例相反,我不使用自定义导航栏;而是使用自定义导航栏.相反,我将图像视图插入现有导航栏的后面.请注意,导航栏必须透明才能完成这项工作.另外,必须裁剪图像视图,否则它会奇怪地扩展到导航栏的底部.

In contrast to the example in the article, I don't use a custom navigation bar; instead I insert the image view behind the existing navbar. Note that the navbar has to be transparent to make this work. Also, the image view has to be clipped, else it strangely extends beyond the navbar's bottom.

也许这可能对其他人有帮助,所以这里是一些代码(应该只在一次上应用到nav控制器,因此,最好将此代码放在子类中而不是在扩展程序):

Maybe this can be of help to someone else, so here's some code (this should only be applied once to a nav controller, so maybe you are better off putting this code in a subclass than in an extension):

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)
    ])
  }
}

这篇关于UINavigationBar背景图像,具有scaleAspectFill行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆