我想你的情况是这个特定的 ViewController 有很多共享的东西,(比如一个公共的顶部栏,或者一个导航栏),但是中间的内容似乎不合适。
在这种情况下,建议使用自定义 UIView,它会根据当前设备的高度或宽度加载不同的 xib 文件。
这里的关键是,你实际上只需要一个 UIView 子类。
为此,您也可以使用@IBDesignable 在界面构建器中实时预览它。
要实现这一点,您必须遵循以下步骤。
1) 根据大小为每个“UIView”创建一个 .xib 文件。
2) 创建一个 UIView 子类。
3) 将接口构建器中的属性挂钩到该子类。请注意,您必须对要使用的每个 xib 文件重复此过程。重要提示:尽管它们是不同的 xib,但它们都被同一个类所吸引。
4) 像这样将创建的类标记为@IBDesignable。
@IBDesignable class CustomView: UIView {
...
}
5) 在您的类中添加以下代码,该代码将根据您选择的任何标准加载不同的 xib。
////////// View Logic //////////
// Our custom view from the XIB file
var view: UIView!
func xibSetup() {
view = loadViewFromNib()
// use bounds not frame or it'll be offset
view.frame = bounds
// Make the view stretch with containing view
view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
// Adding custom subview on top of our view (over any custom drawing > see note below)
addSubview(view)
}
func setup()
{
// Extra setup goes here
}
func loadViewFromNib() -> UIView {
let bundle = Bundle(for: type(of: self))
let nib : UINib
let screenRect : CGRect = UIScreen.main.bounds;
// Use a different Nib based on the current screen height
if screenRect.size.height == 1024 {
// iPad Air & Pro
nib = UINib(nibName: "iPadNormal", bundle: bundle)
}
else if screenRect.size.height == 1366 {
// Large iPad Pro
nib = UINib(nibName: "iPadLarge", bundle: bundle)
}
else {
// Fall back
nib = UINib(nibName: "iPadFallback", bundle: bundle)
}
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
override init(frame: CGRect) {
// 1. setup any properties here
// 2. call super.init(frame:)
super.init(frame: frame)
// 3. Setup view from .xib file
xibSetup()
// 4. Other Setup
setup()
}
required init?(coder aDecoder: NSCoder) {
// 1. setup any properties here
// 2. call super.init(coder:)
super.init(coder: aDecoder)
// 3. Setup view from .xib file
xibSetup()
// 4. Other Setup
setup()
}
////////////////
重要提示:
仅当自定义视图的内容相同或更改非常少(布局无关紧要)时,才建议使用此方法。如果内容在尺寸之间变化很大(就像您实际上想要显示不同的东西),那么您应该使用您的共享逻辑创建一个“BaseViewController”,并为每个 iPad 尺寸创建一个子类,以便它们每个都有自己的 ViewController + Interface Builder屏幕。然后只需加载所需的屏幕,就好像它是一个完全不同的屏幕。