[英]iPhone/iOS: How to implement Drag and Drop for subviews of a Scrollview?
我在UIViewController
有一個水平滾動視圖,我有很多小尺寸的圖像。 我將圖像保存在scrollview中,因為圖像更多,因此用戶可以水平滾動並選擇圖像。 但是,問題是,我必須選擇一個圖像並拖放到該UIViewController
視圖。 但是,由於圖像處於滾動視圖中,因此將圖像拖放到UIViewcontroller
的視圖中不起作用,也不會檢測到觸摸事件。 請注意 :如果我沒有scrollview,只是將圖像保存到UIViewcontroller
的視圖中,將圖像拖放到同一屏幕上,效果非常好。
當我需要滾動視圖和拖放圖像時,我該如何解決這個問題,請給我一些建議/幫助?
你好,得到,
我不會直接為您提供代碼,但會知道如何管理它。
您可以通過這種方式進行管理,當您在當時在scrollView中觸摸對象時,或者當您通過拖動移動該對象時,通過myScroll.scrollEnabled = NO;
禁用滾動myScroll.scrollEnabled = NO;
然后在endTouch上,您可以通過myScroll.scrollEnabled = YES;
啟用Scroll myScroll.scrollEnabled = YES;
所以通過這個你可以管理你移動滾動的對象希望你有邏輯。
這是演示代碼: 使用ScrollView拖放 。 它具有相同的邏輯,在touchesMoved:
上Disabling
滾動視圖touchesMoved:
並在touchesEnded:
上Enabling
滾動視圖touchesEnded:
。
我確實在沒有任何子類化之前實現了這種行為。
我使用了UIScrollView
canCancelContentTouches = NO
來確保子視圖處理自己的觸摸。 如果觸摸了子視圖(在您的情況下是圖像),我將視圖從滾動視圖移動到超視圖上並開始跟蹤它的拖動。 (您必須在新的超視圖中計算正確的坐標,因此它保持不變)。
拖動完成后,我檢查是否到達目標區域,否則我將其移回滾動視圖。 如果這不夠詳細,我可以發布一些代碼。
那么這是我的示例代碼: Github:JDDroppableView
Getsy,
嘗試拖放對象的代碼:
-(void)dragAndDropWithGesture {
UILongPressGestureRecognizer *downwardGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(dragGestureChanged:)];
[scrollViewAlfabeto addGestureRecognizer:downwardGesture];
for (UIGestureRecognizer *gestureRecognizer in myscrollView.gestureRecognizers)
{
[gestureRecognizer requireGestureRecognizerToFail:downwardGesture];
}
}
- (void) dragGestureChanged:(UIPanGestureRecognizer*)gesture
{
CGPoint point = [gesture locationInView:scrollViewAlfabeto];
if (gesture.state == UIGestureRecognizerStateBegan)
{
[imageViewToMove removeFromSuperview];
[self.view addSubview:imageViewToMove];
UIView *draggedView = [myscrollView hitTest:point withEvent:nil];
if ([draggedView isKindOfClass:[UIImageView class]])
{
imageViewToMove = (UIImageView*)draggedView;
}
}
else if (gesture.state == UIGestureRecognizerStateChanged)
{
imageToMove.center = point;
}
else if (gesture.state == UIGestureRecognizerStateEnded ||
gesture.state == UIGestureRecognizerStateCancelled ||
gesture.state == UIGestureRecognizerStateFailed)
{
// Determine if dragged view is in an OK drop zone
// If so, then do the drop action, if not, return it to original location
NSLog(@"point.x final:%f", point.x);
NSLog(@"point.y final:%f", point.y);
if (CGRectContainsPoint(goal.frame, point)){
imageToMove.frame = CGRectMake(167, 159, 100, 100);
}
else{
[imageToMove removeFromSuperview];
[myscrollView addSubview:imageToMove];
[imageToMove setFrame:CGRectMake(12, 38, 100, 100)];
imageToMove = nil;
}
}
}
願這段代碼能幫到你。
我創建了一個示例,說明了如何在兩個或多個視圖之間拖放: http : //www.ancientprogramming.com/2012/04/05/drag-and-drop-between-multiple-uiviews-in-ios/
我發現將手勢識別器注冊到與拖動的實際視圖不同的視圖是個好主意。 即使拖動的視圖更改其“父”視圖,這也將確保手勢繼續。
也許它可以給一些靈感
對於類似的問題,我創建了UIScrollView子類,如下所示:當PoliteScrollView確定它們被拖動時,它會將觸摸消息傳遞給它的子視圖。
@interface PoliteScrollView : UIScrollView
// number of pixels perpendicular to the scroll views orientation to make a drag start counting as a subview drag
// defaults to 1/10 of the scroll view's width or height, whichever is smaller
@property(nonatomic,assign) CGFloat subviewDraggingThreshold;
// yes when a subview is being dragged
@property(nonatomic,assign) BOOL isDraggingSubview;
// the subview being dragged
@property(nonatomic,strong) UIView *draggingSubview;
@end
@protocol PoliteScrollViewDelegate <NSObject>
@optional
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesBegan:(NSSet *)touches;
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesMoved:(NSSet *)touches;
- (void)scrollView:(PoliteScrollView *)scrollView subviewTouchesEnded:(NSSet *)touches;
@end
關鍵的設計理念是在滾動視圖中拖動是模糊的。 用戶是否滾動或拖動子視圖? PoliteScroll視圖通過提供兩件事來處理這個問題:(1)方向的概念(水平如果它比它寬,否則是垂直的),以及(2)在垂直於它的方向的方向上構成阻力的閾值距離。 (默認為寬度或高度的1/10)。
我粘貼了這個,其他幾個文件都在一個粘貼箱中 ,包含以下內容:
要在項目中組合這些,將粘貼bin粘貼到適當命名的文件中,添加帶有PoliteScrollView的故事板(確保設置它的委托),添加一些圖像(ViewController嘗試將puppy0.jpeg添加到puppy4.jpeg。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.