1

I have wired up a UIStackView in my storyboard and I am dynamically adding buttons to it, this works fine if I add one or two buttons but when I want to insert the third button the app crashes with the following error

017-12-27 10:41:14.315786+0800 NWMPos[39434:24150577] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'index out of bounds for arranged subview: index = 2 expected to be less than or equal to 1'
*** First throw call stack:
(0x187151d04 0x1863a0528 0x187151c4c 0x190ce44c4 0x104ec1fdc 0x106ae549c 0x106ae545c 0x106aea050 0x1870f9eb0 0x1870f7a8c 0x187017fb8 0x188eaff84 0x1905ec2e8 0x104ec4620 0x186b3a56c)
libc++abi.dylib: terminating with uncaught exception of type NSException

I have not specified anywhere (that I know of) a limit of 2 entries in the stackview so I am a bit lost here as to why I can add two buttons but not a third

Below is the code that adds the buttons

dispatch_async(dispatch_get_main_queue(), ^{
        _fcVariantImageView.image = nil;

        if ([finalUrl hasPrefix:@"https"]) {
            NSURL *url = [[NSURL alloc] initWithString:[finalUrl stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
            NSData *data =[NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            _fcVariantImageView.contentMode = UIViewContentModeScaleAspectFit;
            _fcVariantImageView.image = image;
        } else {
            _fcVariantImageView.image = [UIImage imageNamed:fcVariantRow[@"fcVariantImageUrl"]];
        }

        if ([finalSwatchUrl hasPrefix:@"https"]) {
            NSURL *url = [[NSURL alloc] initWithString:[finalSwatchUrl stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
            NSData *data =[NSData dataWithContentsOfURL:url];
            UIImage *image = [UIImage imageWithData:data];
            UIButton *imageButton1 = [UIButton buttonWithType:UIButtonTypeCustom];
            imageButton1.tag = 1;
            imageButton1.frame = CGRectMake(0, 0, 4, 4);
            [imageButton1 setImage:image forState:UIControlStateNormal];
            [imageButton1 addTarget:self action:@selector(buttonPushed:) forControlEvents:UIControlEventTouchUpInside];
            [_fcVariantColourStackView insertArrangedSubview:imageButton1 atIndex:0];
        }

        // If 2 variants we need add a second swatch
        if(numberOfVariants == 2) {
            NSDictionary *fcVariantRow2 = [_fullConceptVariants objectAtIndex:1];
            //NSString *finalUrl2 = [NSString stringWithFormat:@"https:%@", fcVariantRow2[@"fcVariantImageUrl"]];
            NSString *finalSwatchUrl2 = [NSString stringWithFormat:@"https:%@", fcVariantRow2[@"fcVariantSwatch"]];

            if ([finalSwatchUrl2 hasPrefix:@"https"]) {
                NSURL *url2 = [[NSURL alloc] initWithString:[finalSwatchUrl2 stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
                NSData *data2 =[NSData dataWithContentsOfURL:url2];
                UIImage *image2 = [UIImage imageWithData:data2];
                UIButton *imageButton2 = [UIButton buttonWithType:UIButtonTypeCustom];
                imageButton2.tag = 2;
                imageButton2.frame = CGRectMake(0, 0, 4, 4);
                [imageButton2 setImage:image2 forState:UIControlStateNormal];
                [imageButton2 addTarget:self action:@selector(buttonPushed:) forControlEvents:UIControlEventTouchUpInside];
                [_fcVariantColourStackView insertArrangedSubview:imageButton2 atIndex:1];
            }
        }

        // If 3 variants we need add a third swatch
        if(numberOfVariants == 3) {
            NSDictionary *fcVariantRow3 = [_fullConceptVariants objectAtIndex:2];
            NSString *finalSwatchUrl3 = [NSString stringWithFormat:@"https:%@", fcVariantRow3[@"fcVariantSwatch"]];

            if ([finalSwatchUrl3 hasPrefix:@"https"]) {
                NSURL *url3 = [[NSURL alloc] initWithString:[finalSwatchUrl3 stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
                NSData *data3 =[NSData dataWithContentsOfURL:url3];
                UIImage *image3 = [UIImage imageWithData:data3];
                UIButton *imageButton3 = [UIButton buttonWithType:UIButtonTypeCustom];
                imageButton3.tag = 3;
                imageButton3.frame = CGRectMake(0, 0, 4, 4);
                [imageButton3 setImage:image3 forState:UIControlStateNormal];
                [imageButton3 addTarget:self action:@selector(buttonPushed:) forControlEvents:UIControlEventTouchUpInside];
                [_fcVariantColourStackView insertArrangedSubview:imageButton3 atIndex:2];
            }
        }

        _fcVariantDescriptionLbl.text = fcVariantRow[@"fcVariantName"];
        _fcVariantViewItemId.text = fcVariantRow[@"fcVariantItemId"];
        _fcVariantViewPriceLbl.text = [NSString stringWithFormat:@"%@ %@", [NWTillHelper getCurrencySymbol], fcVariantRow[@"fcVariantPrice"]];
        _fcSelectedColorLbl.text = fcVariantRow[@"fcVariantColourDescription"];

        [_fcVariantSpinner stopAnimating];
    });
Matt Douhan
  • 2,053
  • 1
  • 21
  • 40
  • I don't even know what 'numberOfVariants' is. – El Tomato Dec 27 '17 at 03:06
  • thats just a counter who tells me how many buttons should be added and debugs tells me its correct, I think the issue is that if its 3 I am not adding the second button, I am trying to add at index 0 and then directly index 2 and its expecting 1 – Matt Douhan Dec 27 '17 at 03:08
  • **the issue is that if its 3 I am not adding the second button, I am trying to add at index 0 and then directly index 2 and its expecting 1** this is the problem. So what do you want in your question? – trungduc Dec 27 '17 at 04:14

0 Answers0