我在 xib 中有两个滚动视图,它们都包含一个非常大的图像,应该从完全按比例缩小以适合。第一个 ScrollView 完美运行,当您缩放或滚动时,对象都在正确移动,但第二个 ScrollView 开始完全放大,无法缩小。
ScrollView 现在显示 25% 的图像(在 0,0 处完全放大),也无法拖动以查看其余部分。如果我捏缩放,图像沿对角线向上和向左移动而根本不缩放,我现在可以将图像拖回 0,0 并返回到它对角滚动的最大点。
.h 文件
UIScrollView *_scrollView;
UIScrollView *_miamiScrollView;
UIView *_mapImageView;
UIView *_mapMiamiView;
UIView *_mapContentView;
NSArray *_autoLayoutViews;
NSArray *_staticViews;
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;//(linked to working scrollview)
@property (strong, nonatomic) IBOutlet UIScrollView *miamiScrollView;//(Linked to 'broken' scrollview)
.m 文件
- (void)viewDidLoad
{
    [self _customizeViews];
}
- (void) _customizeViews
{
    UIImageView *mapImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"MainGameDisplay.jpg"]];
    mapImageView.userInteractionEnabled = YES;
    UIImageView *mapMiamiView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"miami.jpg"]];
    mapMiamiView.userInteractionEnabled = YES;
    _mapContentView = [[UIView alloc] initWithFrame:CGRectMake(0, 50, 568, 270)];
    _mapContentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    _mapContentView.clipsToBounds = YES;
    _mapContentView.userInteractionEnabled = YES;
    [_mapContentView addSubview:_scrollView];
    [_mapContentView addSubview:_miamiScrollView];
    [self.view addSubview:_mapContentView];
    [self.view sendSubviewToBack:_mapContentView];
    UIScrollView *scrollView = _scrollView;
    CGRect scrollFrame = scrollView.frame;
    scrollFrame.origin = CGPointZero;
    scrollView.frame = scrollFrame;
    scrollView.delegate = self;
    scrollView.minimumZoomScale = 1;
    scrollView.maximumZoomScale = 1.0;
    [scrollView addSubview:mapImageView];
    scrollView.contentSize = mapImageView.frame.size;
    _scrollView = scrollView;
    _mapImageView = mapImageView;
    UIScrollView *miamiScrollView = _miamiScrollView;
    CGRect miamiScrollFrame = CGRectMake(0 , 270, 568, 270);
    scrollFrame.origin = CGPointZero;
    miamiScrollView.frame = miamiScrollFrame;
    miamiScrollView.delegate = self;
    miamiScrollView.minimumZoomScale = 0.125;
    miamiScrollView.maximumZoomScale = 1;
    [miamiScrollView addSubview:mapMiamiView];
    miamiScrollView.contentSize = mapMiamiView.frame.size;
    _miamiScrollView = miamiScrollView;
    _mapMiamiView = mapMiamiView;
    [self _setupAutolayoutViews];
    [self _setupStaticViews];
    [self _zoomToFit: _scrollView];
    [self _zoomToFit: _miamiScrollView];
   [self _updatePositionForViews:_autoLayoutViews];
}
- (void) _zoomToFit: (UIScrollView*)view
{
    CGFloat contentWidth = view.contentSize.width;
    CGFloat contentHeigth = view.contentSize.height;
    CGFloat viewWidth = view.frame.size.width;
    CGFloat viewHeight = view.frame.size.height;
    CGFloat width = viewWidth / contentWidth;
    CGFloat heigth = viewHeight / contentHeigth;
    CGFloat scale = MAX(width, heigth);
    if ( scale < view.minimumZoomScale ) {
        view.minimumZoomScale = scale;
    } else if ( scale > view.maximumZoomScale ) {
        view.maximumZoomScale = scale;
    }
    view.zoomScale = scale;
}
#pragma mark - Positions
- (void) _updatePositionForViews:(NSArray *)views
{
    CGFloat scale = _scrollView.zoomScale;
    CGPoint contentOffset = _scrollView.contentOffset;
    contentOffset.x -= _scrollView.frame.origin.x;
    contentOffset.y -= _scrollView.frame.origin.y;
    for ( UIView *view in views ) {
        CGPoint basePosition = [self _basePositionForView:view];
        [self _updatePositionForView:view scale:scale basePosition:basePosition offset:contentOffset];
    }
}
- (CGPoint) _basePositionForView:(UIView *)view
{
    NSString *key = [NSString stringWithFormat:@"%d", view.tag];
    NSString *stringValue = [_coordinates objectForKey:key];
    NSArray *values = [stringValue componentsSeparatedByString:@":"];
    if ( [values count] < 2 ) return CGPointZero;
    CGPoint result = CGPointMake([[values objectAtIndex:0] floatValue], [[values objectAtIndex:1] floatValue]);
    return result;
}
- (void) _updatePositionForView:(UIView *)view scale:(CGFloat)scale basePosition:(CGPoint)basePosition offset:(CGPoint)offset;
{
    CGPoint position;
    position.x = (basePosition.x * scale) - offset.x;
    position.y = (basePosition.y * scale) - offset.y;
    CGRect frame = view.frame;
    frame.origin = position;
    view.frame = frame;
}
////////////////////////////////////////////////////////////////////////////////////// 
#pragma mark - UIScrollViewDelegate
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
{
    [self _lockInteraction];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate;
{
    [self _unlockInteraction];
}
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
    [self _lockInteraction];    
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale;
{
    [self _unlockInteraction];
}
- (void) _lockInteraction
{
    [self _setControls:_staticViews interacted:NO];
    [self _setControls:_autoLayoutViews interacted:NO];
}
- (void) _unlockInteraction
{
    [self _setControls:_staticViews interacted:YES];
    [self _setControls:_autoLayoutViews interacted:YES];
}
- (void) _setControls:(NSArray *)controls interacted:(BOOL)interacted
{
    for ( UIControl *control in controls ) {
        if ( [control isKindOfClass:[UIControl class]]) {
            control.userInteractionEnabled = interacted;
        }
    }
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    [self _updatePositionForViews:_autoLayoutViews];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [self _updatePositionForViews:_autoLayoutViews];
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView;
{
    return _mapImageView;
}
//DEFAULT BUTTONS.
- (void) _setupAutolayoutViews
{
    UIButton *btn1 = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
    [btn1 addTarget:self action:@selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
    btn1.tag = kAddContactButton;
    btn1.center = CGPointZero;
    [_mapContentView addSubview:btn1];
    _autoLayoutViews = [[NSArray alloc] initWithObjects:btn1, nil];
}
//CUSTOM BUTTONS.
- (void) _setupStaticViews
{
    UIButton *openMiamiButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [openMiamiButton setBackgroundImage:[UIImage imageNamed:@"logo.png"] forState:UIControlStateNormal];
    [openMiamiButton addTarget:self action:@selector(quickTest:) forControlEvents:UIControlEventTouchUpInside];
    openMiamiButton.frame = CGRectMake(0.0 ,0.0, 50.0, 50.0);
    openMiamiButton.tag = OpenMiamiButton;
    openMiamiButton.enabled = YES;
    openMiamiButton.alpha = 0.5;
    [_mapImageView addSubview:openMiamiButton];
    _staticViews = @[openMiamiButton,];
    for ( UIView *view in _staticViews ) {
        CGPoint point = [self _basePositionForView:view];
        CGRect frame = view.frame;
        frame.origin = point;
        view.frame = frame;
    }
}
//And for the transition between views:
-(void) quickTest: (UIButton *)button
{
    /*
    if (!openMiami)
        openMiami = [[MiamiGameDisplay alloc] initWithNibName:nil bundle:nil];
    openMiami.mainPage = self;
    [self.navigationController pushViewController:openMiami animated:YES];
     */
    if (!testBool){
    [UIView animateWithDuration:0.5f
                     animations:^{
                         _scrollView.frame = CGRectMake(0 , -270, 568, 270);
                     }
                     completion:Nil];
        [UIView animateWithDuration:0.5f
                         animations:^{
                             _miamiScrollView.frame = CGRectMake(0 , 0, 568, 270);
                         }
                         completion:Nil];
        testBool=YES;
    }
    else {
        [UIView animateWithDuration:0.5f
                         animations:^{
                             _miamiScrollView.frame = CGRectMake(0 , 270, 568, 270);
                         }
                         completion:Nil];
        [UIView animateWithDuration:0.5f
                         animations:^{
                             _scrollView.frame = CGRectMake(0 , 0, 568, 270);
                         }
                         completion:Nil];
        testBool=NO;
    }
}