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

标签 objective-c ios uiviewcontroller

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

基本上,在我应用程序的主视图控制器的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 - 继续检查直到 True

    ios - 设置带有身份验证的URL的图像-IOS SDK

    objective-c - 无法从NSTask的stdout获得中间输出?

    ios - 如何通过标识符在 Storyboard 中获取 View Controller ?

    objective-c - 当用户键入文本时为文本着色(iOS、Xcode)

    ios - Subspec vendored_frameworks 作为另一个 cocoapod 库

    ios - iOS 中的 FireBase removeValue 并不总是持久保存到数据库

    ios - 根据限定符将变量设置为不同的自定义 View (Swift)

    objective-c - 使用 plist 文件中的数据时定义模型是一个好习惯吗?

    ios - 在起始页隐藏 UINavigationController