【问题标题】:How to set UIView size to match parent without constraints programmatically如何以编程方式设置 UIView 大小以匹配没有约束的父级
【发布时间】:2016-06-09 12:00:25
【问题描述】:

这个问题听起来很简单,但它让我发疯了。 我在 IB 中创建了一个名为 iBag 的白色视图,它的大小取决于屏幕大小。

现在我想以编程方式创建一个新的 UIView,并通过此代码将其作为子视图添加到具有相同大小和位置的 iBag

let newView = UIView()
newView.frame =  (frame: CGRect(x: 0, y: 0, width: iBag.frame.width, height: iBag.frame.height))
newView.backgroundColor = UIColor.redColor()
iBag.addSubview(newView)

我也尝试过边界,但没有帮助。 我可以使用约束来解决问题,但我想了解问题所在。

【问题讨论】:

  • 你在哪里实例化 ViewWillAppear 中的新视图???
  • @SandeepBhandari In viewDidLoad
  • 你可以在 ViewDidAppear 中试试吗????
  • 这是因为约束。
  • 您应该在viewDidLayoutSubviews 中添加新视图,因为在此之前框架和自动布局过程不会完成。确保保留对新视图的引用,并且仅在它为 nil 时添加它,因为 viewDidLayoutSubviews 可能会被多次调用

标签: ios swift uiview cgrect


【解决方案1】:

试试这个:

Swift 1 和 2:

newView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

Swift 3+:

newView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

如果它不起作用,还有这个:

iBag.autoresizesSubviews = true

【讨论】:

    【解决方案2】:

    这么多答案,没有人解释什么是错的。

    我会努力的。

    您正在将newView 的框架设置为您的超级视图框架自动布局引擎开始确定您的超级视图位置和大小之前。因此,当您使用superviews 框架时,您正在使用它的初始框架。在大多数情况下这是不正确的。

    你有 3 种方法可以正确地做到这一点:

    • 为您的newView 使用自动布局约束

    • viewDidLayoutSubviews 方法中设置newViews 框架。哪个是 当自动布局引擎完成确定帧实际值时调用。 (注:该方法可以多次调用)

    • newView 设置自动调整大小的掩码

    【讨论】:

    • 谢谢。你救了我的周末。所有教程都告诉如何格式化 UIView,没有人告诉必须在 viewDidLayoutSubviews 而不是 viewDidLoad 上调用 update
    【解决方案3】:

    试试这个

    subview.frame = parentView.bounds

    subview.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]

    parentView.addSubview(subview)

    【讨论】:

      【解决方案4】:

      试试这个,

       override func viewDidLayoutSubviews() {
      
      
          newView.frame =  (frame: CGRect(x: 0, y: 0, width: iBag.frame.width, height: iBag.frame.height))
      
      }
      

      或者您可以使用viewWillAppearviewDidAppear 设置框架。

      因为在viewDidload 中,您的 iBag 框架与您的界面构建器(故事板)中的框架相同。现在它将根据您运行的约束和设备大小而改变。因此,在viewDidload 中,您的新视图获取旧框架而不是更改框架。所以,最好使用viewDidLayoutSubviewsviewWilAppear

      第二件事,在任何地方都使用自动布局。在父视图而不是子视图中使用自动布局是不好的做法。

      【讨论】:

      • 这不是一个好的解决方案,因为 viewDidLayoutSubviews 被多次调用。所以会创建很多“newViews”。
      • 是的,没错@jn-se 编辑了我的答案!现在,我认为这很好
      【解决方案5】:

      也许这会对你有所帮助

      override func viewDidLayoutSubviews() {
      
          let newView = UIView()
          newView.frame = iBag.bounds
          newView.addConstraints(iBag.constraints)
          newView.backgroundColor = UIColor.redColor()
          iBag.addSubview(newView)
      
      }
      

      希望这会对你有所帮助。

      【讨论】:

      • 对不起,还是没有结果
      • 您是否在情节提要或约束布局中使用自动调整大小?
      • 在尝试了不同的方法后它起作用了,但它只适用于 viewDidLayoutSubviews 函数。无论如何,谢谢。
      【解决方案6】:

      也许这会起作用:-

      subview.bounds.size = parentView.bounds.size
      
      subview.center = parentView.center
      

      但在您的情况下,CGRect 内的widthheight 应该是

      width: parentView.bounds.size.width
      height: parentView.bounds.size.height
      

      然后将其作为子视图添加到它的父级。

      【讨论】:

      • 不,同样的结果。
      【解决方案7】:

      试试这个代码:

      let newView = UIView()
      newView.frame =  (frame: CGRect(x: iBag.frame.origin.x, y: iBag.frame.origin.y, width: iBag.frame.size.width, height:  iBag.frame.size.height))
      newView.backgroundColor = UIColor.redColor()
      iBag.addSubview(newView)
      

      【讨论】:

        【解决方案8】:

        不使用约束可能是错误的。如果您的故事板/笔尖设置为使用 AutoLayout(默认情况下启用),则设置框架/边界会被 AutoLayout 系统覆盖,您必须使用约束来使布局看起来正确。 (或设置将自动调整大小掩码转换为约束的标志。我不记得那个标志叫什么,目前似乎找不到它。)

        【讨论】:

          【解决方案9】:

          如果您在 viewdidload 中设置视图,请在 viewdidappear 中调用它,以便根据屏幕尺寸捕获原始视图帧

          【讨论】:

            【解决方案10】:

            尝试使用 applyConstraints

            parentView.addSubview(newSubview, applyConstraints: true)
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-02
            • 1970-01-01
            • 2016-08-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多