从 UIPopoverController 拖放到其他 UIView

发布于 2024-09-07 10:58:29 字数 249 浏览 2 评论 0原文

我将如何实现将 UIView 从 UIPopoverController 拖放到后面的 UIView 中。

这是 Pages 在其插入媒体弹出窗口中提供的功能,您可以在其中将形状从 UIPopoverController 中拖出并将其放入主文档中。

我实际上对 UIGestureRecognizers 及其实现位置感到困惑。

谢谢,

乌梅尔

How would I go about implementing dragging and dropping a UIView from UIPopoverController into the back UIView.

This is the functionality that Pages provide in their insert media popover, where you can drag a shape out from the UIPopoverController and drop it into the main document.

I am actually confused with the pan UIGestureRecognizers and where they will be implemented.

Thanks,

Umer

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紫轩蝶泪 2024-09-14 10:58:30

根据 UIPopoverController 的文档,当弹出窗口出现时,它会出现在一个特殊的“窗口”上。因此,仅将子视图添加到弹出视图控制器的内容视图控制器不足以将视图拖到弹出视图控制器的视图之外。

这里最简单的解决方案是创建您自己的窗口,在发生拖动时将可拖动视图添加到窗口中。使窗口在拖放期间可见,然后在完成后释放窗口。

如上所述,手势识别器 (GR) 最适合拖/放功能。一旦 GR 的状态更改为“开始”,GR 将控制所有触摸,直到达到“结束”或“取消”状态,这使得它非常适合在视图控制器和窗口之间拖动视图:)

示例:

@interface MySplitViewController : UISplitViewController {

    UIView *dragView;
    UIWindow *dragWindow;
}

实现:
注意我们不需要在窗口上调用“makeKeyAndVisible”。 设置 Apple 的“隐藏”属性

我们只需要在 makeKeyAndVisible 方法中 :
// 方便。大多数应用程序调用它来显示主窗口并使其成为关键。否则使用视图隐藏属性

-(void)dragBegan{

    self.dragWindow = [[UIWindow alloc] initWithFrame:self.view.window.frame];
    [self.dragWindow addSubview:self.dragView];
    [self.dragWindow setHidden:NO];
}

这里我们处理手势识别器的“已结束”或“已取消”状态。
注意:拖/放完成后删除窗口非常重要,否则您将失去与下面视图的用户交互性。

-(void)dragEnded{

    [self.dragView removeFromSuperview];

    [self.dragWindow setHidden:YES];
    [self.dragWindow release];

    [self.view addSubview:self.dragView];
}

According to the documentation on UIPopoverController, when the popover is presented, it is presented on a special "window". Because of this, simply adding a subview to the popover view controller's content view controller is not sufficient to be able to drag a view outside of the popover view controller's view.

The easiest solution here is to create your own window, add your drag-able view to the window when dragging occurs. Make the window visible for the duration of the drag/drop, and then release your window when complete.

As mentioned above, gesture recognizers (GR) are best suited for Drag/Drop functionality. Once the GR's state has changed to "Began" the GR will control all touches until the "Ended" or "Cancelled" state is achieved which makes it ideal for dragging views between view controllers as well as windows :)

Example:

@interface MySplitViewController : UISplitViewController {

    UIView *dragView;
    UIWindow *dragWindow;
}

Implementation:
NOTE we do not need to call "makeKeyAndVisible" on our window. We just need to set its "Hidden" property

From Apple in regards to the makeKeyAndVisible method:
// convenience. most apps call this to show the main window and also make it key. otherwise use view hidden property

-(void)dragBegan{

    self.dragWindow = [[UIWindow alloc] initWithFrame:self.view.window.frame];
    [self.dragWindow addSubview:self.dragView];
    [self.dragWindow setHidden:NO];
}

Here we handle the Gesture Recognizer's "Ended" or "Cancelled" state.
NOTE: It is important to remove the window when the Drag/Drop is complete or you will lose user interactiveness with the views below.

-(void)dragEnded{

    [self.dragView removeFromSuperview];

    [self.dragWindow setHidden:YES];
    [self.dragWindow release];

    [self.view addSubview:self.dragView];
}
苏大泽ㄣ 2024-09-14 10:58:30

您必须处理两个视图控制器,其中一个位于后台,称为 mainController,另一个使用称为 popoverController 的 UIPopoverViewController 来呈现。您的 popoverController 可以将 UIPanGestureRecognizer 添加到视图中,用户可以拖动该视图。 gestureRecognizer 的操作目标可以是 popoverController 上的方法。

一旦用户开始拖动操作,您的操作方法就会被调用,并以gestureRecognizer作为参数,假设gestureRecognizer的状态是UIGestureRecognizerStateBegan。您可以保存视图的当前帧,以便在放置失败时能够将其动画回来。可能需要将视图移动到其他超级视图(例如窗口),因为我不确定 UIPopoverViewController 是否 ClipsToBounds 其视图。

当用户拖动时,您的操作方法会被一遍又一遍地调用,并且gestureRecognizer处于UIGestureRecognizerStateChanged状态。使用 UIPanGestureRecognizer 上的 translationInView: 方法来确定用户拖动的程度,并相应地更新拖动的视图中心/框架/变换。

一旦用户抬起手指,最后一次调用操作方法,并将gestureRecoginzers状态设置为UIGestureRecognizerStateEnded。现在是时候看看拖动是否成功了。例如,popoverController 可以通过委托询问 mainController 在视图当前位置下是否有一个放置目标,如果是,则 mainController 可以采取行动,否则 popoverController 会将拖动的视图动画恢复到它的来源,并将其添加回作为它的视图的子视图。

我希望这在某种程度上是可以理解的并且有帮助的。

You have to deal with two view controllers one that's in the background called mainController one that presented using a UIPopoverViewController called popoverController. Your popoverController could add a UIPanGestureRecognizer to the views, that the user can drag. The action target of the gestureRecognizer could be a method on the popoverController.

Once the user starts a dragging operation your action method is called with the gestureRecognizer as an argument, were the state of the gestureRecognizer is UIGestureRecognizerStateBegan. You could than save the current frame of the view somewere to be able to animate it back, when the dropping fails. It might be necessary to move the view to an other superview (the window for example), because I'm not sure if UIPopoverViewController clipsToBounds its view.

As the user draggs, your action method is called over and over with the gestureRecognizer in the state UIGestureRecognizerStateChanged. Use the translationInView: method on UIPanGestureRecognizer to determine how much the user dragged and update the dragged views center/frame/transform accordingly.

Once the user lifts his finger the action method is called for a last time with the gestureRecoginzers state set to UIGestureRecognizerStateEnded. Now it's time to find out if the drag was successful. For example the popoverController could ask the mainController via delegation if there's a drop target under the views current position, if so the mainController can take action, else the popoverController would animate the dragged view back to were it came from, and add it back as a subview to it's view.

I hope this is somehow comprehensible and helpful.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文