Friday, September 10, 2010

Programmatically adding views to fit view not working

I was attempting to modify my sliders so that I add the programmatically to fit the available space.  In doing so I was taking an input view and calculating the size that the 4 bars should be to fill up the available space.  I was running into a problem that they weren't displaying correctly.  The bottom bar was always running over.

The weird thing was that all the logging showed that it was working.  I finally figured out that the navigation bar at the top seemed to be messing me up.  I was calculating my view sizes prior to pushing them onto the navigation stack, and that was compressing the data.

The code that calculates and populates my slider where viewToUse is a parameter:
this is done with the loadView command:



    NSLog(@"view height %f, width %f x %f, y %f",viewToUse.frame.size.height,viewToUse.frame.size.width,viewToUse.frame.origin.x,viewToUse.frame.origin.y);
    
    int sliderHeight=(viewToUse.frame.size.height)/4-spacing;
    
    NSLog(@"SliderHeight %d",sliderHeight);
    
    for (int i=0;i<4;i++)
    {
        CGRect labelFrame=CGRectMake(0, (sliderHeight+spacing)*i+sliderHeight/2-labelHeight/2, labelWidth, labelHeight);
        UILabel *label=[[UILabel alloc] initWithFrame:labelFrame];
        label.adjustsFontSizeToFitWidth=true;
        label.text=[sliderLabels objectAtIndex:i];
        [viewToUse addSubview:label];
        CGRect areaFrame=CGRectMake(leftMargin+labelWidth, (sliderHeight+spacing)*i,viewToUse.bounds.size.width-leftMargin-rightMargin-labelWidth, sliderHeight);
        
        sliders[i]=[[UISlider alloc]init];
        [sliders[i] addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged];
        sliders[i].tag=i;        
        sliders[i].accessibilityLabel=[sliderLabels objectAtIndex:i];
        NSLog(@"Y is %d",(sliderHeight+spacing)*i);
        sliders[i].frame=areaFrame;
        [viewToUse addSubview:sliders[i]];
        
     }    

This precise code looks very different depending on how my view is initialized:

With a navigation bar:


 NSLog(@"Select color chosen");
    
[self.textView resignFirstResponder];
    ColorEdit *colorEditor=[[ColorEdit alloc] init];
    
    [self.navController pushViewController:colorEditor animated:true];
    [self.navController setNavigationBarHidden:false ];











And with this, (no navigation bar)


self.textView resignFirstResponder];
    ColorEdit *colorEditor=[[ColorEdit allocinit];
    
    [self.navController pushViewController:colorEditor animated:true];
    [self.navController setNavigationBarHidden:true ];















Finally I moved the initialization to another function instead of when the view loads and call this.

  NSLog(@"Select color chosen");
    
[self.textView resignFirstResponder];
    ColorEdit *colorEditor=[[ColorEdit alloc] init];
    
    [self.navController pushViewController:colorEditor animated:true];
    [self.navController setNavigationBarHidden:false ];
    [colorEditor initColors];













Note that this changes the size of the view, probably because it autoresizes then the navigation bar is added.
With the navigation bar it is 241 pixels high.  Without the navigation bar it is 285 pixels high.


The lesson is that when programmatically filling in a view, pay attention to WHEN you do it. If you are going to have other items hanging around check to see if those are changing the heights of your views.  This might throw off your results.  This particular one cost me several hours of debugging, since I was sure my math was correct.

No comments:

Post a Comment