Comment dessiner une UIToolbar ou UINavigationBar transparente dans iOS7

88

Je voudrais un tout transparent UIToolbaret / ou UINavigationBar. J'ai essayé les différentes incantations suggérées pour pré et post-iOS 5 mais aucune ne semble plus fonctionner.

Comment cela pourrait-il être accompli dans iOS 7?

Ben Packard
la source
Pour la postérité - J'utilisais par erreur self.edgesForExtendedLayout = UIRectEdgeNone, ce qui empêche la vue de s'étendre sous la barre d'outils.
Ben Packard

Réponses:

303

Swift 3 (iOS 10)

Transparent UIToolbar

self.toolbar.setBackgroundImage(UIImage(),
                                forToolbarPosition: .any,
                                barMetrics: .default)
self.toolbar.setShadowImage(UIImage(), forToolbarPosition: .any)

Transparent UINavigationBar

self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.isTranslucent = true

Swift <3

Transparent UIToolbar

self.toolbar.setBackgroundImage(UIImage(),
                                forToolbarPosition: UIBarPosition.Any,
                                barMetrics: UIBarMetrics.Default)
self.toolbar.setShadowImage(UIImage(),
                            forToolbarPosition: UIBarPosition.Any)

Transparent UINavigationBar

self.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: UIBarMetrics.Default)
self.navigationBar.shadowImage = UIImage()
self.navigationBar.translucent = true

Objectif c

Transparent UIToolbar

[self.toolbar setBackgroundImage:[UIImage new]
              forToolbarPosition:UIBarPositionAny
                      barMetrics:UIBarMetricsDefault];
[self.toolbar setShadowImage:[UIImage new]
          forToolbarPosition:UIBarPositionAny];

Transparent UINavigationBar

[self.navigationBar setBackgroundImage:[UIImage new]
                         forBarMetrics:UIBarMetricsDefault];
self.navigationBar.shadowImage = [UIImage new];
self.navigationBar.translucent = YES;

Discussion

Le réglage translucentsur YESdans la barre de navigation fait l'affaire, en raison d'un comportement décrit dans la UINavigationBardocumentation. Je vais rapporter ici le fragment pertinent:

Si vous définissez cette propriété sur YESsur une barre de navigation avec une image d'arrière-plan personnalisée opaque, la barre de navigation appliquera une opacité système inférieure à 1,0 à l'image.


Résultat final

résultat final

Gabriele Petronella
la source
1
Avez-vous confirmé que la version de la barre d'outils fonctionne sur iOS7? J'obtiens une barre d'outils sombre et un étrange scintillement sur la présentation.
Ben Packard
2
La capture d'écran provient du iOS 7simulateur
Gabriele Petronella
De plus, je viens d'exécuter une application de test sur mon iPhone 5 avec iOS 7 et cela fonctionne comme prévu.
Gabriele Petronella
1
Bien fait, tant de mauvaises / mauvaises façons de le faire là-bas sur SO
pfrank
2
Si vous utilisez edgeForExtendedLayout = UIRectEdgeNone, vous souhaiterez probablement implémenter des transitions personnalisées. Car sinon, lors de la poussée des vues, la transition par défaut créera un scintillement sombre sous la barre transparente pendant l'animation. Pour info, voici une ressource rapide pour une transition glissante de base: gist.github.com/ArtFeel/7690431
anna
8

Si vous souhaitez le faire via l'application entière, vous devez utiliser le proxy UIAppearance (iOS5 +):

UINavigationBar *navigationBarAppearance = [UINavigationBar appearance]; navigationBarAppearance.backgroundColor = [UIColor clearColor]; [navigationBarAppearance setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault]; navigationBarAppearance.shadowImage = [[UIImage alloc] init];

Documents: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAppearance_Protocol/Reference/Reference.html

Article: http://nshipster.com/uiappearance/

Adam Waite
la source
Juste une note pour les personnes qui regardent ceci - mettez ce code dans votre AppDelegate didFinishLaunchingWithOptions pour un moyen rapide et sale de l'appliquer.
Shaun F
Vous pouvez également définir ce proxy d'apparence pour qu'il ne fonctionne qu'avec des UINavigationControllersous-classes spécifiques , c'est-à-dire celles auxquelles vous souhaitez appliquer ce comportement.
Evan R
2

Essayer:

[navBar setBackgroundImage:[UIImage alloc] forBarMetrics:UIBarMetricsDefault];
Leo Natan
la source
0
@implementation MyCustomNavigationBar

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setup];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setup];
    }
    return self;
}

- (void)setup {
    [self setupBackground];
}

- (void)setupBackground {
    self.backgroundColor = [UIColor clearColor];
    self.tintColor = [UIColor clearColor];

    // make navigation bar overlap the content
    self.translucent = YES; 
    self.opaque = NO;

    // remove the default background image by replacing it with a clear image
    [self setBackgroundImage:[self.class maskedImage] forBarMetrics:UIBarMetricsDefault];

    // remove defualt bottom shadow
    [self setShadowImage: [UIImage new]]; 
}

+ (UIImage *)maskedImage {
    const float colorMask[6] = {222, 255, 222, 255, 222, 255};
    UIImage *img = [UIImage imageNamed:@"nav-white-pixel-bg.jpg"];
    return [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(img.CGImage, colorMask)];
}

@end
hurlé
la source
0

Quelque chose sur lequel je suis tombé par hasard, c'est que si je créais une sous UINavigationBar- classe puis créais une -(void)drawRect:méthode vide , j'obtiendrais une barre de navigation transparente. Je n'ai testé cela que sous iOS 7. *, mais cela semblait fonctionner!

Jakenberg
la source