iOS 10 Issue: UIScrollView Not Scrolling, Even Whe

2019-04-09 16:54发布

问题:

UPDATE: This is an iOS 10 issue. This still works as before in iOS 9.

This is ...interesting.

I just converted my "teaching project" (a "toy" app) to Swift 3.

It has been working for a couple of years under Swift 1.2.

All of a sudden, my UIScrollView is not scrolling, even when I set the contentSize way past its lower boundary.

Here's the relevant code (the displayTags routine is called with an array of images that are displayed centered and slightly vertically offset, leading to a vertical chain):

    /*******************************************************************************************/
    /**
        \brief  Displays the tags in the scroll view.

        \param inTagImageArray the array of tag images to be displayed.
    */
    func displayTags ( inTagImageArray:[UIImage] )
    {
        self.tagDisplayView!.bounds = self.tagDisplayScroller!.bounds
        if ( inTagImageArray.count > 0 )    // We need to have images to display
        {
            var offset:CGFloat = 0.0    // This will be the vertical offset for each tag.

            for tag in inTagImageArray
            {
                self.displayTag ( inTag: tag, inOffset: &offset )
            }
        }
    }
    /*******************************************************************************************/
    /**
        \brief  Displays a single tag in the scroll view.

        \param inTag a UIImage of the tag to be displayed.
        \param inOffset the vertical offset (from the top of the display view) of the tag to be drawn.
    */
    func displayTag ( inTag:UIImage, inOffset:inout CGFloat )
    {
        let imageView:UIImageView = UIImageView ( image:inTag )
        var containerRect:CGRect = self.tagDisplayView!.frame   // See what we have to work with.
        containerRect.origin = CGPoint.zero
        let targetRect:CGRect = CGRect ( x: (containerRect.size.width - inTag.size.width) / 2.0, y: inOffset, width: inTag.size.width, height: inTag.size.height )
        imageView.frame = targetRect
        containerRect.size.height = max ( (targetRect.origin.y + targetRect.size.height), (containerRect.origin.y + containerRect.size.height) )
        self.tagDisplayView!.frame = containerRect
        self.tagDisplayView!.addSubview ( imageView )
        self.tagDisplayScroller!.contentSize = containerRect.size
        print ( "Tag Container Rect: \(containerRect)" )
        print ( "    Tag ScrollView Bounds: \(self.tagDisplayScroller!.bounds)" )
        inOffset = inOffset + (inTag.size.height * 0.31)
    }

Note that the scrollView's contentSize is expanded each time a tag is added. I checked (see the print statements), and the value seems to be correct.

The project itself is completely open-source.

This is where this issue manifests (I have other bugs, but I'll get around to fixing them after I nail this one).

I'm sure that I am doing something obvious and boneheaded (usually the case).

Anyone have any ideas?

回答1:

it will work when you will set contentSize on main thread and put this code in - (void)viewDidLayoutSubviews

- (void)viewDidLayoutSubviews
{
    dispatch_async (dispatch_get_main_queue(), ^
                    {
                        [self.scrollview setContentSize:CGSizeMake(0, 2100)];
                    });
}


回答2:

contentSize should be change in main thread in swift.

DispatchQueue.main.async {
        self.scrollView.contentSize = CGSize(width: 2000, height: 2000)
    }

This worked for me.



回答3:

OK. I solved it.

I remove every single auto layout constraint for the internal (scrolled) view at build time.

I assume that iOS 10 is finally honoring the contract by forcing the top of the scrolled view to attach to the top of the scroller, even though the user wants to move it.