【问题标题】:Position a UIView at point of tap to launch popover在点击点放置一个 UIView 以启动弹出窗口
【发布时间】:2016-11-24 05:11:10
【问题描述】:

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

我在整个 tableview 上使用了一个明确的UIView (self.clearTopView),并使用源自(所以我认为)点击位置 (@987654332) 的框架来初始化启动视图 (tappedViewOverlay) @) 和 CGSize (tappedRectSize)。然后我将它作为子视图添加到self.clearTopView。我现在把它涂成黑色,这样我就可以找到它了。

如下图所示,部分方案正在按计划进行。 tappedViewOverlay 视图已添加,并适当着色。 popoverPresentationController (thisPPC) 按预期从该视图启动。

问题是视图始终位于屏幕的左上角,而不是所需的位置,即点击发生的位置。以下是相关代码:

    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 iphone uiview uipopovercontroller


    【解决方案1】:

    问题是“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];
    

    【讨论】:

    • 据我所知,UITableViewRowAction 按钮没有框架属性,至少没有可访问的属性...
    • 然后可以使用相关的方法: - (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view; with CGPoint point = [tapGestureRecognizer locationInView:self.clearTopView];
    • 如果您也提供日志信息会更好。
    • 给你:point is located at {0, 0} tappedRect = {{0, 0}, {60, 60}} tappedViewOverlay.frame = {{0, 0}, {60, 60}}
    • 哇,我发现一个问题:不应该先初始化'tapGestureRecognizer'然后添加到self.clearTopView吗?
    猜你喜欢
    • 2017-07-28
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多