为了账号安全,请及时绑定邮箱和手机立即绑定

子类化UIView的正确做法?

子类化UIView的正确做法?

九州编程 2019-12-07 14:00:09
我正在研究一些基于UIView的自定义输入控件,并且正在尝试确定用于设置视图的正确做法。当一个UIViewController的工作,这是相当简单的使用loadView和相关viewWill,viewDid方法,但是继承一个UIView的时候,我有最接近methosds是`awakeFromNib,drawRect和layoutSubviews。(我在考虑设置和拆卸回调的问题。)就我而言,我在中设置框架和内部视图layoutSubviews,但屏幕上看不到任何内容。确保我的视图具有想要的正确高度和宽度的最佳方法是什么?(尽管可能有两个答案,但无论是否使用自动版式,我的问题都适用。)什么是正确的“最佳实践”?
查看完整描述

3 回答

?
SMILET

TA贡献1796条经验 获得超4个赞

这在Google中仍然很高。以下是swift的更新示例。


该didLoad函数使您可以放置所有自定义的初始化代码。正如其他人提到的那样,didLoad当通过编程方式创建视图init(frame:)或XIB反序列化器通过以下方式将XIB模板合并到您的视图中时,将被调用init(coder:)


除了:layoutSubviews,updateConstraints大多数视图被多次调用。当视图的边界发生变化时,此功能适用于高级多遍布局和调整。就我个人而言,我尽可能避免使用多遍布局,因为它们会消耗CPU周期并使所有事情变得头疼。另外,我很少在初始化器中放入约束代码,因为我很少使它们无效。


import UIKit


class MyView: UIView {

  //-----------------------------------------------------------------------------------------------------

  //Constructors, Initializers, and UIView lifecycle

  //-----------------------------------------------------------------------------------------------------

  override init(frame: CGRect) {

      super.init(frame: frame)

      didLoad()

  }


  required init?(coder aDecoder: NSCoder) {

    super.init(coder: aDecoder)

    didLoad()

  }


  convenience init() {

    self.init(frame: CGRectZero)

  }


  func didLoad() {

    //Place your initialization code here


    //I actually create & place constraints in here, instead of in

    //updateConstraints

  }


  override func layoutSubviews() {

     super.layoutSubviews()


     //Custom manually positioning layout goes here (auto-layout pass has already run first pass)

  }


  override func updateConstraints() {

    super.updateConstraints()


    //Disable this if you are adding constraints manually

    //or you're going to have a 'bad time'

    //self.translatesAutoresizingMaskIntoConstraints = false


    //Add custom constraint code here

  }

}


查看完整回答
反对 回复 2019-12-07
?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

Apple 文档中有一个不错的摘要,iTunes上提供的免费斯坦福课程对此做了很好的介绍。我在这里介绍我的TL; DR版本:


如果您的类主要由子视图组成,则在init方法中分配它们的正确位置。对于视图,有两种不同的init方法可以调用,这取决于是从代码还是从笔尖/ storyboard实例化视图。我要做的是编写自己的setup方法,然后从initWithFrame:和initWithCoder:方法中调用它。


如果要进行自定义绘图,则确实要drawRect:在视图中进行覆盖。但是,如果自定义视图主要是子视图的容器,则可能不需要这样做。


仅layoutSubViews当您要执行纵向或横向方向上的添加或删除子视图之类的操作时才覆盖。否则,您应该可以不理会它。


查看完整回答
反对 回复 2019-12-07
  • 3 回答
  • 0 关注
  • 620 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信