到目前为止,我通过以下方式处理导航栏中的渐变_
let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor(hex:"92CF1F").cgColor, UIColor(hex:"79AB1B").cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().isTranslucent = false
UINavigationBar.appearance().clipsToBounds = false
if DeviceType.IS_IPAD{
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : UIFont .systemFont(ofSize: 24, weight: UIFontWeightLight), NSForegroundColorAttributeName: UIColor.white]
}
else
{
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : UIFont .systemFont(ofSize: 20, weight: UIFontWeightLight), NSForegroundColorAttributeName: UIColor.white]
}
UISearchBar.appearance().backgroundColor = UIColor.clear
但是现在在iPhone X中我有问题,因为“64”作为梯度的导航栏高度如下_
请建议针对此进行修复,以便在每种情况下动态使用。
答案 0 :(得分:4)
使用Alisson Barauna对您的问题的回答,我设法通过更新我的UINavigationBar扩展来解决这个问题,如下所示:
extension UINavigationBar {
@objc func setGradientBackground(colors: [UIColor]) {
var updatedFrame = bounds
if UIDevice().userInterfaceIdiom == .phone {
if UIScreen.main.nativeBounds.height == 2436{
updatedFrame.size.height += 44
} else {
updatedFrame.size.height += 20
}
}
let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)
setBackgroundImage(gradientLayer.createGradientImage(), for: UIBarMetrics.default)
}
通过这样做,如果程序检测到正在使用iPhone X(屏幕高度为2436),则高度将设置为较大的iPhone X尺寸(44)。
答案 1 :(得分:1)
我已经通过屏幕高度检查了iPhone X模式,然后我更改了生成的渐变图像以填充导航栏。 我认为这不是最好的解决方法,但它现在工作正常。
class func checkiPhoneModel() -> String {
if UIDevice().userInterfaceIdiom == .phone {
switch UIScreen.main.nativeBounds.height {
case 1136:
return "5, 5s, 5c, se"
case 1334:
return "6, 6s, 7"
case 2208:
return "6+, 6S+, 7+"
case 2436:
return "X"
default:
return "unknown"
}
}
return ""
}
然后你可以为UINavigationBar创建一个扩展,添加一个方法来改变渐变图像的颜色:
extension UINavigationBar {
func setGradientBackground(colors: [UIColor]) {
var size:CGFloat
if Reachability.checkiPhoneModel() == "X" {
size = 44
}
else {
size = 20
}
var updatedFrame = bounds
updatedFrame.size.height += size
let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)
setBackgroundImage(gradientLayer.creatGradientImage(), for: UIBarMetrics.default)
}
}
当iPhone X时,size var设置为44,而其他型号则为20。
然后在viewDidLoad上,只需调用最近创建的方法:
self.navigationController?.navigationBar.setGradientBackground(colors: [.red, .yellow])
答案 2 :(得分:0)
您不仅不能再认为导航栏高度为64,而且不能再假设静态高度。
我认为,实现您尝试做的最简单的方法是使用UINavigationController
init(navigationBarClass:toolbarClass:)
方法和覆盖UINavigationBar
的自定义layerClass
子类{1}}直接指定您的CAGradientLayer
。
不幸的是,我认为没有办法解雇和忘记"这与UIAppearance
。
答案 3 :(得分:0)
如何使用UIImage.resizableImage()
拉伸图像,如下所示:
(这几乎是完美的解决方案)
open class NavigationController: UINavigationController {
var gradientColors = [UIColor]() {
didSet {
updateGradient()
}
}
open func updateGradient() {
guard gradientColors.count > 1 else {
// There has to be at least two colors to set gradient..
return
}
let gradient = CAGradientLayer()
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = gradientColors.map({ $0.cgColor })
if let gradientImage = gradient.snapshotImage() {
let image = gradientImage.resizableImage(withCapInsets: UIEdgeInsets(top: 1, left: 1, bottom: 1, right: 1), resizingMode: UIImage.ResizingMode.stretch)
UINavigationBar.appearance().setBackgroundImage(image, for: .default)
}
}
}
CALayer.snapshotImage()
实现:
public extension CALayer {
public func snapshotImage() -> UIImage? {
return UIGraphicsImageRenderer(bounds: frame).image { (imageContext) in
render(in: imageContext.cgContext)
}
}
}