我有一个视图控制器,看起来像:
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,600.0) } }
当我通过让spotViewController = SpotViewController(spot:spot)实例化视图控制器并将其推送到导航控制器时,结果框架在viewDidLoad和viewWillAppear中都是不正确的.它给了我(0.0,600.0)这是界面构建器中的大小.
为什么会发生这种情况以及使用xib实例化视图控制器以确保帧正确的正确方法是什么?
解决方法
这将解决您的问题,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() } } }