bounds 属性是一个 CGRect。CGRect 不是 Objective-C 对象,所以你不能直接使用%@
. 您需要先将其转换为字符串NSStringFromCGRect
:
NSLog(@"bounds: %@", NSStringFromCGRect(label.bounds));
处理布局UILabel
及其周围元素的最佳方法是创建一个自定义UIView
子类以包含标签和其他元素,并覆盖其layoutSubviews
方法来进行布局。
例如,假设我们想要标签和图像视图,并且我们希望图像视图与标签的底部边缘齐平。我们可以创建一个UIView
名为的子类ContainerView
:
@interface ContainerView : UIView
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, strong) UIImageView *imageView;
@end
我们可以将其用作标签的超级视图和图像视图。我们将依靠 ContainerView 来布置标签和图像,因此我们不需要指定它们的框架。我们还将依赖 ContainerView 将标签和图像视图添加为子视图。
ContainerView *superView = [[ContainerView alloc] initWithFrame:someRect];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectZero];
label.text = someString;
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0;
superView.label = label;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"someImage"]];
superView.imageView = imageView;
[self.view addSubview:superView];
下面是我们如何实现 ContainerView(假设我们使用 ARC):
@implementation ContainerView
@synthesize label = _label;
@synthesize imageView = _imageView;
我们将覆盖 ContainerView 的“标签”设置器以将标签添加为子视图:
- (void)setLabel:(UILabel *)label {
if (_label) {
[_label removeFromSuperview];
}
_label = label;
if (_label) {
[self addSubview:label];
}
}
我们对 'imageView' setter 做同样的事情:
- (void)setImageView:(UIImageView *)imageView {
if (_imageView) {
[_imageView removeFromSuperview];
}
_imageView = imageView;
if (_imageView) {
[self addSubview:imageView];
}
}
有趣的部分是layoutSubviews
方法。系统layoutSubviews
在不同的时间将消息发送到视图,包括在它获得新的子视图之后以及它的大小发生变化时。
- (void)layoutSubviews {
[super layoutSubviews];
// Put the label's upper left corner at (20, 20) and make it as wide as I am,
// minus a 20 point margin on each side.
self.label.frame = CGRectMake(20, 20, self.bounds.size.width - 40, 10000);
// Tell the label to make itself exactly large enough to fit its text. This will
// shrink its height.
[self.label sizeToFit];
// Now put the image view flush against the bottom edge of the label.
CGSize imageSize = self.imageView.image.size;
self.imageView.frame = CGRectMake(20, CGRectGetMaxY(self.label.frame),
imageSize.width, imageSize.height);
}