iOS (iPad) перетаскивание в UISplitViewController - PullRequest
5 голосов
/ 04 января 2012

Я работаю над D & D в UISplitViewController (на основе проекта шаблона XCode), от MasterViewController до DetailViewController.

По сути, я создаю UILongPressGestureRecognizer и помещаю его в свойство self.tableview MasterViewController.

Ниже мой распознаватель жестов.

- (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 ]

4 голосов
/ 06 января 2012

ОК. Я выяснил, «ПОЧЕМУ» это происходит, и «КАК» исправить (и прикреплю код обработчика, чтобы сделать это правильно, все ниже.

Вот код ... "Просто" добавьте его в свой 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);
    }
}

Это работает как шарм - дайте мне знать, как это работает для вас (если вам нужен пример проекта, дайте мне знать ...)

3 голосов
/ 01 марта 2012

Спасибо за ваше решение!Вы получили мне 90% пути туда.В качестве оплаты я дам вам последние 10%:)

Проблема кажется в том, что UIWindow никогда не поворачивается, а только его подпредставления!Поэтому решение состоит в том, чтобы использовать подпредставление.

Я также добавил некоторый код, который показывает, как увидеть, какая ячейка выбрана (при условии, что ваш главный вид - UITableViewController).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...