【问题标题】:Getting size of UIView in init在init中获取UIView的大小
【发布时间】:2017-01-07 18:38:56
【问题描述】:

我在我的 iOS 应用程序中创建了 UIView 的自定义子类,我试图在视图的 init 方法中获取视图的计算大小,因此我可以在创建子视图以放入自定义视图时使用它们。

自定义视图位于堆栈视图中,它为我的视图分配了总(主视图)高度的 1/3。

我的初始化看起来像这样:

var mySubView: UIImageView

required init?(coder aDecoder: NSCoder) {

    mySubView = UIImageView()
    super.init(coder: aDecoder)

    let viewWidth = Int(self.frame.size.width)
    let viewHeight = Int(self.frame.size.height)
    mySubView.frame = CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight)
    mySubView.backgroundColor = UIColor.cyan

    self.addSubview(mySubView)
}

但是,没有正确报告高度和宽度。例如,上面的 mySubView 最终只填充了自定义视图总空间的大约一半。

任何帮助将不胜感激!

【问题讨论】:

  • 我认为视图在其生命周期的这一点上不知道它的尺寸。尝试获取viewWillAppear中的尺寸
  • 你不能,如果它是视图控制器的视图。在视图控制器的生命周期中还为时过早。您需要等到(最早)UIViewController.viewwilllayoutSubviews()。出于这个原因,您可能应该使用自动布局约束,其中许多已经由堆栈视图处理。创建您的自定义视图,针对自定义视图添加子视图和约束(在 IB 或代码中),它会按照您需要的方式进行布局。
  • @toddg 是正确的,viewWillLayoutSubviews()(由 UIViewController 使用)的替代方法是 viewWillAppear()(由 UIView 使用)。我倾向于为此考虑视图控制器。注意:我相信这两个函数可以在加载时多次调用,也可以在方向更改(以及 iPad 中的多任务处理)等情况下调用。
  • 在 UIView 子类中覆盖 layoutSubviews() 是视图生命周期中最早可以抓取视图框架(并使用它来决定如何布局子视图)的位置
  • 完美 - 将代码移动到 layoutSubviews() 工作!非常感谢!

标签: swift cocoa-touch uiview ios10


【解决方案1】:

除非您事先知道确切的尺寸,否则在视图的生命周期中调用初始化程序太早,无法准确地进行布局。即便如此,按习惯来说,这样做是错误的地方。

尝试使用layoutSubviews 方法:

class SubView: UIImageView {

    var mySubView: UIImageView

    required init?(coder aDecoder: NSCoder) {

        mySubView = UIImageView()
        mySubView.backgroundColor = UIColor.cyan

        super.init(coder: aDecoder)
        self.addSubview(mySubView)
    }

    override func layoutSubviews() {
        mySubView.frame = self.bounds
        super.layoutSubviews()
    }
}

现在子视图边界将在每个布局通道开始时正确设置。这是一个便宜的操作。

另外,UIViewbounds 属性是转换为视图内部坐标空间的frame。这意味着通常情况下这是真的:bounds = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)。我建议阅读有关视图布局的文档。

或者,您可以完全放弃手动布局并使用 AutoLayout 为您执行此操作。

class SubView: UIImageView {

    var mySubView: UIImageView

    required init?(coder aDecoder: NSCoder) {

        mySubView = UIImageView()
        mySubView.backgroundColor = UIColor.cyan

        super.init(coder: aDecoder)
        self.addSubview(mySubView)

        mySubView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        mySubView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        mySubView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
        mySubView.heightAnchor.constraint(equalTo: heightAnchor).isActive = true
    }
}

【讨论】:

  • 谢谢!我在这里为我的问题简化了这个案例——在我的应用程序中,我不希望任何子视图全尺寸,但问题是我需要几乎像素完美的精细控制它们的相对大小。我尝试使用 AutoLayout 有一段时间,但我根本无法让它按照我需要的方式进行布局,所以我认为更手动的方法可能会节省一些时间。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
相关资源
最近更新 更多