【问题标题】:Different UI for different iPAD sizes针对不同 iPad 尺寸的不同 UI
【发布时间】:2017-06-20 19:53:02
【问题描述】:

我们的项目适用于所有 iPAD,我们遇到了一个问题,例如,我们在屏幕上垂直放置了 8 个按钮,并添加了限制作为垂直间距,它们在 iPAD 9.7 英寸上看起来不错,但在 iPAD 上看起来真的很大12.9,所以问题是,有没有什么好的方法可以更好地实际使用屏幕空间,如果它是 iPAD 12.9,则添加一个额外的 UIView。我已经研究过使用尺寸等级,但我相信所有 iPAD 都有一个尺寸等级,我想要的是如果有一种方法可以使用界面生成器为不同的 iPAD 尺寸提供不同的 UI

【问题讨论】:

  • 你有想要实现的 UI 示例吗?
  • 这不是 StackView 应该做的吗?看看吧。。
  • 您不需要添加 UIView,您可以通过适当的方式设置约束来实现您的目标。约束内有许多选项可以设置视图,如关系、优先级、纵横比等。

标签: ios ipad xcode8 ipad-3


【解决方案1】:

我想你的情况是这个特定的 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屏幕。然后只需加载所需的屏幕,就好像它是一个完全不同的屏幕。

【讨论】:

  • 嘿@Pochi,非常感谢您的回答,这是使用不同视图的好方法。但是我的一个问题是,如果我使用您的方式制作的视图,并且该视图只占用一定的高度怎么办?我将如何做到这一点而不是使用 let screenRect : CGRect = UIScreen.main.bounds。如果我不给它一个高度会怎样?另外,我可以在我的故事板中使用这个 UIView 类吗?
  • 第一个问题:什么都没发生,只要有适当的约束就会正常显示。您需要指定一个位置(如中心 x 和 y),以及视图的大小。只要视图中的所有元素都具有彼此的相对位置,您就不需要指定高度。只需确保顶部元素的位置相对于视图的顶部,然后其下方的元素相对于最后一个元素,依此类推,直到最后一个元素的位置相对于视图的底部。这种方法的好处是您可以在 IB 上进行设计。
  • 第二个问题:是的。如果您使用我在上面发布的代码,只需将 UIView 拖到界面构建器中即可。然后将其设置为您的自定义视图的类型。它应该自动显示为预览。但请记住,对于 Interface Builder (IB) 来呈现视图,它使用 init?(coder aDecoder: NSCoder) 方法中的代码。由于那个调用“loadViewFromNib”,那里的条件将定义哪个 XIB 将用作预览。
  • 在我忘记之前,这里有一篇描述它是如何工作的帖子:(它有点旧但没有太大变化)supereasyapps.com/blog/2014/12/15/…
【解决方案2】:

按照我的建议设置约束看看我为你创建的Sample

  1. 提供您的按钮纵横比。
  2. 给定宽度等于父视图的宽度。
  3. 添加约束在容器中水平居中和在容器中垂直居中。
  4. 选择您的按钮,然后转到尺寸检查器并设置宽度的乘数(例如 0.3 或 0.4 等)。
  5. 然后将乘数设置为“将 X 中心对齐到..”(如果您希望按钮位于中心的左侧,则将乘数设置为低于 1,例如 0.8、0.7、0.5 等如果您希望按钮位于右侧然后将乘数值设置为大于 1,如 1.2 等)。
  6. 像第 5 步一样设置“将中心 y 对齐到..”的乘数值。

全部完成。运行并检查。

希望这会对你有所帮助。

【讨论】:

    【解决方案3】:

    您可以为此使用自动布局。您可以为按钮分配纵横比基本高度。请记住,可以选择将比率关系设置为“等于”或“小于等于”。您可以使用这些而不是给出确切的约束。所以这会导致按钮适应高度。然后在代码中,您可以简单地检查是否有足够的空间来绘制额外的 uiview。这也将解决“看起来真的很大”的问题。

    在此处查看 IB 屏幕截图以了解我所指的内容: Click on 'Relation' to see these settings

    【讨论】:

      【解决方案4】:

      假设您的 nib 是 Foo_pro.xib 和 Foo_ipad.xib。

      @implementation Util
      
      +(BOOL) isIpad_1024
      {
          if ([UIScreen mainScreen].bounds.size.height == 1024) {
              return  YES;
          }
          return NO;
      }
      
      +(BOOL) isIpadPro_1366
      {
          if ([UIScreen mainScreen].bounds.size.height == 1366) {
              return  YES;
          }
          return NO;
      }
      
      +(NSString *)convertXib:(NSString *)nibName {
          if([Util isiPadPro_1366]) {
              return [NSString stringWithFormat:@"%@_pro", nibName];
          } else {
              return [NSString stringWithFormat:@"%@_ipad", nibName];
          }
      }
      
      Foo *foo = [[Foo alloc] initWithNibName:[Util convertXib:@"Foo"] bundle:nil]
      

      【讨论】:

        【解决方案5】:

        试试这个

        1.删除所有按钮的约束

        1. 将所有按钮添加到堆栈视图中
        2. 在您的堆栈视图上设置垂直约束
        3. 为 stackview 按钮设置相同的高度和相同的宽度
        4. 如果您为任何按钮设置了高度,则删除高度
        5. 如果您希望 stackview 在不同的设备上运行,请不要设置它的高度。

        【讨论】:

          【解决方案6】:

          你可以用这个

          所有按钮都嵌入到视图中并设置为超级视图的约束。

          • 确保为其添加纵横比约束。

          选择所有按钮并添加约束

          • 等宽、等高、纵横比

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2019-11-15
            • 2015-02-28
            • 2020-12-26
            • 1970-01-01
            • 2020-03-26
            • 1970-01-01
            • 2012-11-11
            • 1970-01-01
            相关资源
            最近更新 更多