3
votes

I'm interested in implementing a paging UIScrollView experience, very similar to the current Twitter app, where there is a main paging UIScrollView (horizontal scrolling) at the top of the view hierarchy, and several other (vertical scrolling) UIScrollViews or UITableViews as the paging UIScrollView's subview.

I was taking reference from this WWDC video where they described how we could add a/several "zooming" scrollViews as a subview of a bigger "paging" scrollView.


In my current setup, I have: A ViewController in storyboard with hierarchy as follows: View > ScrollView (contentScrollView) > Several subviews (UIImageViews, UIButtons and UILabels).

When that view is being loaded, I call a method setupPagingScrollView method in its viewDidAppear.

- (void)setupPagingScrollView
{
    // Setup the PAGING UIScrollView
    self.pagingScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 340, self.view.frame.size.height)];
    self.pagingScrollView.contentSize = CGSizeMake(680, self.view.frame.size.height);
    self.pagingScrollView.pagingEnabled = YES;
    self.pagingScrollView.backgroundColor = [UIColor blackColor];

    // Remove the CONTENT UIScrollView (from storyboard) from the view.
    // Add the CONTENT UIScrollView (from storyboard), as a subview of the newly created PAGING UIScrollView
    [self.contentScrollView removeFromSuperview];
    [self.pagingScrollView addSubview:self.contentScrollView];
    [self.view addSubview:self.pagingScrollView];


    // Create the 2nd page, which is a UITableView
    self.tableView = ({
        UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(340, 0, 320, self.view.frame.size.height) style:UITableViewStylePlain];
        tableView.delegate = self;
        tableView.dataSource = self;
        tableView.backgroundColor = [UIColor whiteColor];
        tableView.tableFooterView = [UIView new];
        tableView.contentInset = UIEdgeInsetsMake(50, 0, 0, 0);
        tableView;
    });
    [self.pagingScrollView addSubview:self.tableView];


    // UINavigationBar for the UITableView in the 2nd page.
    self.likesCommentsNavBar = ({
        UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(340, 0, 320, 44)];
        UINavigationItem *navItem = [[UINavigationItem alloc] init];

        UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:@[@"Likes", @"Comments"]];
        [segmentedControl addTarget:self action:@selector(toggleLikesCommentsWithSegmentedControl:) forControlEvents:UIControlEventValueChanged];
        segmentedControl.selectedSegmentIndex = 0;

        navItem.titleView = segmentedControl;
        navBar.items = @[navItem];

        navBar;
    });

    [self.pagingScrollView addSubview:self.likesCommentsNavBar];\
}

My intended end result would be something like the twitter application, just that instead of panning between 3 UITableViews, my first view would be a custom view with some images, labels, and buttons, and the 2nd and 3rd page would be UITableViews.

I have created a mockup of my intended result

enter image description here

Currently, I am able to get the result I want but I realize that there is some choppiness in the performance. Am I doing something wrong here by allocating memory to so many views or something?

Many thanks!

1
images being loaded when you scroll could be the culprit (if that happens at all) when loading images you can load them on a background thread and then present them on the main thread so that the UI thread isnt blocked while loading the images, not sure if that is the actual reason for your problem but ive had this problem before and it made my scrolling experience much smootherFonix
Do you have more code for this example that you got working? I am really interesting in something like the twitter app. Thanksmikemike396
@Pyraego.com I realized that the one making everything choppy was the self.likesCommentsNavBar. I commended that chunk away and the performance is back to normal. I'm not sure why though.Ryan

1 Answers

0
votes

Incase the image loading on the main thread is the problem here, here is an easy way to load images on a background thread

UIImageView *imageView = [[UIImageView alloc] init]; // can be your IBOutlet or something instead

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{

    UIImage *image = [UIImage imageNamed:@"imageName"];

    dispatch_sync(dispatch_get_main_queue(), ^{

        imageView.image = image; //can add some fade in animation or something here too
    });
});