it-swarm.com.ru

Изменить значение альфа на панели навигации

Это возможно?

Я хочу изменить альфа-значение навигационной панели в моем контроллере представления (в анимации), но если я сделаю self.navigationController.navigationBar.alpha = 0.0;, часть экрана, которую занимал навигационная панель, полностью исчезнет и выйдет из черного ящика, а это не то, что я мне нравится (я бы предпочел, чтобы это был цвет фона self.view).

14
Doug Smith

Поддерживая ответ Колина, я хочу дать вам дополнительную подсказку, чтобы настроить внешний вид UINavigationBar, включая альфа.

Хитрость заключается в использовании UIAppearance для вашего NavigationBar. Это позволяет вам назначить UIImage для вашего NavigationBar's backgroundImage . Вы можете сгенерировать эти UIImages программно и использовать для них UIColors и установить свойства альфа-цвета , как вы хотите. Я сделал это в одном из моих собственных приложений, и он работает, как ожидалось.

Здесь я даю вам некоторые фрагменты кода :

  1. Например. в вашем ..AppDelegate.m добавьте эти строки в didFinishLaunchingWithOptions:

    //create background images for the navigation bar
    UIImage *gradientImage44 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for portrait orientation
    UIImage *gradientImage32 = nil; //replace "nil" with your method to programmatically create a UIImage object with transparent colors for landscape orientation
    
    //customize the appearance of UINavigationBar
    [[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
    [[UINavigationBar appearance] setBarStyle:UIBarStyleDefault];
    
  2. Реализуйте удобные методы для программного создания объектов UIImage, например, создать новую категорию для UIImage:

    //UIImage+initWithColor.h
    //
    #import <UIKit/UIKit.h>
    
    @interface UIImage (initWithColor)
    
    //programmatically create an UIImage with 1 pixel of a given color
    + (UIImage *)imageWithColor:(UIColor *)color;
    
    //implement additional methods here to create images with gradients etc.
    //[..]
    
    @end
    
    //UIImage+initWithColor.m
    //
    #import "UIImage+initWithColor.h"
    #import <QuartzCore/QuartzCore.h>
    
    @implementation UIImage (initWithColor)
    
    + (UIImage *)imageWithColor:(UIColor *)color
    {
        CGRect rect = CGRectMake(0, 0, 1, 1);
    
        // create a 1 by 1 pixel context 
        UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0);
        [color setFill];
        UIRectFill(rect);
    
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }
    
  3. Переработайте создание вашего образа в 1. (#import "UIImage + initWithColor.h" в AppDelegate.m и замените "nil"):

Это ваш интерес: изменяя альфа-свойство ваших цветов, вы также влияете на уровень непрозрачности NavigationBar!

            UIImage *gradientImage44 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];
            UIImage *gradientImage32 = [UIImage imageWithColor:[UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.2]];

Я создал небольшой демонстрационный проект и добавлю вам два скриншота : Сам вид имеет желтый backgroundColor . BackgroundImages панели навигации имеют красный цвет . Скриншот 1 показывает панель навигации со значением для альфа = 0,2 . На снимке экрана 2 показана панель навигации со значением для альфа = 0,8.

Screenshot for NavigationBar with alpha=0.2Screenshot for NavigationBar with alpha=0.8

20
Computerspezl

Самый простой способ сделать это - изменить альфа-компонент фонового представления navigationBar, который в настоящее время (iOS9) является первым подпредставлением навигационной панели. Однако обратите внимание, что мы никогда не знаем, изменится ли иерархия подпредставления Apple в более поздних выпусках, поэтому нужно быть осторожным.

let navigationBackgroundView = self.navigationController?.navigationBar.subviews.first
navigationBackgroundView?.alpha = 0.7
7
ambientlight

Непосредственно из ссылки Apple Developer: 

«Существует только несколько прямых настроек, которые вы можете сделать для панели навигации В частности, можно изменять свойства barStyle, tintColor и translucent, но вы никогда не должны напрямую изменять UIView- свойства уровня, такие как свойства frame, bounds, alpha или hidden. "

Однако вы можете установить свойство прозрачности на панели навигации. Если вы делаете [self.navigationController.navigationBar setTranslucent:YES];, Это должно решить вашу проблему. Вы также можете попытаться узнать, подходит ли какое-либо из перечислений UIBarStyle.

6
Colin

MickBraun ответ в Swift:

  1. В AppDelegate.Swift добавьте эти строки в didFinishLaunchingWithOptions:

    // create background images for the navigation bar
    let gradientImage44 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
    let gradientImage32 = UIImage.imageWithColor(UIColor(red: 1.0, green: 0.0, blue: 1.0, alpha: 0.2))
    
    // customize the appearance of UINavigationBar
    UINavigationBar.appearance().setBackgroundImage(gradientImage44, forBarMetrics: .Default)
    UINavigationBar.appearance().setBackgroundImage(gradientImage32, forBarMetrics: .Compact)
    UINavigationBar.appearance().barStyle = .Default
    
  2. Реализуйте удобные методы для программного создания объектов UIImage.

    class func imageWithColor(colour: UIColor) -> UIImage {
        let rect = CGRectMake(0, 0, 1, 1)
    
        // Create a 1 by 1 pixel content
        UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
        colour.setFill()
        UIRectFill(rect)
    
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    
        return image
    }
    
2
Allanah Douglas

У вас есть несколько вариантов, частично зависящих от barStyle вашего UINavigationBar. Главное понять, что вам, вероятно, не обязательно анимировать свойство alpha, чтобы получить эффект, который вы описываете.

UIBarStyleDefault или UIBarStyleBlackOpaque Опция A - установить для полупрозрачного свойства UINavigationBar значение YES, а затем анимировать альфа:

            navigationBar.translucent = YES; // ideally set this early, in the nib/storyboard, or viewDidLoad

...

            [UIView animateWithDuration: 1.0
                             animations: ^{

                                 // toggle:
                                 navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;

                             }];

В этом сценарии ваше представление будет располагаться за панелью навигации, даже если его альфа равен 1.0. Недостатком этого сценария является то, что даже с альфа-версией 1.0 вы можете увидеть оттенок цвета фона вашего представления за UINavigationBar. Кроме того, все ваши подпредставления должны быть расположены на 44 пункта сверху вниз.

UIBarStyleDefault или UIBarStyleBlackOpaque Опция B - скрыть панель навигации в анимации перехода с перекрестным разделением. Это откроет супервизор UINavigationBar. Если вы используете UINavigationController, тогда черный фон представления UINavigationController - это то, что вы увидите, но вы можете установить цвет фона представления UINavigationController в соответствии с вашим представлением, чтобы получить желаемый эффект:

    UINavigationBar* navigationBar = self.navigationController.navigationBar;

    self.navigationController.view.backgroundColor = self.view.backgroundColor;
    [UIView transitionWithView: navigationBar
                      duration: 1.0
                       options: UIViewAnimationOptionTransitionCrossDissolve
                    animations: ^{
                        // toggle:
                        navigationBar.hidden = !navigationBar.hidden;
                    }
                    completion: nil];

В этом решении следует обратить внимание на проблему с макетом, если UINavigationController обновляет фрейм вида, потому что вы скрыли UINavigationBar. Это было бы хорошо, за исключением того, что ваши подпредставления могут сместиться вверх на 44 пикселя, если они привязаны к верхнему левому углу. Чтобы обойти это, вы можете вместо этого привязать ваши подпредставления к нижней части вашего представления (либо с пружинами, либо с ограничениями макета).

UIBarStyleDefault или UIBarStyleBlackOpaque Опция C заключается в том, чтобы прикрыть UINavigationBar другим представлением, снова используя перекрестную анимацию перехода:

        UINavigationBar* navigationBar = self.navigationController.navigationBar;

        [UIView transitionWithView: navigationBar
                          duration: 1.0
                           options: UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowAnimatedContent
                        animations: ^{

                            // toggle:
                            const int tag = 1111; 
                            UIView* navOverlayView = [navigationBar viewWithTag: tag];
                            if ( navOverlayView == nil )
                            {
                                navOverlayView = [[UIView alloc] initWithFrame: CGRectInset( navigationBar.bounds, 0, -3 ) ];
                                navOverlayView.backgroundColor = self.view.backgroundColor;
                                navOverlayView.tag = tag;
                                [navigationBar addSubview: navOverlayView];
                            }
                            else
                            {
                                [navOverlayView removeFromSuperview];
                            }
                        }
                        completion: nil];

UIBarStyleBlackTranslucent : Эта опция самая простая, так как UINavigationBar уже полупрозрачен, и ваше представление уже позади. Просто оживите альфу:

    [UIView animateWithDuration: 1.0
                     animations: ^{

                         // toggle:
                         navigationBar.alpha = navigationBar.alpha == 0 ? 1.0 : 0.0;

                     }];
1
TomSwift

Если вы просто хотите избавиться от navigationBar анимированным способом, вы можете сделать следующее:

[self.navigationController setNavigationBarHidden:YES animated:YES];

Если вы хотите управлять анимацией и необходимо установить для alpha значение 0.0, читайте дальше:

«Черный ящик», который вы видите, находится в нижележащем окне или окне. Если вы просто хотите, чтобы цвет вашего вида вместо «черного ящика», сделайте:

self.navigationController.view.backgroundColor = self.view.backgroundColor;

[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
    self.navigationController.navigationBar.alpha = 0.0;
} completion:NULL];

Если вы хотите, чтобы ваш фактический вид находился там, где был navigationBar, вам нужно увеличить height вашего вида:

[UIView animateWithDuration:1.0 delay:1.0 options:0 animations:^{
    self.navigationController.navigationBar.alpha = 0.0;

    CGFloat navigationBarHeight = self.navigationController.navigationBar.frame.size.height;

    CGRect frame = self.view.frame;
    frame.Origin.y -= navigationBarHeight;
    frame.size.height += navigationBarHeight;
    self.view.frame = frame;
} completion:NULL];
1
Danilo

Swift3

var navAlpha = // Your appropriate calculation   
self.navigationController!.navigationBar.backgroundColor =  UIColor.red.withAlphaComponent(navAlpha)
0
Deven

Вы также можете попытаться установить фоновое представление под панелью навигации и изменить это представление напрямую.

private lazy var backgroundView: UIView = UIView()

...

private func setupNavigationBarBackground() {
    guard let navigationBar = navigationController?.navigationBar else { return }
    navigationBar.setBackgroundImage(UIImage(), for: .default)
    navigationBar.isTranslucent = true
    view.addSubview(backgroundView)
    backgroundView.alpha = 0
    backgroundView.backgroundColor = .red
    backgroundView.translatesAutoresizingMaskIntoConstraints = false
    backgroundView.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor).isActive = true
    backgroundView.bottomAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
    backgroundView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    backgroundView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
}

private func changeNavigationBarAlpha(to alpha: CGFloat) {
    backgroundView.alpha = alpha
}
0
GaétanZ

Это должно дать вам желаемый эффект:

self.navigationController.navigationBar.alpha = 0.0;
self.navigationController.navigationBar.frame = CGRectMake(0,0,320,0);

Не пробовал это в анимации, работает в моем viewDidAppear, хотя, надеюсь, это работает.

0
JustAnotherCoder