UIScrollView
があり、中に別のUIScrollView
があります。どちらも水平方向にスクロールされ、pagingEnabled = YES
が付いています。私が内側のスクロールビューをスクロールし始め、最も右の境界に到達したと仮定します。そして、スクロールして進むと、外側のscrollViewが動き始めます。これを避ける必要があります。内部ビューはラバーバンド効果でジャンプし、外部ビューはその場所に留まる必要があります。
それが明確であることを願っていますが、ここにスケッチがあります:
outerView.scrollEnabled = NO;
を次のように設定しようとしました:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
outerView.scrollEnabled = NO;
}
、そしてinnerViewだけでスクロールする場合、私が必要とする方法で正確に機能します。 OuterViewはもうスクロールされません。しかし、outerViewをもう一度スクロールする場合は、scrollEnabled
をYESに戻す必要があります。私はここでそれをやろうとしました:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
outerView.scrollEnabled = YES;
}
、しかし私が同じ問題を抱えているよりも、ラバーバンド効果のあるinnerViewジャンプの代わりにinnerView outerViewスクロールの最も適切な境界に到達した後。
問題を解決するための提案はありますか?
[〜#〜]更新[〜#〜]
このソリューションは常に機能します。
_@implementation InnerScrollViewController <UIScrollViewDelegate, UIGestureRecognizerDelegate>
- (void)viewDidLoad
{
UISwipeGestureRecognizer* swipeGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipe:)] autorelease];
swipeGesture.delegate = self;
[self.view addGestureRecognizer:swipeGesture];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
_outerScrollView.scrollEnabled = NO;
return YES;
}
- (void)handleSwipe:(UIGestureRecognizer*)gestureRecognizer
{
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
_outerScrollView.scrollEnabled = NO;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (!decelerate)
{
_outerScrollView.scrollEnabled = YES;
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
_outerScrollView.scrollEnabled = YES;
}
@end
_
---------------------------------------------- -------------------------
古い答え:常に機能するとは限りません
これが私が問題を解決した方法です:
_@implementation InnerView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.delaysContentTouches = NO;
}
return self;
}
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
{
return NO;
}
_
私が理解しているように、_self.delaysContentTouches = NO;
_はすべてのイベントをすぐに配信するようにし、- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
はレスポンダーチェーンによるこれらのイベントの通過を防ぎます。
以下の方法でメソッドを変更します。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if(scrollView == innerView)
outerView.scrollEnabled = NO;
else
outerView.scrollEnabled = YES;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
if(scrollView == innerView)
{
if(innerView.contentOffset.x + innerView.frame.size.width == innerView.contentSize.width)
{
outerView.scrollEnabled = NO;
}
else
{
outerView.scrollEnabled = YES;
}
}
}
同様の問題があります。解決策を見つけましたが、innerScrollView.bounces = NO
でのみ機能します。
@interface PageCtrl ()
@property (weak, nonatomic) IBOutlet UIScrollView *innerScrollView;
@property(nonatomic) UIPanGestureRecognizer *panLockScroll;
@end
@implementation PageCtrl
- (void)viewDidLoad {
// ...
self.innerScrollView.delegate = self;
self.innerScrollView.bounces = NO; // disable bounces!
self.panLockScroll = [[UIPanGestureRecognizer alloc]initWithTarget:self action:nil];
self.panLockScroll.delegate = self;
[self.innerScrollView addGestureRecognizer:self.panLockScroll];
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)otherGestureRecognizer{
if( gestureRecognizer == self.panLockScroll &&
otherGestureRecognizer == self.innerScrollView.panGestureRecognizer ){
return YES;
}
return NO;
}
@end
これは私にとってうまくいきます:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
outerScrollView.scrollEnabled = NO;
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[NSTimer scheduledTimerWithTimeInterval:0.3
target:[NSBlockOperation blockOperationWithBlock:^{ outerScrollView.scrollEnabled = YES; }]
selector:@selector(main)
userInfo:nil
repeats:NO];
}
クラス宣言でUIScrollViewDelegateを採用し、innerScrollViewのデリゲートをselfに設定することを忘れないでください(outerScrollViewのデリゲートを割り当てないでください)。