2

I am pretty new to programming.

The screen has two vertical columns and 3 boxes. A box will go to the left column if right column has less boxes then the left. And each box has several subviews. In my code, the "yearBOX" and "dayBOX" will go to the left column. The problem is that "dayBOX" just overlaps the yearBOX instead of stacking below. I've been checking the document and playing around for about 10 hours but couldn't find any solution. Swift or Objective-C code are welcome. I tried to set the TopAnchord but it didn't work. Thanks alot.

And here's the full code:

EDITED: Removed some unused lines. And added some critical code to fix the problem.

[boxStack.topAnchor constraintEqualToAnchor:dayBox.topAnchor].active=YES; [dayBox.bottomAnchor constraintEqualToAnchor:boxStack.bottomAnchor].active = YES; [boxStack.topAnchor constraintEqualToAnchor:dayBox.topAnchor].active=YES; [dayBox.bottomAnchor constraintEqualToAnchor:boxStack.bottomAnchor].active = YES;

- (void)viewDidLoad {
CGRect watchersRect = CGRectMake(0, 20, 320, 460);
UIView *colorLayer = [[UIView alloc]initWithFrame:watchersRect];
colorLayer.backgroundColor = [UIColor grayColor];

[self.view addSubview:colorLayer];


UIStackView *watchersUI = [[UIStackView alloc]init];
    NSMutableArray *leftArr=[[NSMutableArray alloc]init];
NSMutableArray *rightArr=[[NSMutableArray alloc]init];

NSMutableArray *yearStackUIArr = [[NSMutableArray alloc]initWithObjects:@"year 1", @"year2",@"year3",@"year4",@"year5",nil];
NSMutableArray *monthStackUIArr = [[NSMutableArray alloc]initWithObjects:@"month 1", @"month 2",@"month 3",nil];
NSMutableArray *dayStackUIArr = [[NSMutableArray alloc]initWithObjects:@"day1", @"day2",@"day3",nil];



watchersUI = [[UIStackView alloc] initWithFrame:watchersRect];
watchersUI.axis= UILayoutConstraintAxisHorizontal;
watchersUI.distribution = UIStackViewDistributionFillEqually;
watchersUI.alignment = UIStackViewAlignmentFill;
watchersUI.spacing = 2;
watchersUI.translatesAutoresizingMaskIntoConstraints = YES;

[colorLayer addSubview:watchersUI];


UIView *leftColumn = [[UIView alloc] init];
[leftColumn setBackgroundColor:[UIColor yellowColor]];

UIView *rightColumn = [[UIView alloc]init];
[rightColumn setBackgroundColor:[UIColor redColor]];


[watchersUI addArrangedSubview:leftColumn];
[watchersUI addArrangedSubview:rightColumn];

[leftColumn.leftAnchor constraintEqualToAnchor:watchersUI.leftAnchor].active = YES;
[rightColumn.rightAnchor constraintEqualToAnchor:watchersUI.rightAnchor].active = YES;
[leftColumn.bottomAnchor constraintEqualToAnchor:watchersUI.bottomAnchor].active = YES;
[rightColumn.bottomAnchor constraintEqualToAnchor:watchersUI.bottomAnchor].active = YES;


UIStackView *leftStack =[[UIStackView alloc]init];
leftStack.axis = UILayoutConstraintAxisVertical;
leftStack.distribution = UIStackViewDistributionFillProportionally;
leftStack.alignment=UIStackViewAlignmentLeading;
leftStack.spacing =2;
leftStack.translatesAutoresizingMaskIntoConstraints = NO;
[leftColumn addSubview:leftStack];
[leftStack.leftAnchor constraintEqualToAnchor:leftColumn.leftAnchor].active =YES;
[leftStack.rightAnchor constraintEqualToAnchor:leftColumn.rightAnchor].active =YES;


UIStackView *rightStack =[[UIStackView alloc]init];
rightStack.axis = UILayoutConstraintAxisVertical;
rightStack.distribution = UIStackViewDistributionFillProportionally;
rightStack.alignment=UIStackViewAlignmentLeading;
rightStack.spacing =2;
rightStack.translatesAutoresizingMaskIntoConstraints = NO;
[rightColumn addSubview:rightStack];
[rightStack.leftAnchor constraintEqualToAnchor:rightColumn.leftAnchor].active =YES;
[rightStack.rightAnchor constraintEqualToAnchor:rightColumn.rightAnchor].active =YES;


UIView *monthBox=[[UIView alloc]init];
monthBox.backgroundColor =[UIColor blackColor];

UIView *yearBox=[[UIView alloc]init];
yearBox.backgroundColor = [UIColor purpleColor];

UIView *dayBox=[[UIView alloc]init];
dayBox.backgroundColor =[UIColor brownColor];


if ([yearStackUIArr count]>0) {

    if ([rightArr count]<[leftArr count]) {

        [rightStack addArrangedSubview:yearBox];
        [rightArr addObject:yearBox];

        [yearBox.topAnchor constraintEqualToAnchor:rightColumn.topAnchor].active = YES;
        [yearBox.leftAnchor constraintEqualToAnchor:rightColumn.leftAnchor].active = YES;
        [yearBox.rightAnchor constraintEqualToAnchor:rightColumn.rightAnchor].active = YES;



    }
    else
    {
        [leftStack addArrangedSubview:yearBox];
        [leftArr addObject:yearBox];

        for (UIView *subs in leftStack.subviews) {
            NSLog(@"yearBox leftStack %@",subs);
        }


        [yearBox.topAnchor constraintEqualToAnchor:leftColumn.topAnchor].active = YES;
        [yearBox.leftAnchor constraintEqualToAnchor:leftColumn.leftAnchor].active = YES;
        [yearBox.rightAnchor constraintEqualToAnchor:leftColumn.rightAnchor].active = YES;


    }


    UIStackView *boxStack = [[UIStackView alloc]init];
    boxStack.axis = UILayoutConstraintAxisVertical;
    boxStack.distribution = UIStackViewDistributionFillEqually;
    boxStack.alignment=UIStackViewAlignmentLeading;
    boxStack.spacing=1;
    boxStack.translatesAutoresizingMaskIntoConstraints = NO;


    for (NSString *innerItem in yearStackUIArr) {
        UILabel *innerView = [[UILabel alloc]init];
        [boxStack addArrangedSubview:innerView];

        [innerView.leftAnchor constraintEqualToAnchor:boxStack.leftAnchor].active =YES;
        [innerView.rightAnchor constraintEqualToAnchor:boxStack.rightAnchor].active =YES;
        [innerView.heightAnchor constraintGreaterThanOrEqualToConstant:20].active =YES;
        innerView.backgroundColor =[UIColor cyanColor];
        innerView.text = innerItem;
        innerView.font = [UIFont systemFontOfSize:10];


    }

    [yearBox addSubview:boxStack];
    [boxStack.leftAnchor constraintEqualToAnchor:yearBox.leftAnchor].active = YES;
    [boxStack.rightAnchor constraintEqualToAnchor:yearBox.rightAnchor].active = YES;
    [boxStack.topAnchor constraintEqualToAnchor:yearBox.topAnchor].active = YES;
    [yearBox.bottomAnchor constraintEqualToAnchor:boxStack.bottomAnchor].active = YES;


}



if ([monthStackUIArr count]>0) {

    if ([rightArr count]<[leftArr count]) {
        [rightStack addArrangedSubview:monthBox];
        [rightArr addObject:monthBox];


        [monthBox.leftAnchor constraintEqualToAnchor:rightColumn.leftAnchor].active = YES;
        [monthBox.rightAnchor constraintEqualToAnchor:rightColumn.rightAnchor].active = YES;

    }
    else
    {
        [leftStack addArrangedSubview:monthBox];
        [leftArr addObject:monthBox];


        [monthBox.leftAnchor constraintEqualToAnchor:leftColumn.leftAnchor].active = YES;
        [monthBox.rightAnchor constraintEqualToAnchor:leftColumn.rightAnchor].active = YES;
    }


    UIStackView *boxStack = [[UIStackView alloc]init];
    boxStack.axis = UILayoutConstraintAxisVertical;
    boxStack.distribution = UIStackViewDistributionFillEqually;
    boxStack.alignment=UIStackViewAlignmentLeading;
    boxStack.spacing=2;
    boxStack.translatesAutoresizingMaskIntoConstraints = NO;


    for (NSString *innerItem in monthStackUIArr) {
        UILabel *innerView = [[UILabel alloc]init];
        [boxStack addArrangedSubview:innerView];

        [innerView.leftAnchor constraintEqualToAnchor:boxStack.leftAnchor].active =YES;
        [innerView.rightAnchor constraintEqualToAnchor:boxStack.rightAnchor].active =YES;
        [innerView.heightAnchor constraintGreaterThanOrEqualToConstant:20].active =YES;
        innerView.backgroundColor =[UIColor whiteColor];
        innerView.text = innerItem;
        innerView.font = [UIFont systemFontOfSize:10];

    }

    [monthBox addSubview:boxStack];
    [boxStack.leftAnchor constraintEqualToAnchor:monthBox.leftAnchor].active = YES;
    [boxStack.rightAnchor constraintEqualToAnchor:monthBox.rightAnchor].active = YES;
    [boxStack.topAnchor constraintEqualToAnchor:monthBox.topAnchor].active=YES;
    [monthBox.bottomAnchor constraintEqualToAnchor:boxStack.bottomAnchor].active = YES;


}

if ([dayStackUIArr count]>0) {

    if ([rightArr count]<[leftArr count]) {

        [rightStack addArrangedSubview:dayBox];
        [rightArr addObject:dayBox];


        [dayBox.leftAnchor constraintEqualToAnchor:rightColumn.leftAnchor].active = YES;
        [dayBox.rightAnchor constraintEqualToAnchor:rightColumn.rightAnchor].active = YES;




    }
    else
    {
        [leftStack addArrangedSubview:dayBox];

        [leftArr addObject:dayBox];

        [dayBox.leftAnchor constraintEqualToAnchor:leftColumn.leftAnchor].active = YES;
        [dayBox.rightAnchor constraintEqualToAnchor:leftColumn.rightAnchor].active = YES;


    }

    UIStackView *boxStack = [[UIStackView alloc]init];
    boxStack.axis = UILayoutConstraintAxisVertical;
    boxStack.distribution = UIStackViewDistributionFillEqually;
    boxStack.alignment=UIStackViewAlignmentLeading;
    boxStack.spacing=2;
    boxStack.translatesAutoresizingMaskIntoConstraints = NO;


    [dayBox addSubview:boxStack];


    for (NSString *innerItem in dayStackUIArr) {
        UILabel *innerView = [[UILabel alloc]init];
        [boxStack addArrangedSubview:innerView];

        [innerView.leftAnchor  constraintEqualToAnchor:boxStack.leftAnchor].active =YES;
        [innerView.rightAnchor constraintEqualToAnchor:boxStack.rightAnchor].active =YES;
        [innerView.heightAnchor constraintGreaterThanOrEqualToConstant:20].active =YES;
        innerView.backgroundColor =[UIColor blueColor];
        innerView.text = innerItem;
        innerView.font = [UIFont systemFontOfSize:10];

    }

    [boxStack.leftAnchor constraintEqualToAnchor:dayBox.leftAnchor].active = YES;
    [boxStack.rightAnchor constraintEqualToAnchor:dayBox.rightAnchor].active = YES;
    [boxStack.topAnchor constraintEqualToAnchor:dayBox.topAnchor].active=YES;
    [dayBox.bottomAnchor constraintEqualToAnchor:boxStack.bottomAnchor].active = YES;



    }


   }

}
William Tong
  • 479
  • 7
  • 14
  • Good question, trying to debug. – Akshansh Thakur May 28 '16 at 11:36
  • Hey, so part of your problem is the auto layout constraint errors that you are getting. I have solved just that. But the not the core issue yet. So, in your `if ([dayStackUIArr count]>0)`, then in your `else if`. Change `[dayBox.heightAnchor constraintGreaterThanOrEqualToAnchor:margin.heightAnchor].active =YES;` to `[dayBox.heightAnchor constraintGreaterThanOrEqualToAnchor:margin.heightAnchor].active =YES;` This will get rid of autoLayout errors – Akshansh Thakur May 28 '16 at 13:22
  • Hi Akshansh. Thank you for pointing this out. And I think that I need to set the 'innerView.topAnchor' to make it right. I don't why but I just found that those innerViews don't stick or attach to their parent StackView. I guess that's the reason. I will update the code again when I get a work around. Thank you again. – William Tong May 28 '16 at 14:23
  • William, I tried to manipulate the code, but seems like nothing is helping. I will keep trying. However, if you find a solution to it, please post the solution. I am very interested and will be looking out for it. Good luck! – Akshansh Thakur May 28 '16 at 18:12
  • Hi Akshansh. The magical thing happened after I added a bottomAnchor to the yearBox which equals the boxstack subview. And a topAnchor for the uistackview boxstack subview of the dayBox. It seems that the anchors are critical for the autolayout. Thanks a lot. – William Tong May 29 '16 at 16:29
  • wow! that is good to hear. I'm happy for you – Akshansh Thakur May 29 '16 at 16:33
  • Yeah, thank you. That's exciting. And I also updated the code for reference. – William Tong May 29 '16 at 16:43
  • i am adding views (contain image view, webView and some other views), I applied your trick but still they are overlapping each other. @WilliamTong – Mansuu.... Sep 07 '17 at 07:23

0 Answers0