关于 UIButton 的 titleLabel 和 imageView 的困惑 属性

Confusion about UIButton's titleLabel and imageView property

我有两个问题:

结果如下:

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: 方法。