2012-01-04 18 views
5

Pracuję nad D & D w UISplitViewController (na podstawie projektu szablonu Xcode), z MasterViewController do DetailViewController.iOS (iPad) Przeciągnij i upuść w UISplitViewController

Zasadniczo, co robię, to tworzenie UILongPressGestureRecognizer i umieszczanie go na właściwości self.tableview w MasterViewController.

Poniżej znajduje się mój aparat rozpoznawania gestów.

- (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); 
    } 
} 

Wszystko działa bardzo dobrze, gdy iPad jest w trybie portretowym - przeciągnij, upuść - działa.

Mój problem zaczyna się, gdy iPad jest obrócony ... W takim przypadku mój _wyświetlony widok jest wyświetlany "przeciwnie obrócony" - "odbija" obrót iPada - aż do opuszczenia.

To jak muszę zastosować jakąś rotację _dragFeedbackWindow - ale próbowałem wiele rzeczy, w przypadku braku ...

Każdy pomysł?

Dzięki!

Odpowiedz

4

OK - I zorientowali się, „dlaczego” tak się dzieje, i „jak” naprawić (i będzie dołączyć kod obsługi to zrobić poprawnie, wszystkie poniżej

Oto kod ... „Właśnie. "dodać go do MAsterViewController (jeśli - tak jak ja - chcesz przeciągnąć z mastera do szczegółu ...)

// 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); 
} 

Teraz obsługi gest 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); 
    } 
} 

ten działa jak marzenie - daj mi znać, jak to działa (jeśli potrzebujesz przykładowego projektu, daj mi znać ...)

+0

Cześć Reuven, mam te same wymagania. Czy mógłbyś/chciałabyś udostępnić przykładowy projekt? Dzięki. – applefreak

+0

pewnie. zabierze mi to dzień na porządek. – Reuven

+1

Oto, ciesz się. http://www.box.com/s/p7exfvxcvzgneo97d1of – Reuven

3

Dzięki za rozwiązanie! Dostałeś mnie na 90% drogi. W zapłacie, dam ci ostatnią 10% :)

Kwestia wydaje się, że nigdy nie zostanie obrócone UIWindow, tylko jego subviews zrobienia! Tak więc rozwiązaniem jest użycie podglądu.

Dodałem również kod, który pokazuje, jak sprawdzić, która komórka jest wybrana (zakładając, że widok główny jest kontrolerem 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); 
     } 
    } 
+1

RefuX, podczas gdy twoja zmiana "czyści" potrzebę ręcznego obracania, nie zapewnia już wizualnej informacji o przeciągnięciu "na wierzchu" menu ... Zobacz przykład, który napisałem: http://www.box.com/ s/p7exfvxcvzgneo97d1of – Reuven

+0

Ahhh .. Nigdy nie testowałem w trybie Portrait :) Tak, myślę, że powyżej nadokiennego okna musielibyśmy narysować na UIWindow. Zrobiłem więcej badań i potwierdziłem, że: "okno samo w sobie nie zmienia układów współrzędnych, stosuje transformację do swoich podobrazów, które zmieniają ich układ współrzędnych." Więc to wszystko ma teraz sens? :) – RefuX

+0

Pewnie tak. Dziękuję za potwierdzenie. – Reuven