Change iOS status bar color in ionic 2 app

2019-04-10 21:39发布

I am following the ionic 2 documentation for setting the iOS status bar color but it is not working. The status bar text is white which means on my white background it is invisible.

The code I have put in my app constructor is:

    StatusBar.overlaysWebView(true);
    StatusBar.styleDefault();

I have imported StatusBar using:

import {StatusBar} from 'ionic-native';

I have also checked that the cordova statusbar plugin is installed.

2条回答
我想做一个坏孩纸
2楼-- · 2019-04-10 22:19

You can try like this add this in the config.xml, with the hex value of the color you want to set:

<preference name="StatusBarOverlaysWebView" value="false" />
<preference name="StatusBarBackgroundColor" value="#000000" />

For ngCordova or ionic-native you can use

  $cordovaStatusbar.styleColor('black');

  $cordovaStatusbar.styleHex('#000');


Or you check on the statusbar cordova plugin github page there are some ways to change the color of status bar: https://github.com/apache/cordova-plugin-statusbar

For Android:

if (cordova.platformId == 'android') {
    StatusBar.backgroundColorByHexString("#333");
}

For iOS

On iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by color name.

StatusBar.backgroundColorByName("red");

Supported color names are:

black, darkGray, lightGray, white, gray, red, green, blue, cyan, yellow, magenta, orange, purple, brown

Or
Sets the background color of the statusbar by a hex string.

StatusBar.backgroundColorByHexString("#C0C0C0");

CSS shorthand properties are also supported.

StatusBar.backgroundColorByHexString("#333"); // => #333333
StatusBar.backgroundColorByHexString("#FAB"); // => #FFAABB
On iOS 7, when you set StatusBar.statusBarOverlaysWebView to false, you can set the background color of the statusbar by a hex string (#RRGGBB).

On WP7 and WP8 you can also specify values as #AARRGGBB, where AA is an alpha value

查看更多
Explosion°爆炸
3楼-- · 2019-04-10 22:24

All you need to do is include this directive in your app.module.ts (or whatever it is called).

This will handle status bar text color behavior dynamically through the whole application (no need to worry when and where to set something):

import { Directive, ElementRef, OnDestroy, OnInit, Optional } from '@angular/core'
import { StatusBar } from '@ionic-native/status-bar'
import { Platform, ViewController } from 'ionic-angular'

@Directive({
  /* tslint:disable */
  selector: "ion-header",
  /* tslint:enable */
})
export class DynamicStatusBarDirective implements OnInit, OnDestroy {
  public static isColorTooLight(colorString) {
    let rgb = DynamicStatusBarDirective.getRgbColor(colorString)

    if (rgb.a || (rgb.a < 0.2)) { // becoming too transparent
      return true
    }

    // contrast computation algorithm/approach: https://24ways.org/2010/calculating-color-contrast
    let yiq = ((rgb.r * 299) + (rgb.g * 587) + (rgb.b * 114)) / 1000
    return yiq >= 128
  }

  public static getRgbColor(colorString): RGB {
    if (!colorString) {
      return null
    }

    let rgb: RGB = new RGB()

    if (colorString[ 0 ] === '#') { // seems hex color
      rgb.r = parseInt(colorString.substr(0, 2), 16)
      rgb.g = parseInt(colorString.substr(2, 2), 16)
      rgb.b = parseInt(colorString.substr(4, 2), 16)
    } else {
      let matchColors = /rgba?\(((25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*,\s*?){2}(25[0-5]|2[0-4]\d|1\d{1,2}|\d\d?)\s*,?\s*([01]\.?\d*?)?\)/
      let colors = matchColors.exec(colorString)
      if (colors) {
        rgb.r = parseInt(colors[ 1 ], 10)
        rgb.g = parseInt(colors[ 2 ], 10)
        rgb.b = parseInt(colors[ 3 ], 10)

        if (colors[ 4 ]) { // has transparency
          rgb.a = parseInt(colors[ 4 ], 10)
        }
      }
    }

    return rgb
  }

  public static getModalParent(nativeElm) {
    return nativeElm
      .parentNode // modal
      .parentNode // modal wrapper
      .parentNode // ion-modal
      .parentNode // ion-app, which handles background status bar
  }

  public static getHeaderBackgroundForMobile(nativeElm) {
    let header = nativeElm.querySelector('.toolbar-background')
    return window.getComputedStyle(header).backgroundColor
  }

  public ionViewEnterCallback: Function
  public modalCloseCallback: Function

  constructor(
    public platform: Platform,
    public statusBar: StatusBar,
    public elm: ElementRef,
    @Optional() public viewCtrl: ViewController,
  ) {
  }

  public ngOnInit(): void {
    this.ionViewEnterCallback = () => this.checkStatusBar()
    if (this.viewCtrl) {
      this.viewCtrl.willEnter.subscribe(this.ionViewEnterCallback)
    }
  }

  public ngOnDestroy(): void {
    this.viewCtrl.willEnter.unsubscribe()
    this.viewCtrl.didLeave.unsubscribe()
  }

  public checkStatusBar(): void {
    if (!this.platform.is('ios')) {
      return
    }

    let nativeElm = this.elm.nativeElement

    if (this.viewCtrl.isOverlay) { // dealing with modal
      let parentNativeElm = DynamicStatusBarDirective.getModalParent(nativeElm)

      if (parentNativeElm) { // modal is open
        this.modalCloseCallback = () => this.setColor(window.getComputedStyle(parentNativeElm).backgroundColor)

        this.viewCtrl.didLeave.subscribe(this.modalCloseCallback)
      }

      if (this.platform.is('tablet')) {
        this.setColor(true) // for modals we are getting grey overlay, so need to set white background
        return
      }
    }

    let background = DynamicStatusBarDirective.getHeaderBackgroundForMobile(nativeElm)

    if (background) {
      this.setColor(background)
    }

  }

  public setColor(background: any): void {
    let isTooLight = DynamicStatusBarDirective.isColorTooLight(background)

    if (isTooLight) {
      this.statusBar.styleDefault()
    } else {
      this.statusBar.styleBlackTranslucent()
    }
  }
}

class RGB {
  r: number
  g: number
  b: number
  a?: number
}
查看更多
登录 后发表回答