对于直接从 Xib 加载的 UIView,何时应用 UIView 大小类?

Posted

技术标签:

【中文标题】对于直接从 Xib 加载的 UIView,何时应用 UIView 大小类?【英文标题】:When are UIView size classes applied, for a UIView loaded directly from a Xib? 【发布时间】:2015-07-08 16:30:08 【问题描述】:

我正在以编程方式使用 xib 初始化 UIView:

- (id)initWithFrame:(CGRect)frame

    self = [[[NSBundle mainBundle] loadNibNamed:@"MyViewNib" owner:self options:nil] objectAtIndex:0];
    if (self)
    
        //perform setup of various components

        return self;
    

此视图使用任意宽度、任意高度和任意宽度、紧凑高度的尺寸类。

我在 xib 中有一个 UIButton,我需要在其背景中放置一个圆圈,如下所示:

self.closeButton.layer.cornerRadius = self.closeButton.frame.size.width / 2.0f;
self.closeButton.layer.backgroundColor = [UIColor colorWithWhite:164.0f / 255.0f alpha:1.0f].CGColor;

如果我在使用任何宽度、紧凑高度的设备上时尝试在 init 函数中设置按钮的圆角半径,标签的框架仍设置为任何宽度、任何高度值。我也尝试过覆盖 layoutSubviews 并在那里设置值,但没有运气。似乎在 layoutSubviews 之后应用了尺寸类约束,而无需再次调用 layoutSubviews,因为其他组件正确显示在屏幕上。

所以,我想知道是否有一个很好的切入点让我了解尺寸类的应用位置,以便我可以正确设置按钮的背景角半径。我可以以编程方式设置按钮,但我想弄清楚如何做到这一点,因为它可能会在转换为大小类的过程中再次出现。

【问题讨论】:

【参考方案1】:

在你的 xib 类中 -(void)awakeFromNib;

【讨论】:

看起来 awakeFromNib 是在调用 Xib 加载函数后立即调用的,所以甚至在“if (self)”初始化体之前。【参考方案2】:

如果我把它放在 init 函数的末尾就可以了:

 [self performSelector:@selector(updateButtonBackground) withObject:nil afterDelay:.001];

显然,到目前为止,已使用尺寸等级设置了约束。虽然这肯定是不理想的,所以如果有人有一个事件驱动或涉及视图“生命周期”的答案(只要适用于 UIView),我会接受......

【讨论】:

【参考方案3】:

这样做怎么样?

-(void)layoutSubviews

    [super layoutSubviews];
self.closeButton.layer.cornerRadius = self.closeButton.frame.size.width / 2.0f;
self.closeButton.layer.backgroundColor = [UIColor colorWithWhite:164.0f / 255.0f alpha:1.0f].CGColor;
//more of your changes
[self layoutIfNeeded]; // You can remove this line if it works without it for you..

【讨论】:

运气不好;它仍然根据任意、任意屏幕尺寸设置角半径...【参考方案4】:

我知道这个帖子很旧,但我在这里没有看到好的答案。

尺寸类在traitCollectionDidChange: 方法中定义。您无法确保 traitCollection 设置在 initWithFrame:awakeFromNib: 中。 因此,根据视图大小类在traitCollectionDidChange: 方法中设置角半径。

【讨论】:

【参考方案5】:

您需要在viewDidLayoutSubviews 中应用圆角半径。至此,您就知道按钮的边界已经建立。

你可以看一个例子on my blog。

【讨论】:

这是针对来自 xib 的以编程方式初始化的视图,将其放入 viewDidLayoutSubviews 似乎不起作用... 您提到您正在为任何宽度、任何高度和任何宽度、紧凑高度进行尺寸分类。这意味着您唯一能看到与 Any/Any 不同的是任何 iPhone 处于横向模式。您是否在 iPhone 上以纵向启动,然后旋转到横向并且 viewDidLayoutSubviews 在这种情况下不起作用? 无旋转,似乎问题在于视图设置为任意大小,即使在 viewDidLayoutSubviews 中/之后也是如此......对我来说闻起来像一个错误! 在 viewDidLayoutSubviews 之后它仍然是 Any to Any ,除非您根据您的尺寸等级将其旋转为横向或横向启动。看看 Compact Width/Any Height 的尺寸类会发生什么情况会很有趣,因此它在 Portrait 中的尺寸应该是正确的。

以上是关于对于直接从 Xib 加载的 UIView,何时应用 UIView 大小类?的主要内容,如果未能解决你的问题,请参考以下文章

xib 指定的位置在 UIView 加载时移动?

从 Textfield.inputview 加载 xib UIView

从 XIB 加载 UIView 大小不正确

如何初始化从 xib 加载的 UIView 子类?继承问题

从 xib 加载子类时如何设置子类 UIView 属性的值

从 .xib 加载自定义视图不适合 iPhone 6+