Adding custom UIViews to a UIScrollview - how to c

2019-07-22 00:25发布

As an iOS newbie I'm trying to develop a (yet another) word game.

I have a UIScrollView holding an UIImageView with the board image.

The UIScrollView can be zoomed by double tap and pinch gestures:

app screenshot

Underneath the UIScrollView I have 7 draggable UIViews representing letter tiles.

The implementation in Tile.m handles dragging with touchesBegan, touchesMoved and posts a notification in touchesEnded.

The single view controller ViewController.m observes this notification and adds/removes the tile to/from the UIScrollView by the following code:

- (void) handleTileMoved:(NSNotification*)notification {
    Tile* tile = (Tile*)notification.object;

    if (tile.superview != _scrollView && 
        CGRectIntersectsRect(tile.frame, _scrollView.frame)) {

        [tile removeFromSuperview];
        [_scrollView addSubview:tile];
        tile.frame = CGRectMake(tile.frame.origin.x + _scrollView.contentOffset.x,
                                tile.frame.origin.y + _scrollView.contentOffset.y,
                                kTileWidth * _scrollView.zoomScale,
                                kTileScale * _scrollView.zoomScale);

    } else if (tile.superview == _scrollView &&
               !CGRectIntersectsRect(tile.frame, _scrollView.frame)) {

        [tile removeFromSuperview];
        [self.view addSubview:tile];
        [self adjustFrames];
    }
}

This kind of works, but I have 2 problems -

app screenshot

Problem 1: How to calculate the position and size of the letter tile, when I am adding it to the scroll view?

Are there any comfortable functions provided by iOS for that purpose or do I have to calculate those values manually (as shown in my code above)?

Problem 2: When I zoom the image view (the game board), then the letter pieces placed on it don't zoom. Probably because of this method?

- (UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView
{
    return _imageView;
}

How to fix this problem? I can't return several objects by the above method

UPDATE:

I have branched my app on GitHub and inserted a contentView between the scrollView and imageView (here fullscreen):

Xcode screenshot

Zooming the image and the tiles works then, but I can't scroll anymore.

I've printed out the contentSize and it seem to be okay with 1000x1000:

-[ViewController viewDidLoad]: image {1000, 1000}
-[ViewController viewDidLayoutSubviews] contentOffset={0, 0} contentSize={1000, 1000}
tile: N 9 {2, 433} {45, 45}
tile: V 1 {47, 433} {45, 45}
tile: L 9 {92, 433} {45, 45}
tile: R 4 {137, 433} {45, 45}
tile: B 7 {182, 433} {45, 45}
tile: B 8 {227, 433} {45, 45}
tile: M 5 {272, 433} {45, 45}
-[ViewController adjustZoom]: scrollView origin={0, 0} size={320, 431} minScale=0.320000 zoomScale=0.640000 maxScale=0.640000
-[ViewController adjustZoom]: imageView origin={0, 0} size={1000, 1000}
-[ViewController adjustZoom]: contentView origin={0, 0} size={640, 640}

I've tried changing _scrollView.canCancelContentTouches and _scrollView.translatesAutoresizingMaskIntoConstraints.

Also I've tried changing the interactivity checkbox of the UIImageView in Interface Builder, but it hasn't helped.

I couldn't figure out the problem by using Reveal app either (here fullscreen):

Reveal app

2条回答
一纸荒年 Trace。
2楼-- · 2019-07-22 00:59

for the problem 1:

there is two property of UIScrollView

 UIScrollView* sc = [[UIScrollView alloc] init];
 CGPoint pt = sc.contentOffset;
 CGFloat scale = sc.zoomScale;

and for the second problem I recommend scaling the letterImage while dragging and when it comes to placing on board place it with original size scrollview will show it good

查看更多
疯言疯语
3楼-- · 2019-07-22 01:06

Problem 2: Use your new contentView as superview for the board and the pieces. That way the position and the size of the pieces in the board coordinates will be independent of the zoom and pan applied to the contentView.

Problem 1: There is no longer problem 1!

查看更多
登录 后发表回答