проблема с позиционированием всплывающего окна

Когда я переключаюсь между портретным и альбомным режимами (и наоборот) на iPad, положение всплывающего окна искажается. Вот как я вычисляю кадр своего всплывающего окна:

aRect = self.myElement.frame;
aRect.origin.x += aRect.size.width;

[aPopOver presentPopoverFromRect:aRect inView:self.myElement.superview permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

Пожалуйста, скажите мне, что здесь не так?


person Abhinav    schedule 04.10.2010    source источник


Ответы (4)


хорошо, я заметил что-то странное в вашем коде.

по какой причине вы добавляете размер ширины к исходной позиции aRect x? aRect.origin.x += aRect.size.width;

я предполагаю, что вы хотите, чтобы это был верхний правый угол....

Вы можете раскомментировать код в вашем .m файле и сделать его таким:

// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
     Return YES; // for supported orientations
    //otherwise return (interfaceOrientation == UIInterfaceOrientationLandscape); if you want only landscape mode.
}

Или что бы я сделал в вашей ситуации, если вы хотите разместить свои подпредставления, используйте didRotateFromIntferfaceOrientation: вот так:

(void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    [self layoutSubviews];
}

а также layoutSubviews

- (void)layoutSubviews
{
    NSLog(@"layoutSubviews called");

    ...recalc rects etc based on the new self.view.bounds...
}

Это работает так.

ПК

person Pavan    schedule 04.10.2010
comment
Да, я пытаюсь выровнять это по правой стороне в середине всплывающего окна. Добавив ширину в источник, я получаю ее в правильном положении при запуске своего приложения. Проблема возникает, когда я меняю ориентацию. - person Abhinav; 05.10.2010
comment
так что вы должны попробовать didRotateFromInterfaceOrientation, я обновлю свой пост о том, как вы можете это сделать. - person Pavan; 05.10.2010
comment
просто вопрос, у вас есть панель вкладок в вашем приложении? - person Pavan; 05.10.2010
comment
Ok. Но какой код я должен написать в методе 'didRotateFromInterfaceOrientation'. Моя логика всплывающего окна тесно связана с методами контроллера, а также мое представление состоит из пользовательских виджетов пользовательского интерфейса. На одном из таких виджетов пользовательского интерфейса я показываю это всплывающее окно. - person Abhinav; 05.10.2010
comment
@abhinav в вашем didRotateFromInterfaceOrientation вы просто пишете свой [self layoutSubviews]; это метод, который вы должны создать, который будет просто иметь код, который обновляет только ваш графический интерфейс. это все. И в вашем методе layoutSubviews, который снова просто будет содержать код, который будет обновлять графический интерфейс пользователя, вот что. поэтому у вас будут такие вещи, как button.x = здесь и aRect.origin.x += везде; и переместите только дисплей, чтобы он подходил для ландшафтного режима. ничего не поделаешь. логика отображения, заполненная методами контроллера, не имеет значения. вам просто нужно обновить графический интерфейс. - person Pavan; 05.10.2010
comment
сначала сделайте тест. настройте свой метод didRotateFromIntergaceOrientation, как я упоминал в посте, который будет содержать однострочный код, который будет вызывать функцию layoutSubviews с [self layoutSubviews]; , затем создайте метод/функцию с именем layoutSubviews, чтобы мы могли ее вызывать. убедитесь, что вы не пишете код в этом методе. Теперь в этом методе вы будете писать только NSLog(@Layout Subviews call); чтобы убедиться, что при запуске программы didRotateFromInterfaceOrientation действительно вызывается, прежде чем вы начнете заполнять layoutSubviews вашим обновлением графического интерфейса вашего приложения. - person Pavan; 05.10.2010
comment
Хорошо, Паван. Я работаю над этим и вернусь в случае проблем. Большое спасибо. - person Abhinav; 05.10.2010
comment
Это приятно слышать. Очевидно, это имело смысл для вас. Замечательно. У вас и так достаточно для работы. Удачи и наслаждайтесь. - person Pavan; 05.10.2010

Из документации UIPopoverController: ( акцент мой)

Если пользователь поворачивает устройство, пока отображается всплывающее окно, контроллер всплывающего окна скрывает всплывающее окно, а затем снова показывает его в конце поворота. Контроллер всплывающего окна пытается расположить всплывающее окно соответствующим образом для вас, но вам, возможно, придется представить его снова или полностью скрыть в некоторых случаях. Например, при отображении из элемента кнопки панели контроллер всплывающего окна автоматически регулирует положение (и, возможно, размер) всплывающего окна для учета изменений положения элемента кнопки панели. Однако, если вы удаляете элемент кнопки панели во время поворота или если вы представили всплывающее окно из целевого прямоугольника в представлении, контроллер всплывающего окна не пытается изменить положение всплывающего окна. В этих случаях вы должны вручную скрыть всплывающее окно или представить его снова с соответствующей новой позиции. Вы можете сделать это в didRotateFromInterfaceOrientation: метод контроллера представления, который вы использовали для представления всплывающего окна.

person Kris Markel    schedule 04.10.2010
comment
Ok. Но какой код я должен написать в методе 'didRotateFromInterfaceOrientation'. Моя логика всплывающего окна тесно связана с методами контроллера, а также мое представление состоит из пользовательских виджетов пользовательского интерфейса. На одном из таких виджетов пользовательского интерфейса я показываю это всплывающее окно. - person Abhinav; 05.10.2010

Это старый вопрос, но я вижу, что ОП не было ясно, что ему делать с предложением Криса Маркела. Это описано в Технические вопросы и ответы QA1694. Просто представьте всплывающее окно еще раз.

Допустим, вы поместили код всплывающего окна выше в метод с именем showPopover. Просто вызовите этот метод при вращении, предварительно убедившись, что он виден:

-(void)showPopover {
    aRect = self.myElement.frame;
    aRect.origin.x += aRect.size.width;

    [self.aPopOver presentPopoverFromRect:aRect inView:self.myElement.superview permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
}

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)oldOrientation
{
    if ([self.aPopover isPopoverVisible]) {
        [self showPopover];
    }
}
person Christopher Pickslay    schedule 07.05.2013

Используйте указанный ниже метод UIPopoverPresentationControllerDelegate в контроллере представления.

func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController,
                                   willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>,
                                   in view: AutoreleasingUnsafeMutablePointer<UIView>) {
    rect.pointee = self.view.bounds
}
person AP_    schedule 27.05.2019