【问题标题】:incorrect frame size when instantiating ViewController w/ xib使用 xib 实例化 ViewController 时帧大小不正确
【发布时间】:2016-04-25 11:35:04
【问题描述】:

我有一个看起来像这样的视图控制器:

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) 实例化视图控制器并将其推送到导航控制器时,viewDidLoadviewWillAppear 中的结果帧都不正确。它给了我(0.0, 0.0, 600.0, 600.0),这是界面生成器中的大小。

为什么会发生这种情况以及使用 xib 实例化视图控制器以确保框架正确的正确方法是什么?

【问题讨论】:

  • 你如何显示控制器(视图)?
  • @Wain 我只是将它推入navigationController 堆栈,带有navigationController!.pushViewController(spotViewController, animated: true)
  • viewDidLayoutSubviews() 中的框架是什么?
  • @DennisPashkov 在viewDidLayoutSubviews 中是正确的 ((0.0, 0.0, 375.0, 667.0))。这是添加诸如添加程序元素/约束之类的正确位置吗?
  • 不,当视图加载/合适时添加它们和布局规则。通过视图出现,布局将变得井井有条

标签: ios iphone swift xib


【解决方案1】:

这将解决您的问题,从 xib 加载 UIViewController,在 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()
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多