これが私がやった方法です:
shouldRecognizeSimultaneouslyWithGestureRecognizer (thanks @omz!) とカスタム スワイプ ジェスチャレコグナイザーを垂直スクロール ビューで使用する (同様の質問を参照)
垂直パンジェスチャを使用した水平スクロール UIScrollView )、次の設定があります。
@interface UIScrollView (GestureRecognition) <UIGestureRecognizerDelegate>
@end
@interface OuterHorizontalScrollView : UIScrollView ...
@property (weak) InnerVerticalScrollView *currentView; // Current inner vertical scroll view displayed.
@end
@implementation OuterHorizontalScrollView
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (self.currentActiveView.placeVerticalScrollView.dragging == NO) {
self.currentActiveView.placeVerticalScrollView.scrollEnabled = NO;
return YES;
} else {
return NO;
}
}
@end
@interface InnerVerticalScrollView : UIScrollView...
@property UISwipeGestureRecognizer *swipeGestureRecognizer;
@end
@implementation InnerVerticalScrollView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
...
self.swipeGestureRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
self.swipeGestureRecognizer.direction = UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp;
[self addGestureRecognizer:self.swipeGestureRecognizer];
}
return self;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if (gestureRecognizer == self.panGestureRecognizer && self.scrollEnabled == YES) {
return YES;
} else if (gestureRecognizer == self.swipeGestureRecognizer) {
return YES;
} else {
self.scrollEnabled = NO;
}
return NO;
}
- (void)handleSwipeGesture:(UIGestureRecognizer *)sender {
self.scrollEnabled = YES;
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
このコードは少しハックです: カスタム スワイプ ジェスチャが認識された場合 (上方向または下方向のみ) にのみ垂直スクロール ビューのスクロールを許可し、他のすべてのジェスチャは外側のスクロール ビューに渡されます。の内側スクロール ビューがドラッグされています。
注: スワイプ ジェスチャが低速または小さなスワイプでも機能することは明らかではありませんでしたが、機能します (上記の引用された質問へのコメントも参照してください)。
もっと簡単に達成できると思うので、後でリファクタリングするかもしれません。
とにかく、外側のスクロールが完全に機能するようになりました-内側のスクロールビューの垂直方向のパンが時折発生することなく、水平方向にスクロールします。
後の更新:前に予想したように、私のソリューションには不要なコードが含まれていました: @burik の回答を参照してください。