浮动自动版式的iOS / OSX [英] Floating autolayout iOS/OSX

查看:103
本文介绍了浮动自动版式的iOS / OSX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要浮动的自动布局。我发现它非常难解决的问题,但我认为它可以通过使用一些这里介绍的技巧来实现:的 http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

I have a need for floating autolayout. I find that its quite hard problem to solve but i think it can be done by using some of the tips described here: http://www.objc.io/issue-3/advanced-auto-layout-toolbox.html

也许有人已经尝试解决这样的问题,或想尝试一下。

Maybe someone have already tried solving such problem or would like to try it.

因此​​,这里的挑战:

So here is the challenge:

很好地飘来意见而下降到新的生产线,如果内容宽度超标,像下一张图片厂景宽更大,所以视图2下降到新行。 (同样会发生,如果view2的宽度将变得更大)

nicely floated views which drops to new line if content width exceeded, like in next picture view1 width is bigger so view2 drops to new line. (same would happen if view2 width would become bigger)

进来序列所有视图,视图可以最小宽度和最大宽度定义应该是容器宽度。视图可以在高度伸展但他们总是充分的内容的宽度。

All views come in sequence, views can have defined min width and max width should be the container width. views can stretch in height but then they always take full content width.

推荐答案

我从事这一挑战今晚。我跑在iPhone模拟器的code;它似乎工作。不过,我并没有尝试匹配OP的确切规格,也没有我跟随链接就如何做到这一点的提示。我只是想看看我能在几个小时敲自己出去。

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.

有什么故事板中看到,除了固定在根视图的边空,黄滚动视图。

There's nothing to see in storyboard except an empty, yellow scroll view pinned to the sides of the root view.

灰色浮动的观点是黄色的滚动视图中。滚动视图的内容大小的宽度为根视图的宽度;内容尺寸的高度收缩和扩展,以适应不同数量的行。

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.

我没有使用自动布局的唯一地方是滚动视图的内容视图(这里,我用苹果的所谓混合模式)。

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").

漂浮细胞的宽度是随机生成每当viewWillLayoutSubviews被调用。因此,所有漂浮细胞改变在设备旋转它们的宽度。我持有的所有的浮动单元的高度为恒定。

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.

@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 < 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 < [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) > 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 < [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 >= minWidth && randomWidth <= 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 < [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

这篇关于浮动自动版式的iOS / OSX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆