在 initWithCoder 上查看 1000x1000:

View 1000x1000 on initWithCoder:

SO 上有几个问题问这个问题,但 none 已经正确地问了。

我使用的自定义进度条是基于 UIView 的 class 实现的。

@implementation MCProgressBarView {
    UIImageView * _backgroundImageView;
    UIImageView * _foregroundImageView;
    CGFloat minimumForegroundWidth;
    CGFloat availableWidth;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
  self = [super initWithCoder:aDecoder];
  // [self bounds] is 1000x1000 here... what? 
  if (self) [self initialize];
  return self;
}


- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) [self initialize];
    return self;
}

- (void) initialize {
  UIImage * backgroundImage = [[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"progress-bg" ofType:@"png"]]
                               resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f)];

  UIImage * foregroundImage = [[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"progress-bg" ofType:@"png"]]
                               resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 10.0f, 0.0f, 10.0f)];

  _backgroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
  _backgroundImageView.image = backgroundImage;
  [self addSubview:_backgroundImageView];

  _foregroundImageView = [[UIImageView alloc] initWithFrame:self.bounds];
  _foregroundImageView.image = foregroundImage;
  [self addSubview:_foregroundImageView];

  UIEdgeInsets insets = foregroundImage.capInsets;
  minimumForegroundWidth = insets.left + insets.right;

  availableWidth = self.bounds.size.width - minimumForegroundWidth;

  [self adjustProgress:0.0f];
}

我在界面生成器上创建了一个 UIView 为 200x20 点并将该视图指定为我正在使用的自定义 class MCProgressBarView。当应用 运行s、initWithCoder 运行s 并创建大小为 1000x1000 点的进度视图时,忽略视图在 IB 上的大小。

如何强制 initWithCoder 运行 使用在 IB 上分配的正确大小?

注意:我不想将它硬连接到 200x20,我也不想在 运行 时通过代码设置它。有没有办法让这个工作?

TL;DR: 将您的 frame/bounds 逻辑移动到 viewDidLayoutSubviews.

initWithCoder: 对于执行帧逻辑是不安全的。您应该为此使用 viewDidLayoutSubviews。 Apple 使用以 iOS 10 开头的 1000x1000 边界。不清楚是错误还是故意的,但它似乎产生了积极的结果——人们来这里询问。 ;-)

事实上,initWithCoder:对于这样的逻辑从来都不安全。过去,您的视图的边界将是 iPhone 5 屏幕的边界,因为那是您在 IB 中使用的视图,但随后视图将增长到 iPhone 6 Plus 大小或 iPad 大小,这会导致视觉问题。

现在,Apple 只是将边界设置为 1000x1000,这在所有情况下都是不正确的。在视图上执行布局过程后,边界会得到更正。