1. ナビゲーションバーのtintColorにステータスバーの色を設定する
if let navigationBar = navigationController?.navigationBar {
navigationBar.tintColor = /* any color */
}
2. ステータスバーとナビゲーションバーをあわせた領域の透過画像を生成する
色から画像を作る関数
func createImage(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
UIColor.clear.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
let baseImageSize = CGSize(
widht: UIScreen.main.widht,
height: navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
)
let baseImage = createImage(color: .clear, size: baseImageSize)
3. ナビゲーションバー部の色を持つ画像をナビゲーションバーのサイズで生成する
let navigationBarImageSize = CGSize(
widht: UIScreen.main.widht,
height: navigationBar.frame.height
)
let navigationBarImage = createImage(color: .clear, size: baseImageSize)
4. 2と3で生成した画像を合成する
画像を合成する関数
func composeImage(_ image: UIImage, to baseImage: UIImage, position: CGPoint) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let baseRect = CGRect(origin: .zero, size: baseImage.size)
baseImage.draw(in: baseRect)
let composeRect = CGRect(origin: position, size: image.size)
image.draw(in: composeRect)
let composedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return composedImage
}
let composePosition = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height)
let composedIamge = composeImage(navigationBarImage, to: baseImage, position: composePosition)
5. 4で生成した画像をナビゲーションバーの背景画像に設定する
navigationBar.setBackgroundImage(composedIamge, for: .default)
6. 完成!
これで完成です。
トータルのコードはこのようになります。
func createImage(color: UIColor, size: CGSize) -> UIImage {
let rect = CGRect(origin: .zero, size: size)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
UIColor.clear.setFill()
UIRectFill(rect)
let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
func composeImage(_ image: UIImage, to baseImage: UIImage, position: CGPoint) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let baseRect = CGRect(origin: .zero, size: baseImage.size)
baseImage.draw(in: baseRect)
let composeRect = CGRect(origin: position, size: image.size)
image.draw(in: composeRect)
let composedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return composedImage
}
if let navigationBar = navigationController?.navigationBar {
navigationBar.tintColor = /* any color */
let baseImageSize = CGSize(
widht: UIScreen.main.widht,
height: navigationBar.frame.height + UIApplication.shared.statusBarFrame.height
)
let baseImage = createImage(color: .clear, size: baseImageSize)
let navigationBarImageSize = CGSize(
widht: UIScreen.main.widht,
height: navigationBar.frame.height
)
let navigationBarImage = createImage(color: /* any color */, size: baseImageSize)
let composePosition = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.height)
let composedIamge = composeImage(navigationBarImage, to: baseImage, position: composePosition)
navigationBar.setBackgroundImage(composedIamge, for: .default)
}
この方法を利用する利点は、NabigationBarの範囲で色分けが完遂出来るので余計なViewを作ったりすることが無いことです。