ios UIScrollView 里面的 UIScrollView
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15437515/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIScrollView inside UIScrollView
提问by Anastasia
I have a UIScrollView
with another UIScrollView
inside. They both are scrolled horizontally and have pagingEnabled = YES
.
Assume that I started to scroll inner scroll view and reached the most right bound. And if I proceed scrolling in it, then the outer scrollView begins to move. I need to avoid this. Inner view should jump with rubber-band effect, outer should stay at it's place.
我有一个UIScrollView
与另一个UIScrollView
里面。它们都水平滚动并具有pagingEnabled = YES
. 假设我开始滚动内部滚动视图并到达最右边的边界。如果我继续在其中滚动,则外部 scrollView 开始移动。我需要避免这种情况。内部视图应具有橡皮筋效果,外部应停留在其位置。
Hope it's clear, but here is a sketch:
希望它很清楚,但这里有一个草图:
I've tried to set outerView.scrollEnabled = NO;
like this:
我试过这样设置outerView.scrollEnabled = NO;
:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
outerView.scrollEnabled = NO;
}
, and it works exactly how I need, if to scroll just in innerView. OuterView is not scrolled anymore. But I have to set scrollEnabled
back to YES somewhere for the case if I'd want to scroll outerView again.
I've tried to do it here:
,并且它完全按照我的需要工作,如果仅在innerView中滚动。OuterView 不再滚动。但是scrollEnabled
如果我想再次滚动outerView,我必须在某个地方设置回YES。我试过在这里做:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
outerView.scrollEnabled = YES;
}
, but than I'm getting the same problem: after reaching the the most right bound of innerView outerView scrolls instead of innerView jumps with rubber-band effect.
,但比我遇到了同样的问题:在到达 innerView 的最右侧边界后,outerView 滚动而不是具有橡皮筋效果的 innerView 跳跃。
Any suggestions how to solve a problem?
任何建议如何解决问题?
采纳答案by Anastasia
UPDATE
更新
This solution works always:
此解决方案始终有效:
@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
-----------------------------------------------------------------------
-------------------------------------------------- ---------------------
OLD ANSWER: doesn't work always
旧答案:并不总是有效
Here is how I solved the problem:
这是我解决问题的方法:
@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;
}
As I understand, self.delaysContentTouches = NO;
makes all events to be delivered immediately, and - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
prevents passing of these events by responder chain.
据我了解,self.delaysContentTouches = NO;
使所有事件立即传递,并- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view
防止响应者链传递这些事件。
回答by Apurv
Modify your methods by below way:
通过以下方式修改您的方法:
- (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;
}
}
}
回答by Eol
I have a similar issue. I found the solution, but it works only with innerScrollView.bounces = NO
.
我有一个类似的问题。我找到了解决方案,但它仅适用于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
回答by etayluz
This works well for me:
这对我很有效:
- (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];
}
Remember to adopt the UIScrollViewDelegate in your class declaration and to set the delegate of the innerScrollView to self (do NOT assign the delegate of the outerScrollView)
记住在你的类声明中采用 UIScrollViewDelegate 并将innerScrollView的委托设置为self(不要分配outerScrollView的委托)