1

I have one ScrollView which contains one imageView (created programmatically with addSubView) and one view, which contains segmented control to change pictures. I added gesture recognisers for zooming. Horizontal position of the segmented control is fixed. The problem occurs when I try to click on the segmented control and the image is zoomed too much. It doesn't work. If zoom level is small, it keeps working and changes between images.
Two screenshots below illustrate the situation: 1) when segmented control works and 2) when it doesn't work.

http://cs617220.vk.me/v617220757/e375/hvRdXNe9SBY.jpg http://cs617220.vk.me/v617220757/e36e/E4auq4-kFL4.jpg

I think, the problem is in hierarchy of views and when added subview doesn't overlap view with segmented control - it works, and when overlap - it stops. I tried to place imageView to the bottom, here is the code:

[self.scrollView addSubview:self.imageView];
[self.scrollView sendSubviewToBack:self.imageView];

But this does not help, the problem remains. How can I put imageView to the bottom of the stack?

Update to comment: I have small UIView in between UIScrollView and segmented control. It seems, that I managed to catch the problem: it is the horizontal-fixing code. I used Reveal app to find this out. Two screenshots show the problem:
Everything is OK Here segmented control is placed just above small UIView. After zooming just a bit the screen looks like:
UIView scrolls away, but segmented control stays at the right place
So, the UIView goes away as the rest of the picture and does not have fixed horizontal position. What is interesting, that if I put segmented control directly on the UIScrollView, it works, but position is not fixed horizontally. This is the code:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect frame = _floorSelector.frame;
    frame.origin.x = scrollView.contentOffset.x;
    _floorSelector.frame = frame;
}

And this doesn't work (if I try to fix position of UIView, not segmented control):

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

{
    CGRect frame = _selectorView.frame;
    frame.origin.x = scrollView.contentOffset.x;
    _selectorView.frame = frame;
}

Solution:
Instead of blocking scrolling in one direction, I decided to get rid off all supplementary views and implement vertical scrolling for segmented view. The code is here:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect frame = _floorSelector.frame;
    frame.origin.y = -scrollView.contentOffset.y;
    _floorSelector.frame = frame;
}

And the view hierarchy as follows:
View hierarchy
So, the segmented control is placed directly on main view, not the scroll view. When scrolling is being performed vertically, it scrolls too, but, when horizontally - it doesn't. Thank's for help.
As Departamento B helped me to solve this problem (it's his idea), I mark his answer with a tick.

Richard Topchii
  • 7,075
  • 8
  • 48
  • 115

2 Answers2

1

See original question for the solution finally implemented.

Original answer below:


Controlling vertical and horizontal control separately:

  • Root view
    • Scrollview -- fits in width, scrolls vertically and height is updated in size by pinch
      • Segmented control
      • Scrollview -- Fits parent scrollview in height, width is updated by pinch
        • Image -- width and height are updated by pinch

Concern: how well does diagonal scrolling work? I would suggest trying it out in a simple static storyboard screen before rebuilding your whole screen.

I have been toying around with this idea and you should do a lot of coding around forwarding the gestures as the outer scrollview grabs all the touches.

Lucas van Dongen
  • 9,328
  • 7
  • 39
  • 60
  • Nice idea, but there is thing that stop me from this approach: is that segmented control should float and be able to scroll vertically so the screen space could be used by content. As I understand, there is some newer approach to this design, so I would like to ask you to share it. I used WWDC 2011 idea "Adwanced Scrolling Techniques". – Richard Topchii Jun 15 '14 at 03:38
  • OK so you want it to scroll vertically the same as the image but horizontally it should stay centered? I've updated my answer with an idea. – Lucas van Dongen Jun 15 '14 at 14:54
0

How to do it

You can put your view at the bottom of stack by adding it at the first index:

[self.scrollViewinsertSubview:aView atIndex:0];

Issue

But scrolling has some issues when you have multiple subviews in scrollView. So what you should do:

Solution

  1. Create a view and add it to the scrollView
  2. On this view you have just created, add your items (yourImageView at the index 0, and after add your segmentedView)
  3. Follow the code below

Code

//adding your view, as a subview of scrollView
[self.scrollView addSubview:self.yourView atIndex:0];

//On your view insert at index 0 your self.imageView
[self.yourView sendSubviewToBack:self.imageView atIndex:0];

//Now add your segmentedView
[self.yourView sendSubviewToBack:self.segmentedView];
E-Riddie
  • 14,660
  • 7
  • 52
  • 74