如何在UIView完全加载时收到通知

时间:2017-08-01 05:15:23

标签: swift uiview layoutsubviews

我有一个UIView被添加到UIViewController,我想确保视图已经完全加载,因为我想访问和使用这些视图的框架。我在UIView中工作,ViewController仅用于测试目的。

以下是我正在使用的示例:

我正在将自定义UIView加载到UIViewController中,因此我以下列方式初始化视图:

在UIViewController中

var slideView: BSlideBar = BSlideBar(frame: CGRect(x: 0, y: 150, width: 320, height: 54))

self.view.addSubview(slideView)

在UIView

override init(frame: CGRect) {
    super.init(frame: frame)    
    customInit()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    customInit()
}

public func customInit() {

    Bundle.main.loadNibNamed("BSlideBar", owner: self, options: nil)
    self.addSubview(self.slideView)
    self.slideView.frame = self.bounds
}

我有一个与我的UIView关联的XIB文件,所以我在自定义初始化函数中加载Nib。

这个UIView里面有其他的UIViews,并且都被添加到UIViewController中。这一切都运行正常,当我尝试访问这些视图的属性时出现问题:

示例:

draggableView.layer.cornerRadius = draggableView.frame.width/2

这将使draggableView成为一个圆圈,并允许我将draggableView的大小基于它所包含的视图,同时将其保持为圆形。这意味着无论我初始化它,我的视图都将保持一致。令人讨厌的是,帧始终作为XIB文件中的帧而不是加载的UIView的帧返回。 (如果我在加载后点击一个按钮然后返回预期和期望的帧)

示例2:

self.centreLine.frame = CGRect(x: Int(sidePadding), y: Int(slideView.frame.height/2), width: Int(UIScreen.main.bounds.width - 2 * sidePadding), height: 2)

我希望这个视图能够适应它所包含的视图的大小。在这种情况下,它应该保持在边缘的填充内并且恰好位于视图的中间。再一次,情况并非如此。

我尝试使用this回答:

-(void)awakeFromNib

override func layoutSubviews() {
    super.layoutSubviews()
}

但这些似乎都没有被告知。

问题部分是由于我在UIView里面,因为我通常称之为:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
}

我有点困惑但真的很想知道为什么会出现这个问题。我遇到的主要问题是简明地搜索问题,并且已经耗尽了我目前所有的线索。

2 个答案:

答案 0 :(得分:0)

在视图类中,创建一个加载nib的类函数并返回加载的视图。用它来初始化视图

UiView

class func loadViewFromNib() -> BSlideBar 
    guard let nibs = Bundle.main.loadNibNamed("BSlideBar", owner: self, options: nil) as? [UIVIew] else {  assertFailure(): return UIView() }

    return nibs.first as! BSlideBar
}

在UIViewVontroller中初始化变量,配置视图,然后将其添加到子视图

var slideBar: BSlideBar = BSlideBar.loadViewFromNib()
slideBar.frame = CGRect(.....)
addSubview(slideBar)

应该工作,但我要仔细检查"为什么"在我回答之前,不要给你不好的信息。

答案 1 :(得分:0)

你并不是“满载”。它“完全布局”。

覆盖layoutSubviews

override func layoutSubviews() {
    super.layoutSubviews()

    // At this point, all of my direct subviews' frames are set.
    // However, their subviews (my more distant descendants)
    // haven't had their frames updated yet.
}

当整个视图层次结构完成布局时,没有特别好的方法可以得到通知。收到drawRect:后,您可以确定所有后代都已布局,但您不应该在此时修改图层属性。