Поверните UIViewController, чтобы противодействовать изменениям в UIInterfaceOrientation.

Я много искал по этому поводу и не могу найти ничего, что могло бы мне помочь.

У меня есть UIViewController, содержащийся в другом UIViewController. Когда родительский UIViewController поворачивается, скажем, из Portrait в LandscapeLeft, я хочу, чтобы он выглядел так, как будто дочерний элемент не вращался. То есть. Я хочу, чтобы ребенок имел одинаковую ориентацию по отношению к небу независимо от ориентации родителя. Если у него есть вертикальный UIButton в портретном режиме, я хочу, чтобы правая сторона кнопки была «вверху» в UIInterfaceOrientationLandscapeLeft.

Это возможно? В настоящее время я делаю действительно грубые вещи, такие как это:

-(void) rotate:(UIInterfaceOrientation)fromOrientation: toOr:(UIInterfaceOrientation)toOrientation
{
    if(((fromOrientation == UIInterfaceOrientationPortrait) && (toOrientation == UIInterfaceOrientationLandscapeRight))
       || ((fromOrientation == UIInterfaceOrientationPortraitUpsideDown) && (toOrientation == UIInterfaceOrientationLandscapeLeft)))
    {

    }
    if(((fromOrientation == UIInterfaceOrientationLandscapeRight) && (toOrientation == UIInterfaceOrientationPortraitUpsideDown))
       || ((fromOrientation == UIInterfaceOrientationLandscapeLeft) && (toOrientation == UIInterfaceOrientationPortrait)))
    {

    }
    if(((fromOrientation == UIInterfaceOrientationPortrait) && (toOrientation == UIInterfaceOrientationLandscapeLeft))
       || ((fromOrientation == UIInterfaceOrientationPortraitUpsideDown) && (toOrientation == UIInterfaceOrientationLandscapeRight)))
    {

    }
    if(((fromOrientation == UIInterfaceOrientationLandscapeLeft) && (toOrientation == UIInterfaceOrientationPortraitUpsideDown))
       || ((fromOrientation == UIInterfaceOrientationLandscapeRight) && (toOrientation == UIInterfaceOrientationPortrait)))
    {

    }
    if(((fromOrientation == UIInterfaceOrientationPortrait) && (toOrientation == UIInterfaceOrientationPortraitUpsideDown))
       || ((fromOrientation == UIInterfaceOrientationPortraitUpsideDown) && (toOrientation == UIInterfaceOrientationPortrait)))
    {

    }
    if(((fromOrientation == UIInterfaceOrientationLandscapeLeft) && (toOrientation == UIInterfaceOrientationLandscapeRight))
       || ((fromOrientation == UIInterfaceOrientationLandscapeRight) && (toOrientation == UIInterfaceOrientationLandscapeLeft)))
    {

    }   
}

что кажется совершенно хорошей тратой кода. Кроме того, я планировал использовать CGAffineTransform (как указано здесь: http://www.crystalminds.nl/?p=1102), но я не понимаю, следует ли мне изменить размеры представления, чтобы они соответствовали тому, что они будут после поворота.

Большой кошмар здесь заключается в том, что вам нужно отслеживать глобальную переменную «ориентация». Если вы этого не сделаете, иллюзия будет потеряна, и ViewController повернется во что угодно.

Мне действительно не помешала бы помощь в этом, спасибо!


person Peter Hajas    schedule 22.03.2010    source источник


Ответы (2)


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

 #pragma mark -
 #pragma mark InterfaceOrientationMethods

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    if(toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
        //self.view = portraitView;
        [self changeTheViewToPortrait:YES andDuration:duration];

    }
    else if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft){
        //self.view = landscapeView;
        [self changeTheViewToPortrait:NO andDuration:duration];
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------------------------------------

- (void) changeTheViewToPortrait:(BOOL)portrait andDuration:(NSTimeInterval)duration{

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:duration];

    if(portrait){
        //change the view and subview frames for the portrait view
    }
    else{   
        //change the view and subview  frames for the landscape view
    }

    [UIView commitAnimations];
}

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

person Madhup Singh Yadav    schedule 22.03.2010
comment
Спасибо Мадхуп. Когда вы советуете изменить кадры вида и подвида для портретного вида - я бы сделал CGAffineTransform? Или у меня должен быть какой-то отдельный способ поворота UIView/UIViewController? Мне нужно, чтобы все элементы вели себя одинаково, просто имели другую ориентацию. Кроме того, что вы имели в виду под закомментированным self.view = PortraitView? Я бы использовал эти методы с самого начала, но я не знаю, как иметь боковой UITableView или боковой UIButton или что-то в этом роде. Еще раз спасибо! - person Peter Hajas; 22.03.2010
comment
@Peter Hajas: я не выполняю преобразования CGAffine, а получаю позиции кадра из xib для портретного и альбомного просмотра и соответствующим образом меняю кадр своих подпредставлений. - person Madhup Singh Yadav; 23.03.2010
comment
Я пытаюсь реализовать эти методы, но всякий раз, когда я поворачиваю устройство симулятора, ни один из методов не срабатывает. Знаете почему? - person Francesco Puglisi; 24.05.2011

я кое-что понял... скажем, наш проект имеет несколько уровней ViewController (как если бы вы добавили подвид другого контроллера представления в свой контроллер представления)

Метод willRotateToInterfaceOrientation:duration не будет вызываться для 2-го слоя ViewController...

Итак, что я сделал, так это то, что после того, как я инициализировал свой контроллер представления 2-го уровня из самого верхнего слоя, затем, когда метод willRotateToInterfaceOrientation:duration вызывается на самом верхнем слое, я также вызову willRotateToInterfaceOrientation:duration для контроллера представления 2-го уровня.

person Yit Ming    schedule 25.08.2010