framework - uikit ios
La ventana emergente de iOS9 siempre apunta a la esquina superior izquierda del ancla (9)
Estoy usando un guión gráfico que presenta un controlador de vista como un elemento emergente. La secuela tiene un UIView
personalizado como su ancla. En pre-iOS9, la ventana emergente apuntaría correctamente a la parte inferior central de la vista UIView
personalizada (presentada debajo de la vista UIV). En iOS9 apunta a la esquina superior izquierda de UIView
.
UIView
rastrear todas las llamadas del selector a la UIView
personalizada para averiguar si hay algo que deba implementar en mi UIView
personalizada para proporcionar el ''punto de acceso'' para la ventana emergente, pero no pude encontrar nada.
Algunas ideas..? Gracias
Gracias a @Igor Camilo por su respuesta, en caso de que sea útil para algunos, así es como solucioné esto en mi código :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
UIPopoverPresentationController* possiblePopOver = segue.destinationViewController.popoverPresentationController;
if (possiblePopOver != nil) {
//
// iOS9 -- ensure correct sourceRect
//
possiblePopOver.sourceRect = possiblePopOver.sourceView.bounds;
}
...
}
Ejemplo: el botón ''Corto'' activa una ventana emergente, la ventana emergente apunta a la esquina superior izquierda del control ''Ordenar''
¡Una respuesta un poco más actualizada para Swift 3! Perdona todo el casting
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "popSegue" {
let popoverViewController = segue.destination
popoverViewController.popoverPresentationController?.delegate = self
segue.destination.popoverPresentationController?.sourceRect = ((sender as? UIButton)?.bounds)!
}
}
Aquí está mi solución, dentro de prepareForSegue
:
segue.destinationViewController.popoverPresentationController?.sourceRect = CGRectMake(anchorView.frame.size.width/2, anchorView.frame.size.height, 0, 0)
Esto moverá el puntero a la mitad inferior de la vista de anclaje
Aquí hay un ejemplo del fragmento de Igor Camilo en 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://.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''s bounds
popoverPresentationController.sourceRect = ((UIView *)sender).bounds;
}
}
}
Intente establecer el anclaje de ancho y altura de su fuente rect (UIView o UIBarButtonItem) y configúrelo como activo. Configúrelo cuando esté inicializando su UIView o UIBarButtonItem.
UIBarButtonItem
[[youruibarbuttonitem.customView.widthAnchor constraintEqualToConstant:youruibarbuttonitem.customView.bounds.size.width] setActive:YES];
[[youruibarbuttonitem.customView.heightAnchor constraintEqualToConstant:youruibarbuttonitem.customView.bounds.size.height] setActive:YES];
Vista
[[uiview.widthAnchor constraintEqualToConstant:uiview.bounds.size.width] setActive:YES];
[[uiview.heightAnchor constraintEqualToConstant:uiview.bounds.size.height] setActive:YES];
Si hace referencia a su UIViewController
en su UIViewController
principal, puede ajustar la propiedad sourceRect
para compensar la ventana emergente. Por ejemplo, dado popover popoverVC
puedes hacer algo así:
float xOffset = 10.0;
float yOffset = 5.0;
popoverVC.popoverPresentationController.sourceRect = CGMakeRect(xOffset, yOffset, 0.0, 0.0);
También encontré este problema, pero ahora funciona cuando lo agregué a mi función PrepareForSegue . Dado que mi ID de Segue contiene la cadena Popover
if ([[segue identifier] containsString:@"Popover"]) {
[segue destinationViewController].popoverPresentationController.sourceRect = self.navigationItem.titleView.bounds;
}
Tenía el mismo problema, pero mi aplicación tiene una gran cantidad de ventanas emergentes, así que creé una función centralizada para la solución (pero aún tenía que usarla en cada controlador de vista que tenía ventanas emergentes).
// 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''s sourceRect is not being set
// so, if it is empty CGRect(0,0,0,0), we simply set it to the source view''s 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 }
}
}
Tuve exactamente el mismo problema. Acabo de resolverlo configurando sourceRect en 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
}
}
solo para actualizar a un ejemplo real con código de trabajo para cualquier UIView
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "PopoverSegueId"?:
if #available(iOS 9.0, *) {
segue.destination.popoverPresentationController?.sourceRect = (segue.destination.popoverPresentationController?.sourceView?.bounds)!
}
default:
break
}
}