[英]Floating autolayout iOS/OSX
我需要浮动自动布局。 我发现它很难解决,但我认为可以通过使用这里描述的一些技巧来完成: http : //www.objc.io/issue-3/advanced-auto-layout-toolbox.html
也许有人已经尝试解决这样的问题或者想尝试一下。
所以这是挑战:
如果超出内容宽度,则会很好地浮动视图,如下一个图片中的视图1宽度更大,因此view2会下降到新行。 (如果view2宽度变大,也会发生同样的情况)
所有视图按顺序排列,视图可以定义最小宽度,最大宽度应该是容器宽度。 视图可以在高度上拉伸,但是它们总是占用全部内容宽度。
今晚我参与了这个挑战。 我在iPhone模拟器中运行了代码; 它似乎工作。 但是,我并没有尝试匹配OP的确切规格,也没有按照链接提供有关如何执行此操作的提示。 我只是想看看我能在几个小时内自己敲出来的东西。
在故事板中没有什么可看的,除了固定在根视图侧面的空黄色滚动视图。
灰色浮动视图位于黄色滚动视图内。 滚动视图的内容大小的宽度是根视图的宽度; 内容大小的高度缩小和扩展以适应不同数量的行。
我没有使用自动布局的唯一地方是滚动视图的内容视图(这里,我使用了Apple的所谓“混合方法”)。
只要调用viewWillLayoutSubviews,就会随机生成浮动单元格的宽度。 因此,所有浮动单元在设备旋转时改变其宽度。 我将所有浮动细胞的高度保持为常数。
@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
为了简化,从Covoa文本系统的工作方式中获取灵感。 然后从核心文本和自动布局一点点。
每个视图都将进入一个数组。 他们每个人都没有内容压缩和大量内容拥抱。 每一行都是一个水平方向的NSStackView。 所有这些都将进入具有垂直方向的NSStackView。 那进入滚动视图。
如果视图不适合堆栈视图行1,则重新调整每个堆栈视图行。
它会工作。
如果变得非常大,它可能会很慢。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.