【问题标题】:View 1000x1000 on initWithCoder:在 initWithCoder 上查看 1000x1000:
【发布时间】:2017-03-04 21:30:59
【问题描述】:

在 SO 上有几个问题问这个问题,但没有一个问题问得正确。

我正在使用一个自定义进度条,它是一个基于 UIView 的类和这个实现。

@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 点,并将该视图分配给我正在使用的这个自定义类 MCProgressBarView。当应用程序运行时,initWithCoder 运行并创建一个大小为 1000x1000 点的进度视图,而不管视图在 IB 上的大小。

如何强制 initWithCoder 以分配给 IB 的正确大小运行?

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

【问题讨论】:

    标签: ios iphone ipad uiview initwithcoder


    【解决方案1】:

    TL;DR:将你的框架/边界逻辑移动到viewDidLayoutSubviews

    initWithCoder: 执行帧逻辑不安全。您应该为此使用viewDidLayoutSubviews。 Apple 从 iOS 10 开始使用 1000x1000 边界。目前尚不清楚是 bug 还是故意的,但它似乎有一个净积极的结果——人们来这里询问它。 ;-)

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

    现在,Apple 只是将边界设置为 1000x1000,这对于所有情况都是不正确的。一旦在视图上执行布局传递,边界就会更正。

    【讨论】:

    • 基于 UIView 的类上没有 viewDidLayoutSubviews。如果我使用 viewController 来正确设置视图大小,那么 Apple 认为整个事情都是很糟糕的,因为很多事情都在 ios 上。
    • @SpaceDog 使用 layoutSubviews.
    • 好的。我在课堂上实现了layoutSubviews。当该方法运行时,视图的大小正确,我无需做任何事情,但是当它显示在应用程序上时,它是 1000x1000。
    • 请张贴截图。听起来有些奇怪。
    猜你喜欢
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 2011-07-02
    • 1970-01-01
    • 2010-10-23
    • 2014-06-18
    • 2011-12-14
    相关资源
    最近更新 更多