iOS(iPad)Drag&放入UISplitViewController

时间:2012-01-04 06:32:39

标签: ios ipad uisplitviewcontroller

我正在使用UISplitViewController(基于Xcode模板项目)的D& D,从MasterViewController到DetailViewController。

基本上,我正在做的是创建一个UILongPressGestureRecognizer并将其放在MasterViewController的self.tableview属性中。

下面是我的手势识别器。

- (void)gestureHandler:(UIGestureRecognizer*)gesture
{
    CGPoint location;
    NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:[gesture locationInView:self.tableView]];
    if (gesture.state == UIGestureRecognizerStateBegan) {
        // Create draggable view
        NSString* imageCanvasName = [self imageNameByIndexPath:indexPath isDetail:YES];
        UIImage* imageCanvas = [UIImage imageNamed:imageCanvasName];
        _draggedView = [[UIImageView alloc] initWithImage:imageCanvas];

        // Create drag-feedback window, add the drag-view and make the drag-window visible
        CGRect windowFrame = self.view.window.frame;
        _dragFeedbackWindow = [[UIWindow alloc] initWithFrame:windowFrame];
        location = [gesture locationInView:gesture.view.window];
        [_draggedView setCenter:location];
        [_dragFeedbackWindow addSubview:_draggedView];
        [_dragFeedbackWindow setHidden:NO];     
    }
    else if (gesture.state == UIGestureRecognizerStateChanged) {
        // Update drag-view location
        location = [gesture locationInView:gesture.view.window];
        [_draggedView setCenter:location];
    }
    else if (gesture.state == UIGestureRecognizerStateEnded)
    {
        // Disconnect drag-view and hide drag-feedback window
        [_draggedView removeFromSuperview];     
        [_dragFeedbackWindow setHidden:YES];

        // If drop is in a valid location...
        if ([self.tableView pointInside:_draggedView.center withEvent:nil] == NO)
        {
            // Get final location in detailViewController coordinates
            location = [gesture locationInView:self.detailViewController.view];
            [_draggedView setCenter:location];
            [self.detailViewController.view addSubview:_draggedView];
        }
    }
    else {
        NSLog(@"%s unrecognized gesture %d", __FUNCTION__, gesture.state);
    }
}

当iPad处于纵向模式时,所有工作都非常好 - 拖动,下降 - 工作。

如果iPad被旋转,我的问题就开始了...... 在这种情况下,我的_draggedView显示为“反向旋转” - 它将“反映”iPad的旋转 - 直到掉线。

这就像我必须对_dragFeedbackWindow应用一些旋转 - 但我尝试了很多东西,失败......

有什么想法吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

好的 - 我想出了“为什么”这种情况发生了,以及“如何”修复(并将附加处理程序代码以正确执行此操作,以下所有内容。

这是代码......“只是”将它添加到你的MAsterViewController(如果 - 像我一样 - 你想从主人拖到细节......)

// A simple UIView extension to rotate it to a given orientation
@interface UIView(oriented)
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation;
@end

@implementation UIView(oriented)
- (void)rotateToOrientation:(UIInterfaceOrientation)orientation {
    CGFloat angle = 0.0;    
    switch (orientation) { 
        case UIInterfaceOrientationPortraitUpsideDown:
            angle = M_PI; 
            break;
        case UIInterfaceOrientationLandscapeLeft:
            angle = - M_PI / 2.0f;
            break;
        case UIInterfaceOrientationLandscapeRight:
            angle = M_PI / 2.0f;
            break;
        default: // as UIInterfaceOrientationPortrait
            angle = 0.0;
            break;
    } 

    self.transform = CGAffineTransformMakeRotation(angle);
}

现在,LongPress手势处理程序......

- (void)gestureHandler:(UIGestureRecognizer*)gesture
{
    CGPoint location;
    UIWindow* dragFeedback = [UIApplication sharedApplication].delegate.window;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        // Create draggable view
        _draggedView = [[UIImageView alloc] initWithImage:@"someImage.png"];

        // Required to adapt orientation... WORKS, BUT WHY NEEDED???
        [_draggedView rotateToOrientation:[[UIApplication sharedApplication] statusBarOrientation]];

        // Create drag-feedback window, add the drag-view and make the drag-window visible
        location = [gesture locationInView:dragFeedback];
        [_draggedView setCenter:location];
        [dragFeedback addSubview:_draggedView];
    }
    else if (gesture.state == UIGestureRecognizerStateChanged) {
        // Update drag-view location
        location = [gesture locationInView:dragFeedback];
        [_draggedView setCenter:location];
    }
    else if (gesture.state == UIGestureRecognizerStateEnded)
    {
        // Disconnect drag-view and hide drag-feedback window
        [_draggedView removeFromSuperview];     

        // Get final location in detailViewController coordinates
        location = [gesture locationInView:self.detailViewController.view];
        [_draggedView setCenter:location];
        // "Noramlize" orientation... WORKS, BUT WHY NEEDED???
        [_draggedView rotateToOrientation:UIInterfaceOrientationPortrait];
        [self.detailViewController.view addSubview:_draggedView];
    }
    else {
        NSLog(@"%s unrecognized gesture %d", __FUNCTION__, gesture.state);
    }
}

这就像一个魅力 - 让我知道它是如何为你工作的(如果你需要一个示例项目,请告诉我......)

答案 1 :(得分:3)

感谢您的解决方案!你让我90%的路程。在付款时,我会给你最后10%:)

问题似乎是UIWindow永远不会被轮换,只有它的子视图呢!所以解决方案是使用子视图。

我还添加了一些代码,显示如何选择哪个单元格(假设您的主视图是UITableViewController)。

- (IBAction)handleGesture:(UIGestureRecognizer *)gesture
    {
        CGPoint location;
        UIWindow *window = [UIApplication sharedApplication].delegate.window;

        //The window doesn't seem to rotate, so we'll get the subview, which does!
        UIView *dragFeedback = [window.subviews objectAtIndex:0];
        if (gesture.state == UIGestureRecognizerStateBegan) {
            location = [gesture locationInView:dragFeedback];

            //which cell are we performing the long hold over?
            NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:[gesture locationInView:self.tableView]];
            UITableViewCell *selecteCell = [self.tableView cellForRowAtIndexPath:indexPath];
            NSLog(@"Cell %@", selecteCell);

            // Create draggable view
            _draggedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage.png"]];

            // Create drag-feedback window, add the drag-view and make the drag-window visible
            [_draggedView setCenter:location];
            [dragFeedback addSubview:_draggedView];
        }
        else if (gesture.state == UIGestureRecognizerStateChanged) {
            // Update drag-view location
            location = [gesture locationInView:dragFeedback];
            [_draggedView setCenter:location];
        }
        else if (gesture.state == UIGestureRecognizerStateEnded)
        {
            // Disconnect drag-view and hide drag-feedback window
            [_draggedView removeFromSuperview];    

            // Get final location in detailViewController coordinates
            location = [gesture locationInView:self.detailViewController.view];
            [_draggedView setCenter:location];
            [self.detailViewController.view addSubview:_draggedView];
        }
        else {
            NSLog(@"%s unrecognized gesture %d", __FUNCTION__, gesture.state);
        }
    }