我认为这是解决从UITableViewRowAction启动弹出框的问题的一种相当聪明的方法,我想在目标操作上放置一个清晰的UIView并将其用于sourceRect来锚定UIPopoverPresentationController。在这种情况下,目标操作是下面的屏幕快照中显示的橙色“Acct”按钮。

我在整个表视图上使用了清晰的UIView(self.clearTopView),并使用从视图中的点击位置(tappedViewOverlay)和point(CGSize)派生的帧初始化了启动视图(tappedRectSize)。 。然后我将其添加为self.clearTopView的子视图。我目前正在将其着色为黑色,以便可以找到它。

如以下屏幕截图所示,该方案的一部分正在按计划工作。添加了tappedViewOverlay视图,并对其进行了适当的着色。根据需要从此视图启动popoverPresentationController(thisPPC)。

ios - 将UIView放置在水龙头处以启动弹出窗口-LMLPHP

问题在于,视图始终位于屏幕的左上角,而不是期望的位置(发生点击的位置)。以下是相关代码:

    else if ([[segue identifier] isEqualToString:@"AccountPopSegue"])
    {

        UITapGestureRecognizer *tapGestureRecognizer;

        CGPoint point = [tapGestureRecognizer locationInView:self.clearTopView];

        NSString *pointString = NSStringFromCGPoint(point);

        NSLog(@"point is located at %@",pointString);


        CGSize tappedRectSize= CGSizeMake(60,60);
        CGRect tappedRect = {point,tappedRectSize};

        NSString * tappedRectString = NSStringFromCGRect(tappedRect);

        NSLog(@"tappedRect = %@",tappedRectString);


        tappedViewOverlay = [[UIView alloc]initWithFrame:tappedRect];
        tappedViewOverlay.backgroundColor = [UIColor blackColor];

        [self.clearTopView addSubview:tappedViewOverlay];

        [self.clearTopView setUserInteractionEnabled:NO];


        NSString *tappedOverlayFrame = NSStringFromCGRect(tappedViewOverlay.frame);
        NSLog(@"tappedViewOverlay.frame = %@",tappedOverlayFrame);


        UIViewController *controller = segue.destinationViewController;
        controller.popoverPresentationController.delegate = self;
        controller.preferredContentSize = CGSizeMake(320, 186);
        UIPopoverPresentationController *thisPPC = controller.popoverPresentationController;


        thisNavController = (UINavigationController *)segue.destinationViewController;
        AccountChangeVC *acCVC = (AccountChangeVC *)thisNavController.topViewController;
        acCVC.delegate = self;

        thisPPC.sourceView = self.clearTopView;
        thisPPC.sourceRect = tappedViewOverlay.bounds;

有人可以告诉我我要去哪里了吗?

编辑

CoderWang指出了我的代码中的一个疏漏,因此我已更正了它:
    else if ([[segue identifier] isEqualToString:@"AccountPopSegue"])
    {

        UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc]init];

        [self.clearTopView addGestureRecognizer:tapGestureRecognizer];



        CGPoint point = [tapGestureRecognizer locationInView:self.clearTopView];

        NSString *pointString = NSStringFromCGPoint(point);

        NSLog(@"point is located at %@",pointString);


        CGSize tappedRectSize= CGSizeMake(60,60);

        CGRect tappedRect = {point,tappedRectSize};

        NSString * tappedRectString = NSStringFromCGRect(tappedRect);

        NSLog(@"tappedRect = %@",tappedRectString);


        tappedViewOverlay = [[UIView alloc]initWithFrame:tappedRect];

        tappedViewOverlay.backgroundColor = [UIColor blackColor];

        [self.clearTopView addSubview:tappedViewOverlay];

        [self.clearTopView setUserInteractionEnabled:NO];


        NSString *tappedOverlayFrame = NSStringFromCGRect(tappedViewOverlay.frame);
        NSLog(@"tappedViewOverlay.frame = %@",tappedOverlayFrame);


        UIViewController *controller = segue.destinationViewController;
        controller.popoverPresentationController.delegate = self;
        controller.preferredContentSize = CGSizeMake(320, 186);
        UIPopoverPresentationController *thisPPC = controller.popoverPresentationController;


        thisNavController = (UINavigationController *)segue.destinationViewController;
        AccountChangeVC *acCVC = (AccountChangeVC *)thisNavController.topViewController;
        acCVC.delegate = self;

        thisPPC.sourceView = self.clearTopView;
        thisPPC.sourceRect = tappedViewOverlay.bounds;

此更改(tapGestureRecognizer的初始化以及self.clearTopView的添加)会导致黑色tappedViewOverlay视图的位置发生轻微变化。在以下屏幕截图中,您可以看到它隐藏在“返回”导航按钮后面:

ios - 将UIView放置在水龙头处以启动弹出窗口-LMLPHP

最佳答案

问题是'tappedRect'是不正确的,不确切知道原因。
但是您可以尝试使用以下方法将“Acct”按钮转换为self.clearTopView的方法:

CGRect tappedRect = [Acct.superview convertRect:acct.frame toView:self.clearTopView];

或转换为窗口(因为self.clearTopView在整个tableview上):
CGRect tappedRect = [Acct.superview convertRect:acct.frame toView:nil];

08-19 11:36