简体   繁体   中英

Origin of subviews relative to parent UIView

I'm having a hell of a time positioning two subviews within their parent view. They are intended to comprise a rudimentary animated bar chart, and the animation part seems to be working well. Likewise, the corresponding bars appear to be accurately reflecting the data.

However, I'm trying to base the origin of the the two views on the lower edge of the parent view (the gray area in the screenshot), and the result seems random. I expect it's not really random, but I haven't been able to pin it down.

Here's the code:

-(void) makeBarChart
{
RiserBar *thisRiser;

for(int i=0; i<2; i++)
{
    thisRiser = [[RiserBar alloc] initWithFrame:CGRectZero];
    thisRiser.tag = i+1;
    [self.chartView addSubview:thisRiser];
//    [self placeAndAnimateThisBar];
}

int barWidth = self.chartView.bounds.size.width /((2 * 2) -1);
int focusBarEndHeight = (self.chartView.bounds.size.height-20) * (focusActivityPercent / 100);
int benchmarkBarEndHeight = (self.chartView.bounds.size.height-20) * (benchmarkActivityPercent / 100);

for (thisRiser in self.chartView.subviews)
{
    switch (thisRiser.tag)
    {
        case 1:
        { [UIView animateWithDuration:1
                                  delay:.2
                                options: UIViewAnimationCurveEaseOut
                             animations:^
             {
                 thisRiser.frame = CGRectMake(20, self.chartView.frame.origin.y, barWidth, 0);
                 thisRiser.backgroundColor = [UIColor blackColor];
                 thisRiser.frame = CGRectMake(20, self.chartView.frame.origin.y, barWidth, -focusBarEndHeight);
                 thisRiser.backgroundColor = [UIColor redColor];
             }
                             completion:^(BOOL finished)
             {
                 NSLog(@"Done!");
             }];
        }
            break;
        case 2:
        {
            [UIView animateWithDuration:1
                                  delay:.2
                                options: UIViewAnimationCurveEaseOut
                             animations:^
             {
                 thisRiser.frame = CGRectMake(barWidth + 40, self.chartView.frame.origin.y, barWidth, 0);//load frame from data
                 thisRiser.backgroundColor = [UIColor blackColor];
                 thisRiser.frame = CGRectMake(barWidth + 40, self.chartView.frame.origin.y, barWidth, -benchmarkBarEndHeight);
                 thisRiser.backgroundColor = [UIColor blueColor];
             }
                             completion:^(BOOL finished)
             {
                 NSLog(@"Done!");
             }];
        }
            break;
        case 3:
            //do something to the view
            break;
            //and so on...
        default:
            break;
    }
}

}

and the resulting screenshot:

在此处输入图片说明

I should mention that the intent is for both the red and blue bar to originate at the bottom of the gray parent view and rise. It's not entirely clear to me why I have to reverse the polarity of the .height property to achieve this. And why is the origin somewhere near the middle of the parent view, given this code?

Can someone please point out my mistake(s)?

Thanks!

Edit, pursuant to the gentle guidance of @Rob in Answer 2:

Here is the change to the relevant part of my code, influenced also by the info in this slideshow , which I highly recommend to anyone who, like me, prefers pictures to verbose explanations:

switch (thisRiser.tag)
{
    case 1:
    { [UIView animateWithDuration:1
                              delay:.2
                            options: UIViewAnimationCurveEaseOut
                         animations:^
         {
             thisRiser.frame = CGRectMake(20, self.chartView.frame.size.height, barWidth, 0);
             thisRiser.backgroundColor = [UIColor blackColor];
             thisRiser.frame = CGRectMake(20, self.chartView.frame.size.height, barWidth, -focusBarEndHeight);
             thisRiser.backgroundColor = [UIColor redColor];
         }
                         completion:^(BOOL finished)
         {
             NSLog(@"Done!");
         }];
    }
        break;
    case 2:
    {
        [UIView animateWithDuration:1
                              delay:.2
                            options: UIViewAnimationCurveEaseOut
                         animations:^
         {
             thisRiser.frame = CGRectMake(barWidth + 40, self.chartView.frame.size.height, barWidth, 0);//load frame from data
             thisRiser.backgroundColor = [UIColor blackColor];
             thisRiser.frame = CGRectMake(barWidth + 40, self.chartView.frame.size.height, barWidth, -benchmarkBarEndHeight);
             thisRiser.backgroundColor = [UIColor blueColor];
         }
                         completion:^(BOOL finished)
         {
             NSLog(@"Done!");
         }];
    }
        break;
    case 3:
        //do something to the view
        break;
        //and so on...
    default:
        break;
}

And here's what it looks like now (the differences in bar height pictured is due to different data):

在此处输入图片说明

Thanks again, Rob!

You have several lines similar to the following:

thisRiser.frame = CGRectMake(20, self.chartView.frame.origin.y, barWidth, -focusBarEndHeight);

It doesn't make sense to use the frame.origin.y of the chartView in the context of setting the frame for its subviews. One has nothing to do with the other. The frame of the riser is relative within the chartView , irrespective of the origin of chartView .

If you want thisRiser to be at the bottom of chartView with a height of focusBarEndHeight , I'd probably do something like:

thisRiser.frame = CGRectMake(20, self.chartView.frame.size.height - focusBarEndHeight, barWidth, focusBarEndHeight);

the subviews's actual position is also depend upon the autoresizingmask of parent. you need to consider the same as well while positioning your subviews or you can

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM