2012-04-05 27 views
7

Thời điểm tôi nhận được touchesBegan, tôi muốn removeFromSuperview chế độ xem đã được chạm và addSuperview sang chế độ xem gốc mới, sau đó tiếp tục nhận được chạm. Tuy nhiên tôi thấy rằng đôi khi điều này không hoạt động. Cụ thể, touchesMovedtouchesEnded không bao giờ được gọi.iOS: Chuyển quyền sở hữu của UIView trong khi các lần chạm xảy ra?

Có một mẹo để thực hiện công việc này một cách chính xác không? Điều này là để thực hiện hành vi kéo và thả, trong đó chế độ xem ban đầu nằm trong chế độ xem cuộn.

Cảm ơn.

Trả lời

0

Bạn cần xử lý các thao tác của mình trong phần giám sát thay vì ở chế độ xem mà bạn muốn tắt. Điều này sẽ cho phép bạn chuyển chế độ xem mà không mất sự kiện chạm của bạn. Khi bạn làm điều này mặc dù, bạn sẽ phải kiểm tra chính mình cho dù liên lạc đang xảy ra trong subview cụ thể bạn muốn chuyển ra ngoài. Điều này có thể được thực hiện nhiều cách khác nhau, nhưng đây là một số phương pháp để giúp bạn bắt đầu:

Chuyển đổi dễ phân biệt/Point để nhìn khác:

[view convertRect:rect toView:subview]; 
[view convertPoint:point toView:subview]; 

Dưới đây là một số phương pháp để kiểm tra nếu điểm nằm trong giao diện :

[subView hitTest:point withEvent:nil]; 
CGRectContainsPoint(subview.frame, point); //No point conversion needed 
[subView pointInside:point withEvent:nil]; 

Nói chung, tốt hơn nên sử dụng UIGestureRecognizers. Ví dụ, nếu bạn đang sử dụng một UIPanGestureRecognizer, bạn sẽ tạo ra một phương thức mà bộ nhận dạng cử chỉ có thể gọi và trong phương thức đó bạn làm công việc của bạn. Ví dụ:

- (void) viewPanned:(UIPanGestureRecognizer *)pan{ 
    if (pan.state == UIGestureRecognizerStateBegan){ 
     CGRect rect = subView.frame; 
     newView = [[UIView alloc] initWithFrame:rect]; 
     [subView removeFromSuperview]; 
     [self addSubview:newView]; 
    } else if (pan.state == UIGestureRecognizerStateChanged){ 
     CGPoint point = [pan locationInView:self]; 
     newView.center = point; 
    } else { 
     //Do cleanup or final view placement 
    } 
} 

Sau đó, bạn init recognizer, gán nó vào mục tiêu (thường tự) và thêm nó:

[self addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(viewPanned:)]]; 

Bây giờ ngã (đó sẽ là SuperView quản lý nó subviews) sẽ trả lời để xoay chuyển động.

+0

Không chắc chắn lý do tại sao. Bạn có thể gửi mã không? BTW, điều gì khiến bạn không thể sử dụng UIGestureRecognizer? Trong hầu hết mọi trường hợp tôi đã xem xét bằng cách sử dụng Touches, tôi đã thấy rằng một UIGestureRecognizer hiện có hoặc subclassing UIGestureRecognizer hoạt động tốt hơn (và tôi có thể tái sử dụng nó). –

+0

Nếu bạn đang sử dụng chứng khoán UIPanGestureRecognizer, 'touchesBegan' sẽ không nằm trong mã của bạn. Bạn nên thiết lập một số phương pháp đích như sau: '- (void) viewPanned: (UIPanGestureRecognizer) pan'. Khi bạn khởi tạo trình nhận dạng, bạn đặt mục tiêu của nó: '[[UIPanGestureRecognizer alloc] initWithTarget: hành động tự: @selector (viewPanned :)]'.Phương thức đó sẽ được gọi lặp lại và bạn có thể kiểm tra trạng thái và thực hiện các hành động thích hợp: 'If (pan.state == UIGestureRecognizerStateBegan) {.......}' hoặc 'If (pan.state == UIGestureRecognizerStateChanged {. ....} 'etc ... –

+0

Tôi mở rộng câu trả lời của mình để phản ánh điều này –

7

Thay vì:

[transferView removeFromSuperView]; 
[newParentView addSubview:transferView]; 

Chỉ sử dụng:

[newParentView addSubview:transferView]; 

Trong tài liệu có nói "Quan điểm có thể chỉ có một SuperView Nếu xem đã có một SuperView và đó. xem không phải là người nhận, phương pháp này loại bỏ các superview trước trước khi làm cho người nhận giám sát mới của nó. "

Do đó không cần sử dụng removeFromSuperView vì nó được xử lý bởi addSubview. Tôi đã nhận thấy rằng removeFromSuperView kết thúc bất kỳ chạm hiện tại nào mà không cần chạm vàoEnded. Nếu bạn chỉ sử dụng addSubview, các lần chạm sẽ không bị gián đoạn.

+1

Đây phải là câu trả lời được chấp nhận vì không cần quản lý việc kéo trong superview để đạt được mục tiêu của OP. ** thực hiện thủ thuật ** Cảm ơn ** walapu ** – walkingbrad

+0

Câu trả lời hay, điều này rất hữu ích! – Max