ソリューションを提供しますが、全体が非常に大きいため、関連するスニペットのみを提供します。
また、ドラッグにジェスチャ認識機能 (UILongPressGestureRecognizer) を使用していることに注意してください。これは、ユーザーがオブジェクトを指で押したままにすることで、アプリでドラッグを開始する方法です。したがって、ドラッグできる各サブビューには独自の UILongPressGestureRecognizer が割り当てられており、その認識エンジンのターゲット/セレクターは、スクロールビューとサブビューの両方を管理する別のクラスにあります。
ジェスチャ認識エンジンのターゲットは次のとおりです。
-(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
}
}
あなたに関連するもの:
- ドラッグを開始するとき、ドラッグするビューをdragViewに保存し、その中心をスクロールビューに対する指の位置に設定します。
- startDrag は重要ではありません。画面上の一部を変更して、ドラッグしているユーザーを表示します
- 実際にオブジェクトを移動すると ( UIGestureRecognizerStateChanged )、ユーザーが指を動かしたポイントの量を取得し、そのデルタをユーザーの指の位置と一緒に使用して、scrollView を 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 をスクロールすることです。もちろん、ドラッグされたビューは一緒に移動するので、中心の反対側のオフセットでそれを補正します。
うまくいけば、これはあなたを助けることができます.