Ios 滚动时移动整个UIScrollView。在顶部时,开始正常滚动

Ios 滚动时移动整个UIScrollView。在顶部时,开始正常滚动,ios,objective-c,cocoa-touch,uiwebview,uiscrollview,Ios,Objective C,Cocoa Touch,Uiwebview,Uiscrollview,我有一个scrollview,或者实际上是一个UIWebView,它最初位于其父视图顶部320px的位置 当用户开始滚动时,我希望整个UIWebView跟随向上移动,直到到达顶部,然后webview应该像正常一样开始滚动。我希望这发生在同一个手指运动。(也就是说,用户不需要抬起手指) 我已经在UIWebView上使用UIPangestureRecognitor实现了这一点(请参见下面的代码)。手势处理程序移动UIWebView并不断将scrollview的contentOffset重置为0。它可

我有一个scrollview,或者实际上是一个UIWebView,它最初位于其父视图顶部320px的位置

当用户开始滚动时,我希望整个UIWebView跟随向上移动,直到到达顶部,然后webview应该像正常一样开始滚动。我希望这发生在同一个手指运动。(也就是说,用户不需要抬起手指)

我已经在UIWebView上使用UIPangestureRecognitor实现了这一点(请参见下面的代码)。手势处理程序移动UIWebView并不断将scrollview的contentOffset重置为0。它可以工作,但性能很差,特别是当webview包含一个沉重的页面时。我猜是webview的滚动和重置使得渲染变得沉重。我的解决方案有点难闻,我想一定有更好的办法

您知道实现我的目标的更好的解决方案吗?

@interface ViewController ()
@property (strong, nonatomic) IBOutlet UIWebView *webView;
@property (nonatomic, strong) UIPanGestureRecognizer *panGestureRecognizer;
@property(nonatomic, strong) UIScrollView *webViewScrollView;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *webViewTopMarginConstraint;
@end

@implementation ViewController {
    BOOL gestureEnabled;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    gestureEnabled = YES;

    // Initially put the webview 320 px down on the topview
    self.webView.translatesAutoresizingMaskIntoConstraints = NO;
    self.webViewTopMarginConstraint.constant = 320.0;

    // SET UP GESTURE RECOGNIZER
    _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesturesForWebview:)];
    _panGestureRecognizer.minimumNumberOfTouches = 1;
    _panGestureRecognizer.maximumNumberOfTouches = 1;
    _panGestureRecognizer.delegate = self;
    [self.webView addGestureRecognizer:_panGestureRecognizer];

    // Get hold of the webviews scrollview
    for (UIView* subView in self.webView.subviews) {
        if ([subView isKindOfClass:[UIScrollView class]]) {
            _webViewScrollView = (UIScrollView *)subView;
        }
    }

    // Load a web page in the webview
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.macrumors.com"]];
    [self.webView loadRequest:requestObj];
}

- (void)handlePanGesturesForWebview:(UIPanGestureRecognizer *)gesture {

    if (gesture.state == UIGestureRecognizerStateChanged) {
        CGFloat transY = [gesture translationInView:self.view].y; //transY will be negative by the number of pixels panned when panning upwards
        if (gestureEnabled) {
            // Move the whole webview according to gesture movement upwards
            // todo Handle scrolling in the opposite direction
            self.webViewTopMarginConstraint.constant = 320 + transY;
            if (self.webViewTopMarginConstraint.constant <= 0.0) {
                // The webview is at the top, disable the gesture recognizer
                gestureEnabled = NO;
                self.webViewTopMarginConstraint.constant = 0.0;
                self.panGestureRecognizer.delegate = nil;
            }
            // "Rewind" the web scrolling
            CGPoint offset = CGPointMake(0.0, 0.0);
            [self.webViewScrollView setContentOffset:offset animated:NO];
        }
    }
}

#pragma mark UIGestureRecognizerDelegate impl
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}
@end
@界面视图控制器()
@属性(强,非原子)ibuiwebview*webView;
@属性(非原子,强)UIPangestureRecognitor*PangestureRecognitor;
@属性(非原子,强)UIScrollView*webViewScrollView;
@属性(强,非原子)IBMOutlet NSLayoutConstraint*webViewTopMarginConstraint;
@结束
@实现视图控制器{
BOOL-gesturenabled;
}
-(无效)viewDidLoad
{
[超级视图下载];
gestureEnabled=是;
//最初将webview 320 px放在topview上
self.webView.translatesAutoresizingMaskIntoConstraints=否;
self.webViewTopMarginConstraint.constant=320.0;
//设置手势识别器
_PangestureRecognitzer=[[UIPangestureRecognitzer alloc]initWithTarget:self action:@selector(HandlePangestResforWebView:)];
_PangestureRecognitor.MinimumNumberOfTouchs=1;
_PangestureRecognitor.MaximumNumberOfTouchs=1;
_pangestrerecognizer.delegate=self;
[self.webView addgestureerecognizer:_pangestureerecognizer];
//掌握网络视图滚动视图
for(self.webView.subView中的UIView*子视图){
if([subView iskindof类:[UIScrollView类]]){
_webViewScrollView=(UIScrollView*)子视图;
}
}
//在webview中加载网页
NSURLRequest*requestObj=[NSURLRequest requestWithURL:[NSURL URLWithString:@]http://www.macrumors.com"]];
[self.webView加载请求:requestObj];
}
-(无效)handlePanGesturesForWebview:(UIPangestureRecognitor*)手势{
如果(手势.state==UIGestureRecognitizerStateChanged){
CGFloat transY=[手势平移视图:self.view].y;//向上平移时平移的像素数将为负
如果(已启用手势){
//根据手势向上移动整个webview
//todo句柄向相反方向滚动
self.webViewTopMarginConstraint.constant=320+transY;

如果(self.webViewTopMarginConstraint.constant,我认为不移动scrollview,只需设置一个内容插入

CGFloat top = 320.0;     
self.webView.scrollView.contentInset = UIEdgeInsetsMake(top, 0.0, 0.0, 0.0);
请注意,您需要将部署目标设置为iOS5+,以便像这样获取滚动视图,而不是像您那样在子视图中循环

因此,总体而言,您的
viewDidLoad
方法将更加简单,并且不需要手势识别器:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CGFloat top = 320.0;     
    self.webView.scrollView.contentInset = UIEdgeInsetsMake(top, 0.0, 0.0, 0.0);
    self.webview.scrollView.delegate = self;
    // Load a web page in the webview
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.macrumors.com"]];
    [self.webView loadRequest:requestObj];
}
此外,根据您在原始帖子中的一条评论,您似乎还将另一个视图与scrollview一起移动。 在这种情况下,您需要通过scrollview委托跟踪滚动,并相应地移动另一个视图。这取决于另一个视图的内容(例如,如果它只是一个imageView横幅类型的东西),我个人会发现调整/裁剪其他视图比将其移出屏幕更为优雅;但我想这将是另一个问题

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    CGFloat offsetY = scrollView.contentOffset.y;
    //here whatever code you use to set that other view frame position
}

在回答实际问题之前,您是否考虑过在不“移动滚动视图,然后在一个移动中滚动”的情况下,以其他方式实现所需的视觉效果?您是否查看过插入/偏移之类的内容,以便在不必移动滚动视图的情况下实现类似的效果?谢谢!我没有尝试插入,但您不认为它会具有相同的“重新渲染”功能吗效果?我仍然需要将contentOffset设置为零,以重置UIWebView滚动。理想情况下,我希望在webview滚动发生之前阻止它,但我不能完全禁用滚动,因为那样我就无法在相同的手指运动中再次拾取滚动。因此,基本上您正在寻找r“视差”功能?@WrightsCS Parallax?你能详细说明一下吗?我没有提到的是,我最初在网络视图上方的320px空间中有另一个视图。除了移动网络视图之外,我还将另一个视图移出屏幕,这对用户来说就像网络视图和另一个视图是同一个滚动视图的一部分。当网络视图到达屏幕顶部会粘住,因此webview占据整个屏幕并开始正常滚动。请参见以下示例:✓&q=视差你能详细说明一下吗?我是否要更改手势处理程序中的插入值?我如何防止在webview中滚动(在它到达顶部之前)使用此解决方案?要么我误解了您的意图,要么您使问题复杂化。但是,据我所知,不需要手势处理程序。而且scrollview不会移动。您可以将scrollview帧的起始像素提高320像素,scrollview的前320像素最初将为空白(插图),滚动时,空白区域将被内容占据。我相信这是您试图实现的目标。我可能错了,因为我知道我从技术上没有回答您的问题(即如何将滚动视图移动到顶部,然后在没有空间移动滚动视图时移动内容);我回答了这个问题