2012-01-04 2 views
5

MasterViewController에서 DetailViewController까지 UISplitViewController (Xcode 템플릿 프로젝트 기반)의 D & D에서 작업하고 있습니다.iOS (iPad) UISplitViewController의 드래그 앤 드롭

기본적으로 내가하고있는 일은 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에 약간의 회전을 적용해야처럼입니다 -하지만 실패 것들의 숫자 ...

어떤 생각을 했어요?

감사합니다.

답변

4

확인 -. 나는 "왜"이런 일이 발생하고 해결하기 위해 (모든 아래, 제대로이 작업을 수행 할 핸들러 코드를 첨부합니다 "HOW"여기

코드의 ... "그냥 알아 냈 (- 나 같은 - 당신이 세부 사항에 마스터에서 드래그합니다 ... 경우) 지금

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

는 길게 누르 제스처 핸들러 ...

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

이를 "당신의 MAsterViewController에 추가 매력처럼 작동합니다. (샘플 프로젝트가 필요하면 알려주세요 ...)

+0

안녕 Reuven, 나는 동일한 필요 조건이있다. 샘플 프로젝트를 공유해주십시오. 감사. – applefreak

+0

. 청소까지 하루가 걸릴거야. – Reuven

+1

여기 있습니다, 즐기십시오. http://www.box.com/s/p7exfvxcvzgneo97d1of – Reuven

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); 
     } 
    } 
+1

RefuX를 사용하면 변경 사항이 수동 순환에 대한 필요성을 "제거"하지만 더 이상 메뉴의 "상단"으로 드래그하는 시각적 피드백을 제공하지 않습니다 ... 게시 한 예 : http://www.box.com/ s/p7exfvxcvzgneo97d1of – Reuven

+0

Ahhh .. Portrait 모드에서 테스트 한 적이 없다. :) 예, UI 윈도우에서 그려야하는 팝 오버 창 위에 있다고 생각합니다. 나는 더 많은 연구를했고 "윈도우 자체가 실제로 좌표계를 변경하지 않고 좌표계를 변경하는 서브 뷰에 변형을 적용합니다."라고 확인했습니다. 적어도 이제는 모두 의미가 있습니까? :) – RefuX

+0

그래. 확인해 주셔서 감사합니다. – Reuven