5 までのステップにはサブビュー自体の作成が含まれますが、panGestureRecognizer に関するステップ 5 から読み取られるドラッグ イベントのみに関心がある場合。
カスタム UIView を作成します。サブビューでアクションが発生したときに viewController に通知するデリゲート プロトコルも作成しました。サブビューがどれほど複雑になるかによって、同じ名前の xib ファイルを作成したい場合があります。これからは filterView と呼びましょう。
filterView に「hide」と「show」のような 2 つのメソッドを作成します。filterView を閉じたり開いたりするためのボタン (つまり、矢印の付いた小さなボタン。ここでは dropdownButton と呼びます) を使用したくない場合は、この手順をスキップできますが、実装することを強くお勧めします。あなたがしなければならないことは、filterView.frame.origin.yをアニメーション化することです
リクエストがあれば、そのアニメーションのコードも送信できます。
3. UIViewController の xib ファイルを開き、UIView を追加して、ドロップダウン ボタンのみが表示されるようにします。ビューをクリックし、インターフェイス ビルダーの右端のペインを使用して、そのクラスを filterView に変更します。このステップで、すべてを正しく行った場合、filtersView のヒントがページの下部に表示されるはずです。そうでない場合、filterView.xib ファイルが filterView ソース コード ファイルに正しく接続されていない可能性があります。
4 . ViewController に FilterView をインポートし、IBOutlet として接続して合成します。デリゲート プロトコルを作成している場合は、デリゲート プロトコルを実装します。filterView にボタンがある場合は、後で必要になります。デリゲート プロトコルには、次のようなオプションのメッセージを含める必要があります。
-(void) featuresButtonTappedOnFilterView: (FilterView *) filterView;
実装では、別のviewControllerを開くなど、viewControllerで行う必要があることを行う必要があります。
5. viewControllers xib ファイルで panGestureRecognizer を作成し、filterViewに追加します。PanGestureRecognizer は、ドラッグ イベントを処理する GestureRecognizer です。最初は、filterView 全体を任意のポイントをクリックしてドラッグできますが、これについては後で説明します。GestureRecognizer を IBOutlet として接続し、次のような IBAction を (できればより適切な名前で) 作成します。
-(IBAction)_panRecogPanned:(id)sender;
ViewController の viewDidLoad メソッドで、デリゲートを次のように設定することを忘れないでください。
[_panRecog setDelegate:self];
6 . より強力な他の状態を実装します。しかし、最初は stateChanged で十分です。
- (IBAction)_panRecogPanned:(id)sender {
switch ([(UIPanGestureRecognizer*)sender state]) {
case UIGestureRecognizerStateBegan: { } break;
case UIGestureRecognizerStateChanged: {
if ( [((UIPanGestureRecognizer *)sender) locationInView:_filterView].y > dropDownButton.frame.height )
return; // Only drag if the user's finger is on the button
CGPoint translation = [_panRecog translationInView:filterView];
//Note that we are omitting translation.x, otherwise the filterView will be able to move horizontally as well. Also note that that MIN and MAX were written for a subview which slides down from the top, they wont work on your subview.
CGRect newFrame = _panRecog.view.frame;
//newFrame.origin.y = MIN (_panRecog.view.frame.origin.y + translation.y, FILTER_OPEN_ORIGIN_Y);
//newFrame.origin.y = MAX (newFrame.origin.y, FILTER_INITIAL_ORIGIN_Y);
newFrame.origin.y = _panRecog.view.frame.origin.y + translation.y;
_panRecog.view.frame = newFrame;
[_panRecog setTranslation:CGPointMake(0, 0) inView:self.view];
} break;
//Remember the optional step number 2? We will use hide/ show methods now:
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled: {
//CGPoint velocity = [_panRecog velocityInView:_panRecog.view];
//Bonus points for using velocity when deciding what to do when if the user lifts his finger
BOOL open;
/*
if (velocity.y < -600.0) {
open = NO;
}
else if (velocity.y >= 600.0) {
open = YES;
} else
*/
if ( _panRecog.view.frame.origin.y > (FILTER_OPEN_ORIGIN_Y + FILTER_INITIAL_ORIGIN_Y) / 2 ) {
open = YES;
}
else {
open = NO;
}
if (open == YES) {
[_filterView show];
}
else {
[_filterView hide];
}
} break;
default:
break;
}
}
注:サブビューがページの境界線から移動するため、フィルタービューはページの下部ではなく上部にありました。MAX ステートメントと MIN ステートメントをコメントアウトして修正します。自分で書くのが面倒です。コードはコピー&ペースト後に変更されます。タイプミスが含まれる可能性があります(おそらく含まれる可能性があります)。