Принудительное расположение и размер макета в iOS Superviews

У меня огромная проблема, и я очень надеюсь, что вы поможете мне здесь... Я очень потерян в данный момент:(

У меня есть проект, который работает с MainWindow.xib. В моем файле делегата приложения я проверяю ориентацию устройства и загружаю соответствующий файл NIB, который имеет разные макеты (подпредставления) в зависимости от ориентации. Вот код для проверки ориентации:

-(void)checkTheOrientation
{
    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) 
    {
        viewController = [[[MyViewController alloc] initWithNibName:@"MyWideViewController" bundle:nil] autorelease];
        NSLog(@"Landscape = MyWideViewController");
    } 
    else if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortrait || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationPortraitUpsideDown)
    {   
        viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil] autorelease];
        NSLog(@"Portrait = MyViewController"); 
    }
}

Это работает, как ожидалось, и в альбомной или книжной ориентации я загружаю правильные виды. Портретное представление загружается идеально, но альбомное представление загружается с толстым черным краем влево, как будто его положения x & y не установлены в 0 и 0 соответственно.

Вот портретное представление: http://uploads.socialcode.biz/2f25352B0e3x3z2t2z21 Вот альбомное представление с ошибкой: http://uploads.socialcode.biz/1G2k3T012d1z0Y1U2q1k

В файле MyViewController.m у меня есть грубое исправление, чтобы правильно сделать размер, чтобы избежать этой большой черной полосы слева. Вот код для этого:

- (void) performLayout {
    // Ensure the main view is properly placed
    NSInteger MaxSizeHeight, MaxSizeWidth;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 
    {
        MaxSizeHeight = 1024;
        MaxSizeWidth  = 768;
    }
    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) {
        CGRect mainViewFrame = [[self view] frame];
        float width = mainViewFrame.size.width;
        mainViewFrame.size.width = mainViewFrame.size.height;
        mainViewFrame.size.height = width;
        mainViewFrame.origin.x = 0;
        mainViewFrame.origin.y = 0;
        [[self view] setFrame:mainViewFrame];
    } else {
        CGRect mainViewFrame = [[self view] frame];
        mainViewFrame.origin.x = MaxSizeWidth - mainViewFrame.size.width;
        mainViewFrame.origin.y = MaxSizeHeight - mainViewFrame.size.height;
        [[self view] setFrame:mainViewFrame];
    }

    // Ensure the content view is properly placed
    CGRect contentFrame = [mainContentView frame];
    if ([[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation] == UIInterfaceOrientationLandscapeRight) 
    {
        contentFrame.size.width = MaxSizeHeight;
        contentFrame.size.height = MaxSizeWidth;
    }
    contentFrame.origin.x = 0;
    contentFrame.origin.y = 44;
    [mainContentView setFrame:contentFrame];

    // Ensure the content subviews are properly placed
    contentFrame.origin.y = 0;
    for (UIView *contentView in [mainContentView subviews]) {
        [contentView setFrame:contentFrame];
    }
}

Проблема этого метода в том, что это просто очень плохой взлом, и он фактически не решает мою проблему. Когда он загружается в альбомной ориентации, он теперь изменяет размеры и позиционирует подпредставление в 1024x768,0,0, но любые дополнительные подпредставления, которые я загружаю через другие NIB, имеют ту же проблему.

Что я действительно хотел бы знать, так это то, как на самом деле я могу установить основное суперпредставление ландшафта равным 1024x768 в позициях 0 и 0, не пытаясь взломать это вместе и продолжать выполнять селектор executeLayout? На данный момент существует много противоречий с этим, поскольку хак на самом деле не правильно устанавливает размер суперпредставления, а просто подпредставления, которые я загружаю поверх суперпредставления.

Я подумал, что, возможно, такое простое исправление может решить проблему с супервизором, но, увы, нет: window.frame = CGRectMake(0, 0, 1024, 768);

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

1 ответ

Решение

Во-первых, в UIView есть метод с именем -layoutSubviews что вы можете переопределить, чтобы расположить подвиды так, как вам нравится. Он будет вызываться при первой загрузке вида и снова перед рисованием, если вы когда-нибудь отправите -setNeedsLayout сообщение.

Во-вторых, вы должны быть в состоянии правильно установить эти позиции в файле.xib или раскадровке. Выберите ваш основной вид в его файле.xib и проверьте его положение в Инспекторе размера. Кроме того, убедитесь, что в инспекторе атрибутов для представления установлено горизонтальное расположение. Если все правильно, то происходит что-то еще. Чтобы упростить проблему, создайте новый проект в XCode с пустым представлением в альбомной ориентации. Я только что сделал один, и нет проблем с позицией. Это то, что вам нужно в вашем реальном приложении, поэтому выясните, что происходит в вашем реальном приложении, чтобы повлиять на положение представления, которого нет в вашем новом приложении-образце.

Другие вопросы по тегам