我有一个看起来像这样的视图控制器:
class SpotViewController: UIViewController {
let spot: Spot
init(spot: Spot) {
self.spot = spot
super.init(nibName: "SpotViewController", bundle: nil)
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear: \(view.frame)") # => (0.0, 0.0, 600.0, 600.0)
}
override func viewDidLoad() {
super.viewDidLoad()
print("viewDidLoad: \(view.frame)") # => (0.0, 0.0, 600.0, 600.0)
}
}
当我通过let spotViewController = SpotViewController(spot: spot)
实例化视图控制器并将其推送到导航控制器时,viewDidLoad
和viewWillAppear
中的结果帧都不正确。它给了我(0.0, 0.0, 600.0, 600.0)
这是接口构建器中的大小。
为什么会发生这种情况以及使用xib实例化视图控制器以确保框架正确的正确方法是什么?
答案 0 :(得分:0)
这将解决您的问题,UIViewController从xib加载,在viewDidLoad期间保持xib大小:
extension UIViewController {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
if self !== UIViewController.self {
return
}
dispatch_once(&Static.token) {
pb_applyFixToViewFrameWhenLoadingFromNib()
}
}
@objc func pb_setView(view: UIView!) {
// View is loaded from xib file
if nibBundle != nil && storyboard == nil {
view.frame = UIScreen.mainScreen().bounds
view.layoutIfNeeded()
}
pb_setView(view)
}
private class func pb_applyFixToViewFrameWhenLoadingFromNib() {
UIViewController.swizzleMethodSelector(NSSelectorFromString("setView:"), withSelector: #selector(UIViewController.pb_setView(_:)))
UICollectionView.swizzleMethodSelector(#selector(UICollectionView.layoutSubviews), withSelector: #selector(UICollectionView.pb_layoutSubviews))
UITableView.swizzleMethodSelector(#selector(UITableView.layoutSubviews), withSelector: #selector(UITableView.pb_layoutSubviews))
}
}
extension UITableView {
@objc private func pb_layoutSubviews() {
if dataSource == nil {
super.layoutSubviews()
} else {
pb_layoutSubviews()
}
}
}
extension UICollectionView {
@objc private func pb_layoutSubviews() {
if dataSource == nil {
super.layoutSubviews()
} else {
pb_layoutSubviews()
}
}
}