我會給你我的解決方案,但由於整個事情是相當大的我我會給你相關的片段。另外,請注意,我使用手勢識別器進行拖動(UILongPressGestureRecognizer),因爲這是用戶在我的應用程序中啓動拖動的方式,方法是將他的手指按在對象上。因此,每個可以拖動的子視圖都有自己的UILongPressGestureRecognizer分配給它,並且該識別器的目標/選擇器位於另一個同時管理scrollview和子視圖的類中。
這裏是手勢識別的目標:
- 當開始我店拖動它查看我拖動dragView並設置其中心:
-(void)dragged:(UILongPressGestureRecognizer *)panRecog
{
if (panRecog.state == UIGestureRecognizerStateBegan)
{
UIView * pannedView = panRecog.view;
dragView = pannedView;
dragView.center = [panRecog locationInView:scrollView];
[scrollView bringSubviewToFront:dragView];
[self startDrag]; // Not important, changes some stuff on screen to show the user he is dragging
return;
}
if (panRecog.state == UIGestureRecognizerStateChanged)
{
int xDelta = dragView.center.x - [panRecog locationInView:scrollView].x;
dragView.center = [panRecog locationInView:scrollView];
[self scrollIfNeeded:[panRecog locationInView:scrollView.superview] withDelta:xDelta];
return;
}
if (panRecog.state == UIGestureRecognizerStateEnded)
{
[self endDrag]; // Not important, changes some stuff on screen to show the user he is not dragging anymore
}
}
,對於你相關的事情成爲你的手指相對於它所處的滾動視圖的位置。
- startDrag對你不重要,它改變屏幕上的某些東西以顯示他正在拖動的用戶
- 當我們實際移動我們的對象(UIGestureRecognizerStateChanged)時,我得到了用戶移動他的手指的點數,並將該增量與用戶的手指位置一起用於檢查scrollId是否需要在scrollIfNeeded中移動。
這是代碼
-(void)scrollIfNeeded:(CGPoint)locationInScrollSuperview withDelta:(int)xDelta
{
UIView * scrollSuperview = scrollView.superview;
CGRect bounds = scrollSuperview.bounds;
CGPoint scrollOffset = scrollView.contentOffset;
int xOfs = 0;
int speed = 10;
if ((locationInScrollSuperview.x > bounds.size.width * 0.7) && (xDelta < 0))
{
xOfs = speed * locationInScrollSuperview.x/bounds.size.width;
}
if ((locationInScrollSuperview.x < bounds.size.width * 0.3) && (xDelta > 0))
{
xOfs = -speed * (1.0f - locationInScrollSuperview.x/bounds.size.width);
}
if (xOfs < 0)
{
if (scrollOffset.x == 0) return;
if (xOfs < -scrollOffset.x) xOfs = -scrollOffset.x;
}
scrollOffset.x += xOfs;
CGRect rect = CGRectMake(scrollOffset.x, 0, scrollView.bounds.size.width, scrollView.bounds.size.height);
[scrollView scrollRectToVisible:rect animated:NO];
CGPoint center = dragView.center;
center.x += xOfs;
dragView.center=center;
}
這件事情不僅水平滾動條,但處理垂直將是非常相似的。它的功能是:
- 檢查是否拖動到滾動視圖的邊界區域(我使用左右30%邊框作爲滾動應該發生的區域)。但只有當用戶在這個方向移動(xDelta < 0左邊,xDelta> 0右邊)
- 接下來我計算了多少移動滾動視圖,使用速度常數和縮放這與多遠用戶是從滾動視圖的實際邊界,因此速度與用戶邊緣距離成正比。
- 最後一步是使用非動畫scrollRectToVisible滾動scrollview。當然 您拖動的視圖會沿着它移動,所以我們用其中心的相反偏移來補償。
希望這可以幫助你。
這就是我需要的!真的非常感謝 – ultragtx
幹得好,謝謝;)! – Oliver
這工程太棒了!但是,您的xDelta計算應該是當前位置減去最後一個位置。最終值減去初始值,這樣一個正xDelta減號用戶向右拖,而負xDelta意味着他們拖到左側。但它也適用於你的方式。 :) – ucangetit