Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I worked on this challenge tonight. I ran the code in the iPhone Simulator; it seems to work. However, I did not attempt to match the exact specifications of the OP, nor did I follow the link to tips on how to do this. I just wanted to see what I could knock out on my own in a couple of hours.</p> <p>There's nothing to see in storyboard except an empty, yellow scroll view pinned to the sides of the root view. </p> <p>The gray floating views are inside a yellow scroll view. The width of the scroll view's content size is the width of the root view; the height of the content size shrinks and expands to accommodate the varying number of rows. </p> <p>The only place I didn't use Auto Layout was for the scroll view's content view (here, I used Apple's so-called "Mixed Approach"). </p> <p>The widths of the floating cells are randomly generated whenever viewWillLayoutSubviews is called. Hence, all floating cells change their width upon device rotation. I held the height of all floating cells to a constant. </p> <p><img src="https://i.stack.imgur.com/gJ5jE.png" alt="enter image description here"></p> <p><img src="https://i.stack.imgur.com/hhwdd.png" alt="enter image description here"></p> <pre><code>@interface ViewController () @property (nonatomic, strong) NSMutableArray *floatingViews; @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; @property (nonatomic, strong) UIView *contentView; @end @implementation ViewController #define NUM_OF_VIEWS 18 #define HEIGHT 30.0f #define HORIZONTAL_SPACER 20.0f #define VERTICAL_SPACER 10.0f - (void)viewDidLoad { [super viewDidLoad]; self.contentView = [[UIView alloc] initWithFrame:self.view.bounds]; [self.scrollView addSubview:self.contentView]; self.floatingViews = [[NSMutableArray alloc] init]; for (int i = 0; i &lt; NUM_OF_VIEWS; i++) { UIView *view = [[UIView alloc] init]; view.backgroundColor = [UIColor grayColor]; view.translatesAutoresizingMaskIntoConstraints = NO; [self.floatingViews addObject:view]; [self.contentView addSubview:view]; } } - (void)viewWillLayoutSubviews { [self configureSizeConstraintsForAllViews]; CGFloat superviewWidth = self.view.bounds.size.width; int row = 0; CGFloat leftMargin = 0.0f; for (int i = 0; i &lt; [self.floatingViews count]; i++) { UIView *currentView = self.floatingViews[i]; // is there room for the current view on this row? NSLayoutConstraint *widthConstaint = [self widthConstraintForView:currentView]; CGFloat currentViewWidth = widthConstaint.constant; if ((leftMargin + currentViewWidth) &gt; superviewWidth) { row++; leftMargin = 0.0f; } // position current view [self configureTopConstraintForView:currentView forRow:row]; [self configureLeftConstraintForView:currentView withConstant:leftMargin]; // update leftMargin leftMargin += currentViewWidth + HORIZONTAL_SPACER; } // update size of content view and scroll view's content size CGRect rect = self.contentView.frame; rect.size.width = superviewWidth; rect.size.height = row * (HEIGHT + VERTICAL_SPACER) + HEIGHT; self.contentView.frame = rect; [self.scrollView setContentSize:rect.size]; } - (void)configureSizeConstraintsForAllViews { static BOOL firstTime = YES; if (firstTime) { firstTime = NO; [self configureHeightConstraintsForAllViews]; } for (int i = 0; i &lt; [self.floatingViews count]; i++) { [self configureRandomWidthForView:self.floatingViews[i]]; } } - (void)configureRandomWidthForView:(UIView *)view { CGFloat maxWidth = self.view.bounds.size.width; CGFloat minWidth = 30.0f; CGFloat randomScale = (arc4random() % 101) / 100.0f; // 0.0 - 1.0 CGFloat randomWidth = minWidth + randomScale * (maxWidth - minWidth); assert(randomWidth &gt;= minWidth &amp;&amp; randomWidth &lt;= maxWidth); NSLayoutConstraint *widthConstraint = [self widthConstraintForView:view]; if (!widthConstraint) { widthConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:0.0f]; [view addConstraint:widthConstraint]; } widthConstraint.constant = randomWidth; } - (NSLayoutConstraint *)widthConstraintForView:(UIView *)view { NSLayoutConstraint *widthConstraint = nil; for (NSLayoutConstraint *constraint in view.constraints) { if (constraint.firstAttribute == NSLayoutAttributeWidth) { widthConstraint = constraint; break; } } return widthConstraint; } - (NSLayoutConstraint *)topConstraintForView:(UIView *)view { NSLayoutConstraint *topConstraint = nil; for (NSLayoutConstraint *constraint in view.superview.constraints) { if (constraint.firstItem == view || constraint.secondItem == view) { if (constraint.firstAttribute == NSLayoutAttributeTop) { topConstraint = constraint; break; } } } return topConstraint; } - (NSLayoutConstraint *)leftConstraintForView:(UIView *)view { NSLayoutConstraint *leftConstraint = nil; for (NSLayoutConstraint *constraint in view.superview.constraints) { if (constraint.firstItem == view || constraint.secondItem == view) { if (constraint.firstAttribute == NSLayoutAttributeLeft) { leftConstraint = constraint; break; } } } return leftConstraint; } - (void)configureHeightConstraintsForAllViews { assert(self.floatingViews); for (int i = 0; i &lt; [self.floatingViews count]; i++) { UIView *view = self.floatingViews[i]; [view addConstraint:[NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0f constant:HEIGHT]]; } } - (void)configureTopConstraintForView:(UIView *)view forRow:(NSUInteger)row { NSLayoutConstraint *topConstraint = [self topConstraintForView:view]; if (!topConstraint) { topConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:view.superview attribute:NSLayoutAttributeTop multiplier:1.0f constant:0.0f]; [view.superview addConstraint:topConstraint]; } topConstraint.constant = row * (HEIGHT + VERTICAL_SPACER); } - (void)configureLeftConstraintForView:(UIView *)view withConstant:(CGFloat)constant { NSLayoutConstraint *leftConstraint = [self leftConstraintForView:view]; if (!leftConstraint) { leftConstraint = [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:view.superview attribute:NSLayoutAttributeLeft multiplier:1.0f constant:0.0f]; [view.superview addConstraint:leftConstraint]; } leftConstraint.constant = constant; } - (BOOL)prefersStatusBarHidden { return YES; } @end </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload