Swift中用lazy var初始化UIView时设置frame不显示视图的原因是什么
核心原因解析
问题的根源是你设置了container.translatesAutoresizingMaskIntoConstraints = false,这个属性的作用是关闭系统自动把frame、autoresizingMask转换为Auto Layout约束的机制:
- 当该属性为默认值
true时:你初始化时传入的frame会被系统自动转换为对应的位置、宽高约束,此时不需要手动加约束也能正常显示视图。 - 当你把它设为
false后:系统会完全忽略所有frame、autoresizingMask相关的设置,视图的位置和尺寸完全依赖你手动编写的Auto Layout约束计算。你如果只设置了top、trailing两个位置约束,缺少宽高约束的情况下,Auto Layout无法确定视图的尺寸,最终视图宽高都会被计算为0,自然无法显示。
冗余问题优化方案
你可以根据业务场景二选一解决重复设置的问题:
方案1:保留frame,不用纯Auto Layout布局
删除container.translatesAutoresizingMaskIntoConstraints = false这行代码,同时删掉所有手动编写的约束,直接通过修改frame的origin或者设置center属性调整视图位置即可。此时初始化设置的frame宽高会生效,圆角配置也能正常生效。
该方案适合位置计算简单、不需要做多尺寸自适应的场景。
方案2:纯Auto Layout布局,移除初始化的frame设置
初始化时直接调用UIView()即可,不需要传入frame参数,保留现有约束代码即可。需要注意圆角的配置要移到布局完成的时机执行,避免初始化时拿不到正确的宽高:
lazy var container: UIView = { let view = UIView() view.backgroundColor = UIColor.systemImageGray() view.clipsToBounds = true return view }() override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() container.layer.cornerRadius = container.bounds.width / 2 }
Auto Layout约束的生效时机晚于viewDidLoad,在初始化闭包中获取的bounds是视图初始的默认值,要等布局完成后设置圆角才能得到正确的效果。
内容的提问来源于stack exchange,提问作者Yuuu
相关产品推荐
相关产品推荐

