Подтвердить что ты не робот

Как получить фактический размер кадра [UIScreen mainScreen]?

Я немного раздражен. У меня есть приложение со статусной панелью, видимой в главном окне. Так как я хотел бы настроить мои представления и их размеры кадров динамически (возможно, строка состояния занимает 40 пикселей во время телефонного разговора, например).

Я могу сделать одно из двух:

[[UIScreen mainScreen] bounds];
[[UIScreen mainScreen] applicationFrame];

На самом деле это раздражает эти два выхода двумя разными наборами значений, каждый из которых одинаково бесполезен.

bounds выведет: {{0, 0}, {320, 480}}, а applicationFrame выводит {{0, 20}, {320, 460}}

Как вы можете видеть, bounds дает правильное y origin (0 начинается справа от строки состояния), но затем дает высоту 480, что неверно. Он должен быть 460, поскольку панель состояния видна. Тогда у нас есть applicationFrame, который начинается на 20 пикселей ниже строки состояния (так что есть колпачок), но затем дает правильную высоту. Но это не очень полезно, когда в любом случае он толкает 20 пикселей.

Любая помощь?

4b9b3361

Ответ 1

На самом деле это очень полезно.
Когда вы запрашиваете UIScreen для него Bounds, вы получаете границы экрана, который является экраном всего устройства. (строка состояния является частью экрана)
Но если вы попросите UIScreen рассказать вам, где и насколько большой может быть корневой вид вашего приложения, запрашивающий applicationFrame, полезен. Прямой связи между двумя вызовами нет, за исключением того, что applicationFrame возвращается в системе координат UIScreen bounds. (Но строка состояния не является частью вашего приложения, что объясняет другой результат)

applicationFrame
Рамка рамки, которая будет использоваться для вашего окна приложений. (Только для чтения)
@property (nonatomic, readonly) CGRect applicationFrame
Обсуждение
Это свойство содержит границы экрана минус область, занятая строкой состояния, если она видна. Использование этого свойства является рекомендуемым способом получения начального размера вашего приложения. Прямоугольник указан в точках.

Ответ 2

Фактически 0 не начинается в нижней части строки состояния. Он начинается с вершины. Добавьте UILabel в (0,0), и вы не увидите его, если у вас нет строки состояния. Таким образом, границы дают вам общую площадь экрана, а applicationFrame дает вам область, с которой ваше приложение должно работать. Бьюсь об заклад, если вы скроете строку состояния, рамка приложения будет соответствовать границам.

Ответ 3

У меня была аналогичная проблема. То, что я делал, было довольно глупым, но я надеюсь, что это поможет кому-то.

В подзаголовке у меня было:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        UIView * otherSubview = [[UIView alloc] initWithFrame:frame];
        [self addSubview:otherSubview];
    }
    return self;
}

Потому что я создавал свой subview с фреймом с источником не в (0,0), но затем используя тот же фрейм для создания subviews для моего subview, эти subviews также были сдвинуты вниз. В результате был нанесен раздражающий черный баннер.

Я исправил это, выполнив следующее:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        CGRect rect = frame;
        rect.origin.x = 0;
        rect.origin.y = 0;
        UIView * otherSubview = [[UIView alloc] initWithFrame:rect];
        [self addSubview:otherSubview];
    }
    return self;
}

Ответ 4

Вы можете посмотреть UIWindow. Он наследует UIView, поэтому он будет иметь границы и фрейм, а приложения iOS - одно окно. - [UIApplication keyWindow] вернет окно, настроенное делегатом приложения. Поскольку все другие представления привязаны в главном окне, я полагаю, что это должно дать вам правильные границы.

Ответ 5

Обновление Swift 2.0:

func presentAboveAll() {
       //Get the view from the nib. Assuming the view is is in AboveAllView.xib
        let nibContents = NSBundle.mainBundle().loadNibNamed("AboveAllView", owner: nil, options: nil)

        //Get hold of your view
        let views =  nibContents.filter {
          if let _ = $0 as? UIView{
            return true
          }
          return false
        }

        guard views.count > 0  else {
          return
        }

        //Set up frame and add to the app key window
        let view  = views.first as! UIView
        view.frame = UIScreen.mainScreen().bounds
        UIApplication.sharedApplication().keyWindow?.addSubview(view)
}