关于 UIButton 的 titleLabel 和 imageView 的困惑 属性
Confusion about UIButton's titleLabel and imageView property
我有两个问题:
- 为什么
button.titleLabel.center
等于 button.titleLabel.origin
,而
为什么 imageView.frame
为零?
UIButton*button=[UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(100, 200, 200, 100);
button.backgroundColor=[UIColor whiteColor];
[button setTitle:@"\U0000e602" forState:UIControlStateNormal];
button.font=iconfont;
[button setBackgroundImage:[UIImage imageNamed:@"pig.jpg"] forState:UIControlStateNormal];
[button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
[self.view addSubview:button];
NSLog(@"button.titleLabel.frame%@",NSStringFromCGRect(button.titleLabel.frame));
NSLog(@"button.frame%@",NSStringFromCGRect(button.frame));
NSLog(@"button.titleLabel.origin%@\nbutton.titleLabel.center%@",NSStringFromCGPoint(button.titleLabel.frame.origin),NSStringFromCGPoint(button.titleLabel.center));
NSLog(@"button.imageView.frame%@",NSStringFromCGRect(button.imageView.frame));
结果如下:
2015-09-08 13:27:43.507 IconFontTest[3458:152384] button.titleLabel.frame{{100, 50}, {0, 0}}
2015-09-08 13:27:43.508 IconFontTest[3458:152384] button.frame{{100, 200}, {200, 100}}
2015-09-08 13:27:43.508 IconFontTest[3458:152384] button.titleLabel.origin{100, 50}
button.titleLabel.center{100, 50}
2015-09-08 13:27:43.509 IconFontTest[3458:152384] button.imageView.frame{{0, 0}, {0, 0}}
视图不会在您设置时立即呈现。在记录它们的框架属性之前,您需要等待下一次绘图更新。
查看 Apple documentation 的 UIView 视图绘制周期部分。这里提到:
For views that contain custom content using UIKit or Core Graphics,
the system calls the view’s drawRect: method. Your implementation of
this method is responsible for drawing the view’s content into the
current graphics context, which is set up by the system automatically
prior to calling this method. This creates a static visual
representation of your view’s content that can then be displayed on
the screen.
When the actual content of your view changes, it is your
responsibility to notify the system that your view needs to be
redrawn. You do this by calling your view’s setNeedsDisplay or
setNeedsDisplayInRect: method of the view. These methods let the
system know that it should update the view during the next drawing
cycle. Because it waits until the next drawing cycle to update the
view, you can call these methods on multiple views to update them at
the same time.
您应该在日志方法之前调用 setNeedsDisplay
方法:
[button setNeedsDisplay];
//Log methods after the above line
或者,您可以尝试在延迟后调用日志方法,比如 0.2 秒以等待下一个绘图周期完成。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"button.titleLabel.frame%@",NSStringFromCGRect(button.titleLabel.frame));
NSLog(@"button.frame%@",NSStringFromCGRect(button.frame));
NSLog(@"button.titleLabel.origin%@\nbutton.titleLabel.center%@",NSStringFromCGPoint(button.titleLabel.frame.origin),NSStringFromCGPoint(button.titleLabel.center));
NSLog(@"button.imageView.frame%@",NSStringFromCGRect(button.imageView.frame));
});
button.imageView.frame
为零,因为您使用了 setbackgroundImage:
方法而不是 UIButton 的 setImage:
方法。
我有两个问题:
- 为什么
button.titleLabel.center
等于button.titleLabel.origin
,而 为什么
imageView.frame
为零?UIButton*button=[UIButton buttonWithType:UIButtonTypeCustom]; button.frame=CGRectMake(100, 200, 200, 100); button.backgroundColor=[UIColor whiteColor]; [button setTitle:@"\U0000e602" forState:UIControlStateNormal]; button.font=iconfont; [button setBackgroundImage:[UIImage imageNamed:@"pig.jpg"] forState:UIControlStateNormal]; [button setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; [self.view addSubview:button]; NSLog(@"button.titleLabel.frame%@",NSStringFromCGRect(button.titleLabel.frame)); NSLog(@"button.frame%@",NSStringFromCGRect(button.frame)); NSLog(@"button.titleLabel.origin%@\nbutton.titleLabel.center%@",NSStringFromCGPoint(button.titleLabel.frame.origin),NSStringFromCGPoint(button.titleLabel.center)); NSLog(@"button.imageView.frame%@",NSStringFromCGRect(button.imageView.frame));
结果如下:
2015-09-08 13:27:43.507 IconFontTest[3458:152384] button.titleLabel.frame{{100, 50}, {0, 0}}
2015-09-08 13:27:43.508 IconFontTest[3458:152384] button.frame{{100, 200}, {200, 100}}
2015-09-08 13:27:43.508 IconFontTest[3458:152384] button.titleLabel.origin{100, 50}
button.titleLabel.center{100, 50}
2015-09-08 13:27:43.509 IconFontTest[3458:152384] button.imageView.frame{{0, 0}, {0, 0}}
视图不会在您设置时立即呈现。在记录它们的框架属性之前,您需要等待下一次绘图更新。
查看 Apple documentation 的 UIView 视图绘制周期部分。这里提到:
For views that contain custom content using UIKit or Core Graphics, the system calls the view’s drawRect: method. Your implementation of this method is responsible for drawing the view’s content into the current graphics context, which is set up by the system automatically prior to calling this method. This creates a static visual representation of your view’s content that can then be displayed on the screen.
When the actual content of your view changes, it is your responsibility to notify the system that your view needs to be redrawn. You do this by calling your view’s setNeedsDisplay or setNeedsDisplayInRect: method of the view. These methods let the system know that it should update the view during the next drawing cycle. Because it waits until the next drawing cycle to update the view, you can call these methods on multiple views to update them at the same time.
您应该在日志方法之前调用 setNeedsDisplay
方法:
[button setNeedsDisplay];
//Log methods after the above line
或者,您可以尝试在延迟后调用日志方法,比如 0.2 秒以等待下一个绘图周期完成。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"button.titleLabel.frame%@",NSStringFromCGRect(button.titleLabel.frame));
NSLog(@"button.frame%@",NSStringFromCGRect(button.frame));
NSLog(@"button.titleLabel.origin%@\nbutton.titleLabel.center%@",NSStringFromCGPoint(button.titleLabel.frame.origin),NSStringFromCGPoint(button.titleLabel.center));
NSLog(@"button.imageView.frame%@",NSStringFromCGRect(button.imageView.frame));
});
button.imageView.frame
为零,因为您使用了 setbackgroundImage:
方法而不是 UIButton 的 setImage:
方法。