我正在开发一些基于 UIView 的自定义输入控件,并且正在尝试确定设置 View 的正确做法。使用 UIViewController 时,使用 loadView
和相关的 viewWill
、viewDid
方法相当简单,但在子类化 UIView 时,最接近的方法我有 `awakeFromNib
、drawRect
和 layoutSubviews
。 (我正在考虑设置和拆卸回调。)在我的情况下,我在 layoutSubviews
中设置我的框架和内部 View ,但我在屏幕上看不到任何东西。
确保我的 View 具有我想要的正确高度和宽度的最佳方法是什么? (无论我是否使用自动布局,我的问题都适用,尽管可能有两个答案。)什么是正确的“最佳实践”?
最佳答案
Apple 非常清楚地定义了如何继承 UIView
在文档中。
查看下面的列表,尤其是 initWithFrame:
和 layoutSubviews
.前者旨在设置您的 UIView
的框架而后者旨在设置框架及其 subview 的布局。
还要记住 initWithFrame:
只有在实例化 UIView
时才会调用以编程方式。如果您从 nib 文件(或 Storyboard)加载它,initWithCoder:
将会被使用。在 initWithCoder:
框架尚未计算,因此您无法修改在 Interface Builder 中设置的框架。如建议 in this answer您可能会考虑调用initWithFrame:
来自 initWithCoder:
为了设置框架。
最后,如果您加载 UIView
从 Nib (或 Storyboard),你也有awakeFromNib
执行自定义框架和布局初始化的机会,因为 awakeFromNib
被称为它保证层次结构中的每个 View 都已取消归档和初始化。
来自 NSNibAwaking
的文档(现在被 awakeFromNib
的文档取代):
Messages to other objects can be sent safely from within awakeFromNib—by which time it’s assured that all the objects are unarchived and initialized (though not necessarily awakened, of course)
还值得注意的是,使用自动布局时,您不应该明确设置 View 的框架。相反,您应该指定一组足够的约束,以便布局引擎自动计算框架。
直接来自documentation :
Methods to Override
Initialization
initWithFrame:
It is recommended that you implement this method. You can also implement custom initialization methods in addition to, or instead of, this method.
initWithCoder:
Implement this method if you load your view from an Interface Builder nib file and your view requires custom initialization.
layerClass
Implement this method only if you want your view to use a different Core Animation layer for its backing store. For example, if you are using OpenGL ES to do your drawing, you would want to override this method and return the CAEAGLLayer class.Drawing and printing
drawRect:
Implement this method if your view draws custom content. If your view does not do any custom drawing, avoid overriding this method.
drawRect:forViewPrintFormatter:
Implement this method only if you want to draw your view’s content differently during printing.Constraints
requiresConstraintBasedLayout
Implement this class method if your view class requires constraints to work properly.
updateConstraints
Implement this method if your view needs to create custom constraints between your subviews.
alignmentRectForFrame:
,frameForAlignmentRect:
Implement these methods to override how your views are aligned to other views.Layout
sizeThatFits:
Implement this method if you want your view to have a different default size than it normally would during resizing operations. For example, you might use this method to prevent your view from shrinking to the point where subviews cannot be displayed correctly.
layoutSubviews
Implement this method if you need more precise control over the layout of your subviews than either the constraint or autoresizing behaviors provide.
didAddSubview:
,willRemoveSubview:
Implement these methods as needed to track the additions and removals of subviews.
willMoveToSuperview:
,didMoveToSuperview
Implement these methods as needed to track the movement of the current view in your view hierarchy.
willMoveToWindow:
,didMoveToWindow
Implement these methods as needed to track the movement of your view to a different window.Event Handling:
touchesBegan:withEvent:
,touchesMoved:withEvent:
,touchesEnded:withEvent:
,touchesCancelled:withEvent:
Implement these methods if you need to handle touch events directly. (For gesture-based input, use gesture recognizers.)
gestureRecognizerShouldBegin:
Implement this method if your view handles touch events directly and might want to prevent attached gesture recognizers from triggering additional actions.
https://stackoverflow.com/questions/15978370/