Как получить фактический размер кадра [UIScreen mainScreen]? - PullRequest
48 голосов
/ 01 марта 2011

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

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

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

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

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

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

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

Ответы [ 5 ]

50 голосов
/ 13 августа 2012

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

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

8 голосов
/ 08 июля 2011

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

1 голос
/ 22 апреля 2012

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

В подвиде у меня было:

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

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

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

- (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;
}
0 голосов
/ 24 декабря 2015

Обновление 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's key window
        let view  = views.first as! UIView
        view.frame = UIScreen.mainScreen().bounds
        UIApplication.sharedApplication().keyWindow?.addSubview(view)
}
0 голосов
/ 01 марта 2011

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

...