LoginSignup
3
3

More than 5 years have passed since last update.

iOSでナビゲーションバーとステータスバーの色を別々に設定する

Posted at

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を作ったりすることが無いことです。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3