Строка состояния iOS 7 сталкивается с панелью навигации

ios objective-c uinavigationcontroller uinavigationbar ios7

56743 просмотра

17 ответа

В моем приложении есть контроллер представления, на котором в раскадровке перетащена панель навигации. В iOS 6 все работало нормально, но в iOS 7 это выглядит так:

ios 7 строка состояния nav var

Строка состояния и панель навигации не должны сталкиваться друг с другом. Я видел много таких вопросов о переполнении стека, но они мне не сильно помогли.

Некоторые вопросы говорят, что я должен использовать это "self.edgesForExtendedLayout = UIRectEdgeNone;" но это не сработало. Некоторые говорят, что я должен удалить панель навигации и встроить ее в контроллер навигации, чего я не могу сделать из-за того, как реализована моя программа. Некоторые решения предлагают использовать границы просмотра и все, но это не сработало и для меня.

Что может помочь мне решить эту проблему? Заранее спасибо!

ОБНОВЛЕНИЕ: я встроил контроллер представления в контроллер навигации. Убрана панель навигации, ранее добавленная в нее вручную. Теперь он выглядит нормально в раскадровке, но когда я запускаю его, он показывает следующее:

Панель навигации iOS 7

Он показывает текст из другого контроллера представления, который в настоящее время находится позади него, который является его родительским контроллером представления. Значит его прозрачный сейчас. Кто-нибудь может указать, что я делаю не так?

Автор: AJ112 Источник Размещён: 12.11.2019 09:09

Ответы (17)


66 плюса

Решение

Последняя версия iOS принесла много визуальных изменений, и с точки зрения разработчика навигация и строка состояния - это два заметных изменения.

Строка состояния теперь прозрачна, а панель навигации за ней просвечивает. Изображение панели навигации может быть даже расширено за строкой состояния.

Прежде всего, если вы новичок и только начали разработку iOS и не знаете, как работает строка состояния и панель навигации, вы можете просто просмотреть пост в блоге ЗДЕСЬ, который я считаю очень полезным. В нем есть вся информация, связанная с навигацией и строкой состояния в iOS 7.

Теперь приступим к ответу на ваш вопрос. Прежде всего, я вижу две разные проблемы. Во-первых, ваша строка состояния и панель навигации как бы сталкиваются друг с другом, как показано вами в вопросе с изображением.

ПРОБЛЕМА. Проблема в том, что ранее вы перетаскивали панель навигации в контроллере представления, который работал корректно в iOS 6, но с появлением iOS 7 SDK этот подход приводит к тому, что строка состояния и панель навигации перекрываются друг с другом.

Решение первой проблемы: Вы можете использовать UIBarPositionTopAttached или использовать границы и рамки просмотра, я также могу предложить и связать вас с документацией Apple и бла-бла-бла, но это займет некоторое время для решения проблемы.

Лучший и самый простой способ решить эту проблему - просто встроить свой контроллер представления в контроллер навигации, и все. Вы можете сделать это, просто выбрав контроллер представления и перейдя в «Редактор»> «Встроить»> «Контроллер навигации» . (Если на старой панели навигации есть какой-либо контент, вы можете сначала перетащить его вниз, встроить контроллер представления в контроллер навигации, а затем переместить кнопки панели на новую панель навигации и затем удалить старую панель навигации)

Решение второй проблемы: Это решение предназначено для вашего конкретного вопроса, который вы упомянули в обновлении, и не предназначено для широкой публики, читающего это. Как видите, панель навигации и состояния не видна, а в прозрачной области показан родительский контроллер представления. Я не совсем понимаю, почему вы столкнулись с этой проблемой, но, скорее всего, из-за какой-либо сторонней библиотеки, например ECSlidingView или любой другой. Вы можете выбрать этот контроллер представления в своей раскадровке и установить цвет фона представления таким же, как на панели навигации. Это перестанет показывать родительский контроллер представления позади, и ваша панель навигации и строка состояния начнут отображаться. Теперь вы можете покрыть остальную часть вашего контроллера представления текстовым представлением или тем, что вы когда-либо используете в нем.

Надеюсь это поможет!

Автор: KC. Размещён: 09.10.2013 01:49

33 плюса

Панель навигации находится слишком близко к строке состояния, потому что, начиная с iOS 7, строка состояния является скорее наложением на представление контроллера всего представления. Поскольку ваша панель навигации имеет значение (0, 0), строка состояния будет отображаться в верхней части панели навигации. Чтобы решить эту проблему, просто переместите панель навигации вниз (или, как уже говорили другие), создайте ограничение между панелью навигации и topLayoutGuide.

Когда вы сделаете это, вы увидите, что теперь между панелью навигации и верхней частью экрана есть разрыв в 20 пунктов. Это потому, что вы только что переместили панель навигации вниз на 20 пунктов. "Но UINavigationControllerмогу сделать это правильно!" Абсолютно, и это делается путем реализации UIBarPositioningDelegateна вашем контроллере представления. Это протокол с одним методом, который должен быть реализован следующим образом:

- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
    return UIBarPositionTopAttached;
}

После добавления контроллера представления в качестве делегата для панели навигации вы заметите, что панель навигации все еще смещена на 20 пунктов вниз, но ее фон будет расширяться под строкой состояния, как и в UINavigationController.

Еще одна вещь, которую вы видите, это то, что панель навигации является полупрозрачной, то есть все, что находится под панелью навигации, будет в некоторой степени видимым. translucentСобственности на UINavigationBarустановлен в YESпо умолчанию прошивки 7. Перед прошивкой 7, по умолчанию было NO.

Автор: Scott Berrevoets Размещён: 03.10.2013 03:14

4 плюса

Вы можете просто сделать это:

1) добавить ограничение между панелью навигации и верхним руководством по макету (выберите навигационную панель, удерживайте клавишу Ctrl и перейдите к «Нижнему руководству по макету», отмените удерживание клавиши Ctrl)

Добавить вертикальный Contrain

2) выберите расстояние по вертикали :

вертикальное расстояние

3) установить постоянную на 0 :

постоянная вертикального расстояния

Результат:

результат

ОБНОВИТЬ

В вашем файле AppDelegate вы можете добавить это:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool 
{
  // Prevent Navigationbar to cover the view
  UINavigationBar.appearance().translucent = false
}
Автор: Masterfego Размещён: 09.03.2015 04:16

3 плюса

Я предлагаю вам в вашем методе viewDidLoad вы пытаетесь:

self.navigationController.navigationBar.translucent = NO;

(по умолчанию это да сейчас)

https://developer.apple.com/library/ios/documentation/uikit/reference/UINavigationBar_Class/Reference/UINavigationBar.html#//apple_ref/occ/instp/UINavigationBar/translucent

Автор: The dude Размещён: 03.10.2013 03:00

2 плюса

Это работает для меня, я надеюсь, вам тоже повезет :).
Добавьте ниже код на ваш взгляд.

-(void) viewDidLayoutSubviews
{
    CGRect tmpFram = self.navigationController.navigationBar.frame;
    tmpFram.origin.y += 20;
    self.navigationController.navigationBar.frame = tmpFram;
}

Это в основном меняет местоположение панели навигации.

Автор: Jageen Размещён: 03.10.2013 02:44

2 плюса

Это новая функция с IOS7. Вместо того, чтобы смотреть на 20 пикселей, панель навигации в IOS7 смотрит на 0 пикселей. В качестве решения сдвиньте весь вид вниз до 20 пикселей или вы можете использовать изображение для панели навигации с высотой 64 пикселя.

Автор: PgmFreek Размещён: 09.10.2013 10:00

2 плюса

Если это все еще кому-то помогает, это то, что мне помогло немного переместить панель навигации в iOS 7 и выше:

-(void)viewWillLayoutSubviews
{
    float iosVersion = 7.0;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= iosVersion) {
        // iOS 7+
        CGRect viewFrame = self.view.frame;
        viewFrame.origin.y += 10;
        self.view.frame = viewFrame;
    }
}

На устройстве с ios 6.1 и ниже панель навигации не изменится, как это было раньше.

И вот что я использовал, чтобы сделать содержимое строки состояния светлее:

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
Автор: derekg Размещён: 24.04.2014 05:15

2 плюса

Если ваш UIViewControllerНЕ в, UINavigationControllerи вы используете UIStoryBoard, вы можете установить «iOS 6/7 Deltas» на 20 для дельты Y, для каждого подпредставления, которое должно быть смещено от UIStatusBar.

введите описание изображения здесь

Автор: Nate Potter Размещён: 07.10.2014 10:15

2 плюса

Используя Swift :

Как сказал @Scott Berrevoets в своем ответе, вам необходимо реализовать метод positionForBarв протоколе UIBarPositioningDelegate, но так как UINavigationBarDelegateпротокол реализует этот протокол:

public protocol UINavigationBarDelegate : UIBarPositioningDelegate {
   ...
}

Вам нужно всего лишь установить delegateиз UINavigationBarвас установить с помощью раскадровки и реализовать метод , и это делается, как и в этом случае:

class ViewController: UIViewController, UINavigationBarDelegate {

   @IBOutlet weak var navigationBar: UINavigationBar!

   override func viewDidLoad() {
       super.viewDidLoad()
       self.navigationBar.delegate = self 
   }

   override func didReceiveMemoryWarning() {
       super.didReceiveMemoryWarning()
       // Dispose of any resources that can be recreated.
   }

   func positionForBar(bar: UIBarPositioning) -> UIBarPosition {
       return UIBarPosition.TopAttached
   }
}

ПРИМЕЧАНИЕ. Стоит упомянуть, что если вы установите положение оси Y на панели навигации, скажем, до 40 от вершины, то она будет вытягиваться снизу вверх из этой позиции, чтобы имитировать поведение, которое UINavigationControllerвам нужно установите 20 сверху.

Я надеюсь, что это поможет вам.

Автор: Victor Sigler Размещён: 14.04.2016 08:46

2 плюса

Сначала установите UIViewControllerBasedStatusBarAppearanceзначение NO в Info.plist. Тогда, в AppDelegate«S application:didFinishLaunchingWithOptions:метод дополнения:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
   [application setStatusBarStyle:UIStatusBarStyleLightContent];
   self.window.clipsToBounds = YES;
   self.window.frame = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height-20);
   self.window.bounds = CGRectMake(0, 20, self.window.frame.size.width, self.window.frame.size.height);
 }
 return YES;
Автор: PJR Размещён: 07.10.2013 01:12

1 плюс

В iOS 7 приложение занимает 100% размера экрана. Это не проблема. http://www.doubleencore.com/2013/09/developers-guide-to-the-ios-7-status-bar/

Автор: Amulya Размещён: 07.10.2013 12:42

1 плюс

в более раннем окне iOS начинается после строки состояния, а в iOS 7 окно начинается с 0px, в более ранней версии высота просмотра составляет 460 (iPhone 4s и более ранние версии) и 548 (iPhone 5), но в iOS 7 высота просмотра составляет 480 (iPhone 4s и более ранние версии) и 568 (iPhone 5 и более поздние версии), поэтому вы должны начать компоновку после 2 пикселей или начать просмотр с 20 пикселей.

Вы можете написать приведенный ниже код в rootviewcontroller или во всех viewcontroller для set view от 20px

#define IOS7_HEIGHT             64

- (void)viewDidLayoutSubviews {
    NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
    if ([currSysVer compare:@"7.0" options:NSNumericSearch] != NSOrderedAscending)
    {
        CGRect frame=[self.view frame];
        if (frame.origin.y!=IOS7_HEIGHT) {

            frame.origin.y = IOS7_HEIGHT;
            frame.size.height -= IOS7_HEIGHT;
            [self.view setFrame:frame];
            [self.view layoutSubviews];
        }
    }
}

здесь высота 64, потому что 20 для строки состояния и 44 для панели навигации. попробуйте код ниже, это поможет вам. и ваша проблема будет решена.

Автор: Pratik Размещён: 09.10.2013 08:23

1 плюс

Для тех, у кого есть проблемы с реализацией решения @Masterfego (которое также является официальным, но у меня были проблемы с Xcode 6.3 и автоматическими ограничениями), вот что я сделал:

У меня есть UIViewController с добавленной панелью навигации. Я выбрал панель навигации и добавил ограничение высоты 64 пикселя. Позже мы увидим предупреждение, что навигационная панель будет выше (но это то, что мы делаем). Наконец, вы можете видеть, что строка состояния выглядит красиво и имеет тот же цвет, что и панель навигации. :)

PS: я не могу размещать изображения еще.

Автор: cduguet Размещён: 28.04.2015 02:16

0 плюса

Вероятно, вы можете создать ограничения, которые прикреплены к верхнему руководству по макету, чтобы указать положение панели навигации относительно строки состояния. См. Руководство по переходу пользовательского интерфейса iOS 7: внешний вид и поведение для получения дополнительной информации об использовании руководств по макету.

Автор: Greg Размещён: 01.10.2013 12:00

0 плюса

это лучший ответ. Но я хотел знать, как использовать Storyboardи тянул UINavigationBarна это. Когда я реализовал метод делегата и установил возвращаемый результат UIBarPositionTopAttached, он не работал.

- (void)viewDidLoad{
    self.navigationbar.delegate = self;
}
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar{
    NSLog(@"Got it");
    //
    //    CGRect frame = self.navigaitonBar.frame;
    //
    //    frame = CGRectMake(0, 20, CGRectGetWidth(frame), CGRectGetHeight(frame));
    //    self.navigaitonBar.frame = frame;
    //
    //    NSLog(@"frame %f",frame.origin.y);
    return UIBarPositionTopAttached;
}
Автор: rbbtsn0w Размещён: 27.11.2013 07:30

0 плюса

Если вы используете Xcode 6 и Swift, вы можете сделать это:

  1. Откройте файл info.plist вашего приложения.
  2. Добавьте логический ключ ViewControllerBasedStatusBarAppearance, если он не существует, и присвойте значение «НЕТ».
  3. Добавьте клавишу «Стиль строки состояния», если она не существует, и выберите для нее значение «Непрозрачный черный стиль».
Автор: Alexsander Размещён: 23.03.2015 01:50

0 плюса

Я столкнулся с проблемой, когда ModalViewControllerс моего экрана открывался полный экран MainViewController, NavigationBarположение менялось, когда пользователь возвращался MainViewControllerиз ModalViewController.

Проблема, которую я заметил, это то, что высота строки состояния не была включена, когда пользователь вернулся MainViewController. Пожалуйста, отладьте и проверьте происхождение вашего NavigationBarдо и после возвращения к вашему ViewController.

// This method will adjust navigation bar and view content.
    private func adjustNavigationControllerIfNeeded() {

        var frame = self.view.frame
        let navigationBarHeight = self.navigationController!.navigationBar.frame.size.height

        if(frame.origin.y == navigationBarHeight && !UIApplication.shared.isStatusBarHidden) { 

   // If status bar height is not included but it is showing then we have to adjust 
      our Navigation controller properly

            print("Adjusting navigation controller")
            let statusBarHeight = UIApplication.shared.statusBarFrame.height

            frame.origin.y += statusBarHeight // Start view below navigation bar
            frame.size.height -= statusBarHeight
            self.view.frame = frame

            self.navigationController!.navigationBar.frame.origin.y = statusBarHeight // Move navigation bar
        }
    }

И вызвать его из метода viewWillAppear -

override func viewWillAppear(_ animated: Bool) {

        super.viewWillAppear(animated)
        self.adjustNavigationControllerIfNeeded()
}
Автор: Rahul Размещён: 07.03.2018 06:33
Вопросы из категории :
32x32