我知道这个问题可能听起来太简单了,但只有在用这个简单的事情挣扎了好几个小时之后我才会在这里发布。 (是的,我是一般的自定义绘图和iOS开发新手。)
我试图画一枚硬币。它是一个灰色的圆圈,上面有一些文字。到目前为止我尝试过:
CGFloat *radius = 30;
CGPoint center = self.view.center;
CGRect someFrame = CGRectMake(center.x - radius, center.y - radius,
2 * radius, 2 * radius);
UIView *circularView = [[UIView alloc] initWithFrame:someFrame];
circularView.backgroundColor = [UIColor grayColor];
UILabel *label = [[UILabel alloc] initWithFrame:someFrame];
label.text = @"5";
label.textColor = [UIColor blackColor];
label.textAlignment = NSTextAlignmentCenter;
[circularView addSubview:label];
circularView.clipsToBounds = YES;
circularView.layer.cornerRadius = radius;
[self.view addSubview:circularView];
尝试了这个和其他变种。但它都没有奏效。标签未显示,并且视图未在横向模式中按预期绘制在视图的中心。
使用CALayer或Quartz或Core Graphics有没有更好的方法呢?正如我所说,我是新手。
答案 0 :(得分:2)
首先要做的事情:
CGFloat *radius = 30;
那......甚至不应该编译。或者至少应该有一个平均警告。这不是你想要的。你想这样说:
CGFloat radius = 30;
那个星号是坏的,只是,这很糟糕。您知道何时想要使用指向原始值的指针,这只是一个问题。那些时候。
有了这个方法,你就走上了正确的轨道,但看起来你对坐标空间有误解。
使用框架someFrame
初始化圆圈。这是一个在self.view
的坐标空间中有意义的框架,这很好,因为您可以在其中添加它(大多数情况下,请参阅下面的旁注)。
然后你将标签frame
设置为相同的东西。哪个可能没问题,除非您将其添加到circularView
- 而不是self.view
。这意味着作为self.view
的孩子的框架有意义的框架突然根本没有意义。你真正想要的只是以下几点:
// The label will take up the whole bounds of the circle view.
// Labels automatically center their text vertically.
UILabel *label = [[UILabel alloc] initWithFrame:circularView.bounds];
// Center the text in the label horizontally.
label.textAlignment = NSTextAlignmentCenter;
// Make it so that the label's frame is tied to the bounds of
// the circular view, so that if its size changes in the future
// the label will still look right.
label.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
你现在遇到的问题是标签远离其他地方,因为circularView
没有&#39,因此会突然离开someFrame
的边缘(从而被剪掉) ; t在circularView
的坐标空间中有意义。
旁注:
如果self.view.frame.origin
不是CGPointZero
,那么这项工作就不会有效。它通常是,但你真正想要的是视图 bounds
的中心,而不是视图frame
的中心。 self.view.center
会在self.view.superview
的坐标空间中为您指定一个点。只要self.view.frame.origin
为{0, 0}
,这似乎就会起作用,但为了在技术上更正确,您应该说:
CGPoint center = CGPointMake(CGRectGetMidX(self.view.bounds),
CGRectGetMidY(self.view.bounds));
即使视图的边界发生变化(例如,如果您旋转设备),您也可以在视图的中心保留circularView
,并使用以下内容:
circularView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin |
UIViewAutoresizingFlexibleRightMargin |
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin;
是的,手动输入autoresizingMask
是最糟糕的事情,但从长远来看它是值得的(实际上,从长远来看,你可能会发疯并制造像我这样的较短的辅助方法......)。
答案 1 :(得分:0)
您需要更改标签框架的原点。将标签添加到背景视图时,其框架的原点相对于其超视图
因此,对于背景视图,CGRectMake(center.x - radius, center.y - radius, 2 * radius, 2 * radius)
,标签为CGRectMake(0, 0, 2 * radius, 2 * radius)
除此之外,您可以跳过背景视图并着色UILabel的背景颜色。
答案 2 :(得分:0)
您的第一个问题是您正在为视图容器(circularView)创建一个框架,其中包含一些非零x和y。然后你创建一个标签并给它相同的框架(非零x和y)。然后将标签添加到容器视图中。标签的x和y将相对于容器视图的x和y(偏移,不居中)。如果您希望标签和容器在屏幕上共享相同的位置,请将其更改为:
UILabel *label = [[UILabel alloc] initWithFrame: circularView.bounds];
另一个问题是你做这个有多简单,你可以用标签来做所有事情(忽略容器视图)。
UILabel *label = [[UILabel alloc] initWithFrame:someFrame];
label.text = @"5";
label.textColor = [UIColor blackColor];
label.textAlignment = NSTextAlignmentCenter;
label.clipsToBounds = YES;
label.layer.cornerRadius = radius;
label.backgroundColor = [UIColor grayColor];
]self.view addSubview:label];