从 Xib 加载视图在自动布局后调整框架子视图的大小
Posted
技术标签:
【中文标题】从 Xib 加载视图在自动布局后调整框架子视图的大小【英文标题】:Load view from Xib get resize frame subviews after auto layout 【发布时间】:2018-05-12 10:42:49 【问题描述】:我已经研究了 2 天,但我没有找到任何解决此问题的方法:
我正在从 Xib 加载视图,并对其应用自动布局。视图显示正确,自动布局工作正常。但是当我尝试在自动布局之后获取子视图的框架时,它不起作用。我需要子视图的框架来制作redView
圆形。
我在初始化时从 Xib 加载视图并将其添加为具有自动布局的子视图(我已经尝试了许多不同的事情并检查我正在做的打印在 layoutSubviews
中。
class ReusableView: UIView
@IBOutlet weak var redView: UIView!
var mainView: UIView?
// MARK: - Initializers.
override init(frame: CGRect)
super.init(frame: frame)
loadXIB()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
loadXIB()
override func layoutSubviews()
super.layoutSubviews()
print ("Self subviews \(self.subviews)")
print ("MainView frame \(mainView?.frame)")
print ("Red View frame \(redView?.frame)")
func loadXIB()
guard let view = loadView(String(describing: type(of: self))) else return
print ("View loaded from nib \(view.frame)")
view.translatesAutoresizingMaskIntoConstraints = false
view.subviews.forEach
$0.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(view)
NSLayoutConstraint.activate([
view.topAnchor.constraint(equalTo: self.topAnchor),
view.leadingAnchor.constraint(equalTo: self.leadingAnchor),
view.trailingAnchor.constraint(equalTo: self.trailingAnchor),
view.bottomAnchor.constraint(equalTo: self.bottomAnchor),
])
mainView = view
func loadView(_ nibName: String) -> UIView?
if nibName.isEmpty
return nil
let bundle = Bundle(for: type(of: self) as AnyClass)
let nib = UINib(nibName: nibName, bundle: bundle)
if let view = nib.instantiate(withOwner: self, options: nil).first as? UIView
return view
return nil
打印结果:
View loaded from nib (0.0, 0.0, 375.0, 667.0)
Self subviews [<UIView: 0x7ff232216880; frame = (0 0; 150 150); autoresize = W+H; layer = <CALayer: 0x60800022f4e0>>]
MainView frame Optional((0.0, 0.0, 150.0, 150.0))
Red View frame Optional((0.0, 20.0, 375.0, 647.0))
MainView subviews Optional([<UIView: 0x7ff232216690; frame = (0 20; 375 647); autoresize = W+H; layer = <CALayer: 0x60800022f520>>])
正如我们所见,主视图已调整大小,但子视图未调整。 (然后当打印视图时它工作得很好,我一直在用更复杂的视图来做,但我以前从未遇到过将框架放入 de UIView 的问题。)
【问题讨论】:
【参考方案1】:我发现了这种解决方法,但我仍然想知道是否有更优雅的方法。
加载视图后,我将 xib 的原始大小存储在一个名为 XibSize
的变量中 guard let view = loadView(String(describing: type(of: self))) else return
xibSize = view.frame.size
然后我创建了一个方法,它将您希望在应用后布局后重新计算的大小作为参数: (由于我们有原始尺寸(XibSize),以及重新计算的mainView的尺寸),我们可以在应用子视图的自动布局后计算尺寸。)
func getSizeAfterAutoLayout(sizeToRecalculate: CGSize) -> CGSize?
guard let mainView = mainView, let xibFrame = xibFrame else return nil
let width = sizeToRecalculate.width * mainView.frame.size.width / xibSize.width
let height = sizeToRecalculate.height * mainView.frame.size.height / xibSize.height
return CGSize(width: width, height: height)
【讨论】:
以上是关于从 Xib 加载视图在自动布局后调整框架子视图的大小的主要内容,如果未能解决你的问题,请参考以下文章