草庐IT

ios - 继承 UIView 的正确做法?

coder 2023-04-25 原文

我正在开发一些基于 UIView 的自定义输入控件,并且正在尝试确定设置 View 的正确做法。使用 UIViewController 时,使用 loadView 和相关的 viewWillviewDid 方法相当简单,但在子类化 UIView 时,最接近的方法我有 `awakeFromNibdrawRectlayoutSubviews。 (我正在考虑设置和拆卸回调。)在我的情况下,我在 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.

关于ios - 继承 UIView 的正确做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15978370/

有关ios - 继承 UIView 的正确做法?的更多相关文章

  1. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. ruby-on-rails - 正确的 Rails 2.1 做事方式 - 2

    question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参

  4. ruby - 我可以将我的 README.textile 以正确的格式放入我的 RDoc 中吗? - 2

    我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  7. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  8. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  9. ruby-on-rails - Rails 单表继承 : How to override the value written to the type field - 2

    在我的系统中,我已经定义了STI。Dog继承自Animal,在animals表中有一个type列,其值为"Dog"。现在我想让SpecialDog继承自dog,只是为了在某些特殊情况下稍微修改一下行为。数据还是一样。我需要通过SpecialDog运行的所有查询,以返回数据库中类型为Dog的值。我的问题是因为我有一个type列,rails将WHERE"animals"."type"IN('SpecialDog')附加到我的查询中,所以我不能获取原始的Dog条目。所以我想要的是以某种方式覆盖rails在通过SpecialDog访问数据库时使用的值,使其表现得像Dog。有没有办法覆盖用于类型

  10. ruby - 如何在 RVM 下将 Bundler 安装到 @global gemset,这是正确的方法吗 - 2

    我在OSX上(如果重要的话)。如果我使用RVM安装Ruby,它会默认将Bundler安装到@globalgemset假设我想要一个不同版本的bundler。我假设我需要做的就是执行geminstallbundler--version但是,这会将bundler安装到默认gemset并且RVM不会为其设置路径。因此,如果我键入bundler,它仍会启动一个与Ruby一起安装到@global中的bundler两个问题:如何将bundler安装到@globalgemset。将bundler安装到@globalgemset中的模式是否正确,或者我遗漏了什么 最佳答案

随机推荐