1

Edit: 1/12/2013

Duplicate (answered) question. The source for the demo project has been updated to reflect.
I'd love to mark this question closed, and giver a proper 'dup' link, but I haven't the reputation for either. What a sad little man I am...


Disclaimer: This is a potentially overly-complex view I'm working on with what may be misguided intentions. I am very much open to the possibility that I'm missing some crucial piece of information/know-how needed to make this work, trying to do something that iOS simply won't do, or that I'm doing it completely wrong. If any of these are the case, I will happily accept an answer that convinces me as such, or just throws a piece of documentation/heavy book at my head with a page number that I may go RTFM.

The General Problem

For one view in a larger app, I'm trying to present to users a vertically-scrolling screen with four major elements. Listed top to bottom, they are as follows; some general information about a Thing (a UITextView), a list of related Stuff (a UITableView, as each represents a potential segue in the actual app), some more information (in the example, a UILabel), and an actionable button (a UIButton). The number of cells in the TableView for the related Stuff varies depending on what the Thing being presented is. so I've worked out a way to adjust the size of the tableView and move the UILabel and UIButton accordingly (detailed below, done in viewDidAppear:). It all works fine and dandy and scrolls and makes me happy, but then when I to press the button, it jumps back to the position it occupies in the Interface Builder view, completely disregarding my programmatic changes to its frame.

The Question(s)

Why?
Can it be fixed (and if so, how)?
Is there a differ and/or better way?

I wanted to post some pictures showing what exactly is going on, but I don't have the reputation, so have the full source to a demo project(See above). Feel free to muck around with the code and see what's going on first-hand.

All The Details

(Feel free to skip these)
The screen I've put together in Interface Builder (and in code) is organized as follows:

View Controller -- Doing what it does.
* UIView -- Used to set a static background.
  * UIScrollView -- Sized to the parent view, used for scrolling
    * UIView -- Width equal to ScrollView, height is arbitrarily large (1200 in my project)
                We shall call him "subScrollView"
      * Content
      * More Content

I have to perform the changes in size/position of the content views in my ViewController's viewDidAppear: method, as making the changes any sooner won't make it through to the view actually be presented.
The reason I need (or just have?) the subScrollView is, if all my content views are subviews of the ScrollView, the issue presented above will occur whenever a scroll happens---e.g. the view appears, the table resizes, the button moves, then the user scrolls the scene and the table snaps back to the size it was given in Interface Builder, and the button moves back to its original position.

Here's the code I'm using to adjust the content views:

whyEvenViewController.h

@interface whyEvenViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>

@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UILabel *wasteMoreSpaceLabel;
@property (weak, nonatomic) IBOutlet UIButton *aButton;

@property (nonatomic) NSInteger tableViewRowCount;

@end

whyEvenViewController.m

- (void)viewDidAppear:(BOOL)animated
{
    // Here's where we resize and move everything. If we attempt to make these
    // changes before this (e.g. in viewDidLoad, viewWillAppear:, or even
    // viewDidLayoutSubviews) they get changed back before this view transitions
    // onto the screen, be it from a Navigation Bar push, or opening the app.

    [super viewDidAppear:animated];

    // Get used to this guy. He's going to be helping us resize frames.
    CGRect newFrame;

    // Set the tableView's frame height to the height of its contentSize which
    // so the entire table (no mater how large it is) is visible.
    newFrame = self.tableView.frame;
    newFrame.size.height = self.tableView.contentSize.height;
    self.tableView.frame = newFrame;

    // Move the wasteMoreSpaceLabel to just below the tableView
    newFrame = self.wasteMoreSpaceLabel.frame;
    newFrame.origin.y = self.tableView.frame.origin.y + self.tableView.frame.size.height - 20;
    self.wasteMoreSpaceLabel.frame = newFrame;

    // Move aButton to just below the wasteMoreSpaceLabel
    newFrame = self.aButton.frame;
    newFrame.origin.y = self.wasteMoreSpaceLabel.frame.origin.y + self.wasteMoreSpaceLabel.frame.size.height + 8;
    self.aButton.frame = newFrame;

    // Set the size of the scroll view such that it ends 20 points below aButton.
    CGSize newSize = self.scrollView.contentSize;
    newSize.height = self.aButton.frame.origin.y + self.aButton.frame.size.height + 20;
    self.scrollView.contentSize = newSize;
}

Thanks for climbing down this wall of text, and thanks for your time.

Community
  • 1
  • 1

0 Answers0