草庐IT

objective-c - 以编程方式添加和删除 View 及其 Controller 的最佳方法是什么?

coder 2024-01-13 原文

我希望看到有关如何以编程方式管理视图的详细说明。我将概述我现在的操作方式,并希望对我的方法很糟糕做出评论,或者仅是有关如何干净,正确地进行操作的概述。

基本上,在我应用程序的主视图控制器的loadView方法中,我首先创建一个根视图,并为其设置self.view。当我想附加一个控制器(例如显示的第一个控制器)时,我调用此方法:

-(void) attachViewForController:(UIViewController*)controller
{
    [self.mRootView addSubview:controller.view];
    [controller viewWillAppear:NO];    
}

注意,我显式调用了viewWillAppear(我相信它不会自动调用它),在这里我手动执行任何动画以使视图进入(滑入,淡入等)。这种方法在这里有什么错误或奇怪吗?

现在,当我想离开此视图并切换到另一个视图时,我调用一个方法来设置开关:
-(void) setControllerSwitch:(UIViewController*)outgoingController 
    incomingController:(UIViewController*)incomingController
    delay:(float)delay;
{
    self.mOutgoingController = outgoingController;
    self.mIncomingController = incomingController;
    self.mSwitchControllerTimer = [NSTimer scheduledTimerWithTimeInterval:delay target:self selector:@selector(switchControllerCallback) userInfo:nil repeats:NO];

}

此时,我已经开始了外出视图的退出动画,并且此方法记录了控制器并安排了一个方法,该方法将在外出视图完成动画处理时执行实际的切换。像这样:
-(void) switchControllerCallback
{
    self.mSwitchControllerTimer = nil;

    // remove outgoing view
    [mOutgoingController.view removeFromSuperview];

    // add incoming view
    [self attachViewForController:mIncomingController]; 
}

这是管理事情的一种体面的方式吗?几点:
  • 我知道我可以替代地设置一个回调,以在传出的控制器动画结束时触发,但是选择只是通过显式的延迟参数来进行操作,以留出空间让我可以交叉淡入淡出的视图。但是,我认为尽早调用setControllerSwitch实际上可能不允许交叉淡入淡出,因为这会使早期的控制器变旧并使其动画被斩断。
  • 如前所述,我很想知道是否显式调用viewWillAppear是“否”,并且有一种更合适的方法来管理视图流。
  • 最佳答案

    从Apple开发人员文档复制而来,但是它对我有很多帮助,帮助我理解视图和管理多个视图。

    有效使用视图的技巧

    对于需要绘制标准系统视图未提供的内容的情况,自定义视图很有用,但是您有责任确保视图的性能足够好。 UIKit尽其所能来优化与视图相关的行为,并帮助您在自定义视图中获得良好的性能。但是,您可以通过考虑以下提示来在这方面帮助UIKit。

    视图并不总是具有对应的视图控制器

    应用程序中的各个视图和视图控制器之间几乎没有一对一的关系。视图控制器的工作是管理视图层次结构,该视图层次结构通常包含一个以上的视图,这些视图用于实现某些自包含功能。对于iPhone应用程序,每个视图层次结构通常填充整个屏幕,尽管对于iPad应用程序,视图层次结构可能仅填充屏幕的一部分。

    在设计应用程序的用户界面时,考虑视图控制器将扮演的角色很重要。视图控制器提供了许多重要的行为,例如协调屏幕上视图的呈现,协调从屏幕上删除这些视图,响应于内存不足警告释放内存以及响应于界面方向变化而旋转视图。规避这些行为可能导致您的应用程序行为不正确或以意外方式运行。

    有关更多信息,请参见View Controller及其在应用程序中的角色,请参阅《适用于iOS的View Controller编程指南》。

    最小化自定义工程图

    尽管有时需要自定义工程图,但您也应尽可能避免这样做。只有当现有系统视图类无法提供所需的外观或功能时,您才真正应该进行任何自定义绘图。每当您的内容可以与现有视图的组合进行组合时,最好的选择是将这些视图对象组合到自定义视图层次结构中。

    利用内容模式

    内容模式最大程度地减少了重绘视图所花费的时间。默认情况下,视图使用UIViewContentModeScaleToFill内容模式,该模式缩放视图的现有内容以适合视图的框架矩形。您可以根据需要更改此模式,以进行不同的调整,但是如果可以的话,应避免使用UIViewContentModeRedraw内容模式。无论采用哪种内容模式,都可以始终通过调用setNeedsDisplay或setNeedsDisplayInRect:来强制视图重绘其内容。

    尽可能将视图声明为不透明

    UIKit使用每个视图的opaque属性来确定该视图是否可以优化合成操作。对于自定义视图,将此属性的值设置为YES可以告诉UIKit,它不需要在视图后呈现任何内容。较少的渲染可以提高绘图代码的性能,因此通常会鼓励这样做。当然,如果将opaque属性设置为YES,则视图必须使用完全不透明的内容完全填充其边界矩形。

    滚动时调整视图的绘画行为

    滚动可以在短时间内引起大量视图更新。如果视图的绘图代码未正确调整,则视图的滚动性能可能会变慢。与其尝试确保视图的内容始终保持原始状态,不如考虑在滚动操作开始时更改视图的行为。例如,您可以暂时降低渲染内容的质量,或者在滚动过程中更改内容模式。滚动停止时,您可以将视图返回到其先前的状态并根据需要更新内容。

    不要通过嵌入子视图自定义控件

    尽管从技术上来说可以将子视图添加到标准系统控件(从UIControl继承的对象)中,但是您永远不应以这种方式对其进行自定义。支持自定义的控件通过控件类本身中的显式且文档齐全的接口来实现。例如,UIButton类包含用于设置按钮标题和背景图像的方法。使用定义的定制点意味着您的代码将始终正常工作。通过在按钮内嵌入自定义图像视图或标签来规避这些方法,可能会导致您的应用程序现在或将来(如果按钮的实现发生更改)的行为不正确。

    关于objective-c - 以编程方式添加和删除 View 及其 Controller 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8748663/

    有关objective-c - 以编程方式添加和删除 View 及其 Controller 的最佳方法是什么?的更多相关文章

    1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

      类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

    2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

      我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

    3. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

      我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

    4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

      我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

    5. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

      我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

    6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

      我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

    7. ruby-on-rails - 渲染另一个 Controller 的 View - 2

      我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

    8. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

      为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

    9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

      我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

    10. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

      查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

    随机推荐