IOS9 popover всегда указывает на верхний левый угол привязки
Я использую раскладку segue, которая представляет контроллер представлений как popover. Сек имеет собственный UIView
как его якорь. На pre-iOS9 popover будет правильно указывать на центральное дно пользовательского UIView
(представленного ниже UIView). На iOS9 он указывает на верхний левый угол UIView
.
Я попытался проследить все вызовы селектора на пользовательский UIView
, чтобы узнать, есть ли что-нибудь, что мне может понадобиться реализовать в моем настраиваемом UIView
, чтобы предоставить "горячую точку" для popover, но не смог найти ничего
Любые идеи..? Благодаря
Благодаря @Igor Camilo его ответ - в случае, если это полезно для некоторых, вот как я исправил это в своем коде:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIPopoverPresentationController* possiblePopOver = segue.destinationViewController.popoverPresentationController;
if (possiblePopOver != nil) {
//
// iOS9 -- ensure correct sourceRect
//
possiblePopOver.sourceRect = possiblePopOver.sourceView.bounds;
}
...
}
Пример: Кнопка "Короткие" запускает popover, popover указывает на верхний левый угол элемента "Сортировка"
![Результат popover]()
![Настройки Segue]()
Ответы
Ответ 1
У меня была такая же проблема. Я просто решил это, установив sourceRect в prepareForSegue:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segue.identifier {
case "Popover Identifier"?:
if #available(iOS 9.0, *) {
segue.destinationViewController?.popoverPresentationController?.sourceRect = anchorView.bounds
}
default:
break
}
}
Ответ 2
У той же проблемы, но у моего приложения множество всплывающих окон, поэтому я создал централизованную функцию для исправления (но все равно пришлось использовать ее на каждом контроллере представления, который имел pop).
// Fix for IOS 9 pop-over arrow anchor bug
// ---------------------------------------
// - IOS9 points pop-over arrows on the top left corner of the anchor view
// - It seems that the popover controller sourceRect is not being set
// so, if it is empty CGRect(0,0,0,0), we simply set it to the source view bounds
// which produces the same result as the IOS8 behaviour.
// - This method is to be called in the prepareForSegue method override of all
// view controllers that use a PopOver segue
//
// example use:
//
// override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
// {
// fixIOS9PopOverAnchor(segue)
// }
//
extension UIViewController
{
func fixIOS9PopOverAnchor(segue:UIStoryboardSegue?)
{
guard #available(iOS 9.0, *) else { return }
if let popOver = segue?.destinationViewController.popoverPresentationController,
let anchor = popOver.sourceView
where popOver.sourceRect == CGRect()
&& segue!.sourceViewController === self
{ popOver.sourceRect = anchor.bounds }
}
}
Ответ 3
Вот пример фрагмента Игоря Камило в Objective-C.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// If the sender is a UIView, we might have to correct the sourceRect of
// a potential popover being presented due to an iOS 9 bug. See:
// https://openradar.appspot.com/22095792 and http://stackoverflow.com/a/32698841/368674
if ([sender isKindOfClass:UIView.class]) {
// Fetch the destination view controller
UIViewController *destinationViewController = [segue destinationViewController];
// If there is indeed a UIPopoverPresentationController involved
if ([destinationViewController respondsToSelector:@selector(popoverPresentationController)]) {
// Fetch the popover presentation controller
UIPopoverPresentationController *popoverPresentationController =
destinationViewController.popoverPresentationController;
// Set the correct sourceRect given the sender bounds
popoverPresentationController.sourceRect = ((UIView *)sender).bounds;
}
}
}
Ответ 4
Здесь мое решение внутри prepareForSegue
:
segue.destinationViewController.popoverPresentationController?.sourceRect = CGRectMake(anchorView.frame.size.width/2, anchorView.frame.size.height, 0, 0)
Это переместит указатель на нижнюю середину представления привязки
Ответ 5
Я также столкнулся с этой проблемой, но теперь она работает, когда я добавил ее в мою функцию PrepareForSegue. Учитывая, что мой идентификатор Segue содержит строку Popover
if ([[segue identifier] containsString:@"Popover"]) {
[segue destinationViewController].popoverPresentationController.sourceRect = self.navigationItem.titleView.bounds;
}
Ответ 6
Если вы ссылаетесь на свой popover UIViewController
в своем основном UIViewController
, вы можете настроить свойство sourceRect
для смещения popover. Например, с учетом popover popoverVC
вы можете сделать что-то вроде этого:
float xOffset = 10.0;
float yOffset = 5.0;
popoverVC.popoverPresentationController.sourceRect = CGMakeRect(xOffset, yOffset, 0.0, 0.0);