子视图相对于父 UIView 的起源
Posted
技术标签:
【中文标题】子视图相对于父 UIView 的起源【英文标题】:Origin of subviews relative to parent UIView 【发布时间】:2014-04-14 07:34:30 【问题描述】:我在父视图中定位两个子视图时遇到了麻烦。它们旨在包含一个基本的动画条形图,并且动画部分似乎运行良好。同样,相应的条形似乎准确地反映了数据。
但是,我试图将两个视图的原点基于父视图的下边缘(屏幕截图中的灰色区域),结果似乎是随机的。我希望它不是真正随机的,但我无法确定它。
代码如下:
-(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;
以及生成的屏幕截图:
我应该提到,红色和蓝色条的意图是从灰色父视图的底部开始并上升。我并不完全清楚为什么我必须反转.height
property 的极性来实现这一点。鉴于此代码,为什么原点位于父视图中间附近?
谁能指出我的错误?
谢谢!
根据答案 2 中 @Rob 的温和指导进行编辑:
这是我代码相关部分的更改,也受到this slideshow 中信息的影响,我强烈推荐给像我一样喜欢图片而不是详细解释的任何人:
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;
这就是它现在的样子(图中条形高度的差异是由于不同的数据):
再次感谢罗伯!
【问题讨论】:
【参考方案1】:您有几行类似于以下内容:
thisRiser.frame = CGRectMake(20, self.chartView.frame.origin.y, barWidth, -focusBarEndHeight);
在为其子视图设置框架的上下文中使用frame.origin.y
的frame.origin.y
是没有意义的。一个与另一个无关。立管的frame
在chartView
内是相对的,与chartView
的origin
无关。
如果您希望thisRiser
位于chartView
的底部,高度为focusBarEndHeight
,我可能会这样做:
thisRiser.frame = CGRectMake(20, self.chartView.frame.size.height - focusBarEndHeight, barWidth, focusBarEndHeight);
【讨论】:
谢谢罗伯。您的陈述不太清楚“立管的框架在图表视图中是相对的......”相对于什么?请纠正我,但我认为子视图是贴在窗口上的 PostIt 便笺,其位置由窗口的位置决定。根据您的回答,显然不是,但快速查看文档并没有解决问题。我会学习更多,但如果您有时间,将非常感谢您提供插图。 会尝试你的建议,但我现在远离我的 MBP。 @TimJones 使用您的“PostIt”笔记类比,PostIt 的frame
是它在窗口窗格中的位置。但是窗口的frame
指示窗扇的位置(即窗口是打开还是关闭)。但是您的 PostIt(即立管)的位置是引用窗口(即chartView
)的frame.origin.y
(即窗口的打开程度)。 PostIt 的位置与窗口的打开程度无关。您只希望它位于窗格的底部,因此您只需要知道窗格的高度和 PostIt 的高度。【参考方案2】:
子视图的实际位置也取决于父视图的 autoresizingmask。 您在定位子视图时也需要考虑同样的问题,或者您可以
【讨论】:
谢谢,山姆。我将研究自动调整大小方面。请参阅上面的更新以解决我的直接问题。以上是关于子视图相对于父 UIView 的起源的主要内容,如果未能解决你的问题,请参考以下文章