2012-01-04 28 views
5

Tôi đang làm việc trên D & D trong UISplitViewController (dựa trên dự án mẫu Xcode), từ MasterViewController đến DetailViewController.iOS (iPad) Kéo và thả trong một UISplitViewController

Về cơ bản, những gì tôi đang làm là tạo UILongPressGestureRecognizer và đặt nó vào thuộc tính self.tableview của MasterViewController.

Dưới đây là trình nhận dạng cử chỉ của tôi.

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

Tất cả hoạt động rất độc đáo khi iPad đang ở chế độ dọc - kéo, thả - công trình.

Vấn đề của tôi bắt đầu nếu iPad được xoay ... Trong trường hợp này, _draggedView của tôi xuất hiện "xoay ngược" - nó sẽ "phản ánh" vòng xoay của iPad - cho đến khi giảm.

Nó giống như tôi phải áp dụng một số luân chuyển để _dragFeedbackWindow - nhưng tôi đã thử một số thứ, thất bại ...

Bất kỳ ý tưởng?

Cảm ơn!

Trả lời

4

OK - Tôi đã khám phá ra "TẠI SAO" điều này xảy ra, và "CÁCH" để sửa chữa (và sẽ đính kèm mã xử lý để thực hiện điều này một cách chính xác, tất cả đều dưới

Dưới đây là đoạn code ... "Chỉ cần. "thêm nó vào MAsterViewController của bạn (nếu - như tôi - bạn muốn kéo từ các bậc thầy đến từng chi tiết ...)

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

Bây giờ, xử lý nhấn và giữ cử chỉ ...

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

này hoạt động như một sự quyến rũ - hãy cho tôi biết cách nó hoạt động cho bạn (nếu bạn cần một dự án mẫu, hãy cho tôi biết ...)

+0

Xin chào, tôi có cùng yêu cầu. Bạn có thể xin vui lòng chia sẻ một dự án mẫu xin vui lòng. Cảm ơn. – applefreak

+0

. nó sẽ đưa tôi một ngày để dọn dẹp. – Reuven

+1

Đây là, thưởng thức. http://www.box.com/s/p7exfvxcvzgneo97d1of – Reuven

3

Cảm ơn giải pháp của bạn! Bạn đã cho tôi 90% con đường ở đó. Trong thanh toán, tôi sẽ cung cấp cho bạn 10% cuối cùng :)

Vấn đề dường như là là UIWindow không bao giờ bị xoay vòng, chỉ các bản phụ của nó mới làm! Vì vậy, giải pháp là sử dụng một subview.

Tôi cũng đã thêm một số mã cho biết cách xem ô nào được chọn (giả sử chế độ xem chính của bạn là 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, trong khi thay đổi của bạn "làm sạch" sự cần thiết phải xoay thủ công, nó không còn cung cấp phản hồi trực quan về việc kéo "trên đầu" của trình đơn ... Xem ví dụ tôi đã đăng: http://www.box.com/ s/p7exfvxcvzgneo97d1of – Reuven

+0

Ahhh .. Tôi chưa bao giờ thử nghiệm ở chế độ Chân dung :) Có, tôi nghĩ rằng để vượt qua cửa sổ bật lên bạn phải vẽ trên UIWindow. Tôi đã nghiên cứu thêm và xác nhận rằng: "chính cửa sổ không thực sự thay đổi hệ tọa độ, nó áp dụng biến đổi cho các bản xem lại thay đổi hệ tọa độ của chúng." Vì vậy, ít nhất tất cả đều có ý nghĩa bây giờ? :) – RefuX

+0

Chắc chắn rồi. Cảm ơn về lời xác nhận. – Reuven

Các vấn đề liên quan