为屏幕外失去响应的对象设置动画
我有一个 UIViewController。其中有一个 UITableView
,它在原点 0,0
处绘制。我还有一个在 0,-80
处绘制的 UIScrollView
,因此它位于屏幕外且不可见。
当按下菜单按钮时,我将 UIViewController
的框架向下移动 80 像素以显示 UIScrollView
。
这里的问题是 UIScrollView
根本没有响应。
如果我在 0,0
处绘制 UIScrollView,它在加载时可见,那么它工作得很好。我什至可以在屏幕外将其动画化,然后再返回屏幕,没有任何问题。
这是我的视图在动画之前的样子:
_____________________________
| | Frame -> (0,-80, 320, 80)
| ScrollView | **Offscreen**
|_____________________________|
| | <- Original view (0,0,320,480)
| |
| |
| |
| |
| |
| Original View |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|_____________________________|
当我制作动画时,我执行以下操作:
[UIView animateWithDuration:0.3
delay:0.0
options:(UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionCurveEaseIn)
animations:^{
self.view.frame = CGRectMake(0.0, (self.view.frame.origin.y + container.frame.size.height), self.view.frame.size.width, self.view.frame.size.height);
scroll.userInteractionEnabled = YES;
}
completion:^(BOOL finished) {
if (scrollLoaded == NO) {
[self loadFavorites];
scrollLoaded = YES;
}
}];
现在我的视图在动画之后看起来像这样:
_____________________________
| | Frame -> (0, -80, 320, 80)
| ScrollView |
|_____________________________|
| | <- Original view (0, 80, 320, 480)
| |
| |
| |
| |
| |
| Original View |
| |
| |
| |
| |
| |
| |
| |
|_____________________________|
| |
| **Offscreen** |
|_____________________________|
我已经对我的 scrollView 进行了子类化code> 更仔细地监听事件:
.h
#import <UIKit/UIKit.h>
@interface UIScrollView_ExtraTouch : UIScrollView
@end
.m
#import "UIScrollView+ExtraTouch.h"
@implementation UIScrollView_ExtraTouch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesBegan");
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesMoved");
if(!self.dragging){
[self.nextResponder touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesEnded");
[self.nextResponder touchesEnded:touches withEvent:event];
}
@end
动画结束后不会有任何日志记录。我认为意味着由于帧位于-80
,它认为它在屏幕外,因此不会接收任何类型的操作。
这是正确的吗?如果是这样有办法解决吗?
I have a UIViewController
. Within that is a UITableView
which is drawn at origin 0,0
. I also have a UIScrollView
that is drawn at 0,-80
so that it is off screen and not visible.
When a menu button is pressed, I animate the UIViewController
's frame down 80px to reveal the UIScrollView
.
The problem here is that the UIScrollView
does not respond at all.
If I draw the UIScrollView
at say 0,0
, where it IS visible on load, it works fine. I can even animate it off screen then back on screen with no issue.
Here is how my view looks before animating:
_____________________________
| | Frame -> (0,-80, 320, 80)
| ScrollView | **Offscreen**
|_____________________________|
| | <- Original view (0,0,320,480)
| |
| |
| |
| |
| |
| Original View |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|_____________________________|
When I animate I do the following:
[UIView animateWithDuration:0.3
delay:0.0
options:(UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionCurveEaseIn)
animations:^{
self.view.frame = CGRectMake(0.0, (self.view.frame.origin.y + container.frame.size.height), self.view.frame.size.width, self.view.frame.size.height);
scroll.userInteractionEnabled = YES;
}
completion:^(BOOL finished) {
if (scrollLoaded == NO) {
[self loadFavorites];
scrollLoaded = YES;
}
}];
Now my view looks like this after animating:
_____________________________
| | Frame -> (0, -80, 320, 80)
| ScrollView |
|_____________________________|
| | <- Original view (0, 80, 320, 480)
| |
| |
| |
| |
| |
| Original View |
| |
| |
| |
| |
| |
| |
| |
|_____________________________|
| |
| **Offscreen** |
|_____________________________|
I have subclassed my scrollView
to listen more closely for events:
.h
#import <UIKit/UIKit.h>
@interface UIScrollView_ExtraTouch : UIScrollView
@end
.m
#import "UIScrollView+ExtraTouch.h"
@implementation UIScrollView_ExtraTouch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesBegan");
[self.nextResponder touchesBegan:touches withEvent:event];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesMoved");
if(!self.dragging){
[self.nextResponder touchesMoved:touches withEvent:event];
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(@"scrollview touchesEnded");
[self.nextResponder touchesEnded:touches withEvent:event];
}
@end
Nothing goes to the log after the animation. Which I think means that since the frame is at -80
, it believes it to be off screen, thus not receive any type of action.
Is this correct? If so is there a way to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
滚动视图位于原始视图之外,因此您无法对其做出反应。要修复此问题,请创建一个足够大以包含整个内容区域的包装视图(scrollView 和 tableView 均作为子视图),将其添加到原始视图,并为该包装视图而不是原始视图设置动画。
因此包装视图将为 320x560,原始视图为 0,-80。然后根据需要将其上下移动 80。
The scroll view is outside of the original view so you cannot react with it. To fix create a wrapper view that is large enough to contain the whole content area(with scrollView & tableView both as subViews), add it to the original view, and animate this wrapper view instead of original view.
So wrapper view will be 320x560, and at 0,-80 in original view. Then move it up and down 80 as needed.