• View Programming Guide for iOS ---- iOS 视图编程指南(三)---Windows


    Windows

    Every iOS application needs at least one window—an instance of the UIWindow class—and some may include more than one window. A window object has several responsibilities:

    每个iOS应用程序需要至少一个窗口---UIWindow类的一个实例---有些可能有不止一个窗口。窗口对象的任务是:

    • It contains your application’s visible content.

      它包含了应用程序的可见内容。

    • It plays a key role in the delivery of touch events to your views and other application objects.

      它在向视图和其它应用程序对象传递触摸事件时扮演关键角色。

    • It works with your application’s view controllers to facilitate orientation changes.

      它和应用程序视图控制器一起促进方向变化。

    In iOS, windows do not have title bars, close boxes, or any other visual adornments. A window is always just a blank container for one or more views. Also, applications do not change their content by showing new windows. When you want to change the displayed content, you change the frontmost views of your window instead.

    在iOS,窗口没有标题栏,关闭按钮,或任何其它可见的装饰。 窗口就只是一个或多个视图的空白容器。 而且,应用程序不会通过显示新窗口来改变它们的内容。 当你想改变显示的内容时, 你可以改变窗口上最前面的视图。

    Most iOS applications create and use only one window during their lifetime. This window spans the entire main screen of the device and is loaded from the application’s main nib file (or created programmatically) early in the life of the application. However, if an application supports the use of an external display for video out, it can create an additional window to display content on that external display. All other windows are typically created by the system, and are usually created in response to specific events, such as an incoming phone call.

    大多数iOS应用程序在它们的生命期都只创建并使用一个窗口。 该窗口贯穿设备的整个主要屏幕, 它在应用程序生命周期早期从应用程序的主要nib文件载入(或程序自动创建)。然而,如果应用程序支持需要外接显示器来显示视频,它可以创建一个额外的窗口来显示外接显示器的内容。通常所有的其它窗口都由系统创建,它们常常是用来响应指定事件,比如一个来电。

    Tasks That Involve Windows

    一、窗口涉及的任务

    For many applications, the only time the application interacts with its window is when it creates the window at startup. However, you can use your application’s window object to perform a few application-related tasks:

    对于很多应用程序,应用程序跟窗口唯一交互,是它启动时创建窗口的时候。然而,你可以使用应用程序窗口对象来执行一些跟应用相关的任务:

    • Use the window object to convert points and rectangles to or from the window’s local coordinate system. For example, if you are provided with a value in window coordinates, you might want to convert it to the coordinate system of a specific view before trying to use it. For information on how to convert coordinates, see “Converting Coordinates in the View Hierarchy.”

      使用窗口对象来转换点和矩形,把它们从窗口的内部坐标系统转换过来,或从别处转换到内部坐标系统去。比如,如果你有一个坐标窗口值,你可能想在使用它之前把它转换为一个指定视图的坐标系统。关于如何转换坐标的信息,请看 “Converting Coordinates in the View Hierarchy.”

    • Use window notifications to track window-related changes. Windows generate notifications when they are shown or hidden or when they accept or resign the key status. You can use these notifications to perform actions in other parts of your application. For more information, see “Monitoring Window Changes.”

      使用窗口通知来追踪窗口相关的各种改变。窗口在显示或隐藏,或当它们接受或放弃(resign)关键状态时,它们会生成各种通知。 你可以用这些通知在应用程序别的部分执行各种操作。 更多信息请看 “Monitoring Window Changes.”

    Creating and Configuring a Window

    二、 创建并配置一个窗口

    You can create and configure your application’s main window programmatically or using Interface Builder. In either case, you create the window at launch time and should retain it and store a reference to it in your application delegate object. If your application creates additional windows, have the application create them lazily when they are needed. For example, if your application supports displaying content on an external display, it should wait until a display is connected before creating the corresponding window.

    你可以用程序创建并配置应用程序的主要窗口,或使用界面创建器(Interface Builder)。任何创建方式,窗口都是在启动时创建,并一直保留它,还需要在应用程序委托对象里存储一个指向该窗口的引用连接。如果应用程序需要创建额外的窗口,让应用程序在需要时惰性的创建它们。 比如,如果应用程序支持显示外接显示器的内容,它应用等待直到显示在创建相关窗口之前被连接完成。

    You should always create your application’s main window at launch time regardless of whether your application is being launched into the foreground or background. Creating and configuring a window is not an expensive operation by itself. However, if your application is launched straight into the background, you should avoid making the window visible until your application enters the foreground.

    你应用总是在启动时创建应用程序主窗口,不管应用程序是被启动到前台或是后台。 创建并配置一个窗口本身并不是高损耗操作。然而,如果应用程序被直接启动到后台,你应该让窗口一直隐藏直到应用程序进入前台。

    Creating Windows in Interface Builder

    1、用界面生成器创建窗口

    Creating your application’s main window using Interface Builder is simple because the Xcode project templates do it for you. Every new Xcode application project includes a main nib file (usually with the name MainWindow.xib or some variant thereof) that includes the application’s main window. In addition, these templates also define an outlet for that window in the application delegate object. You use this outlet to access the window object in your code.

    用界面生成器创建应用程序的窗口很简单,因为Xcode项目模板已经为你完成。 每个新Xcode应用程序工程都包含一个主nib文件(通常的名称是MainWindow.xib 或一些变种),它包含了应用程序的主窗口。 此外,这些模板还给窗口在应用程序代理对象内定义了一个接口(outlet)。 你可以在代码里使用该接口来访问窗口对象。

    Important: When creating your window in Interface Builder, it is recommended that you enable the Full Screen at Launch option in the attributes inspector. If this option is not enabled and your window is smaller than the screen of the target device, touch events will not be received by some of your views. This is because windows (like all views) do not receive touch events outside of their bounds rectangle. Because views are not clipped to the window’s bounds by default, the views still appear visible but events do not reach them. Enabling the Full Screen at Launch option ensures that the window is sized appropriately for the current screen.

     重要:当用界面生成器创建窗口时, 推荐你启用”全屏启动“选项,该选项在属性选择器(attributes inspector)里。 如果该选项不被启用,你的窗口将比设备屏幕小,一些视图将接收不到很多触摸事件。那是因为窗口(跟所有视图一样)不接收在它们的边界矩形外发生的触摸事件。因为默认情况下,视图没有被裁减到窗口的边界里,视图任然是可见的,但是事件没有到达那里。启用”全屏启动”选项确保窗口尺寸对于当前屏幕正合适。

    If you are retrofitting a project to use Interface Builder, creating a window using Interface Builder is a simple matter of dragging a window object to your nib file. Of course, you should also do the following:

    如果你正使用界面生成器更新(retrofitting)一个项目, 用界面生成器创建一个窗口很简单,你只需要拖动一个窗口对象到nib文件即可。 当然,你还应该做以下事情:

    • To access the window at runtime, you should connect the window to an outlet, typically one defined in your application delegate or the File’s Owner of the nib file.

      要想在运行时访问窗口,你应该把窗口连接到一个接口,通常是一个在应用程序委托或nib文件的File's Owner里定义的接口。

    • If your retrofit plans include making your new nib file the main nib file of your application, you must also set theNSMainNibFile key in your application’s Info.plist file to the name of your nib file. Changing the value of this key ensures that the nib file is loaded and available for use by the time theapplication:didFinishLaunchingWithOptions: method of your application delegate is called.

      如果你的更新计划包含制作新的nib文件来代替应用程序的主nib文件, 你必要同时在应用程序的Info.plist文件的NSMainNibFile关键字那里,把关键字设置为你的新nib文件名。 改变该关键字确保该nib文件被加载,并让应用程序调用application:didFinishLaunchingWithOptions: 方法时使用它。

    For more information about creating and configuring nib files, see Interface Builder User Guide. For information about how to load nib files into your application at runtime, see “Nib Files” in Resource Programming Guide.

    更多有关创建和配置nib文件的各种信息,请看 Interface Builder User Guide. 更多有关在运行时应用程序如何加载nib文件的详细信息,请看Resource Programming Guide  “Nib Files” .

    Creating a Window Programmatically

    2、用程序创建一个窗口

    If you prefer to create your application’s main window programmatically, you should include code similar to the following in the application:didFinishLaunchingWithOptions: method of your application delegate:

    如果你更喜欢用程序创建你的应用程序主窗口,你应该在应用程序委托的application:didFinishLaunchingWithOptions: 方法里包含以下相似代码:

    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

    In the preceding example, self.window is assumed to be a declared property of your application delegate that is configured to retain the window object. If you were creating a window for an external display instead, you would assign it to a different variable and you would need to specify the bounds of the non main UIScreen object representing that display.

    例子中,假设 self.window是应用程序委托中一个已被声明的属性(property),应用程序委托是用来保留(retain)窗口对象的。如果你想要为外部显示器创建一个窗口,你应该把它分配(assign)给一个不同的变量, 并且你应该需要指定非主要UIScreen 对象的边界用来代表那个外部显示器。

    When creating windows, you should always set the size of the window to the full bounds of the screen. You should not reduce the size of the window to accommodate the status bar or any other items. The status bar always floats on top of the window anyway, so the only thing you should shrink to accommodate the status bar is the view you put into your window. And if you are using view controllers, the view controller should handle the sizing of your views automatically.

    当创建窗口时,你应该总是设置窗口尺寸为满屏。 你不应该为容纳状态栏或任何其它项而缩减窗口尺寸。 不管怎样状态栏总是漂浮在窗口的上边, 所以你只需要把容纳状态栏的视图放入窗口。 而且如果你有使用视图控制器,视图控制器应该能自动处理视图的尺寸。

    Adding Content to Your Window

    3、向窗口添加内容

    Each window typically has a single root view object (managed by a corresponding view controller) that contains all of the other views representing your content. Using a single root view simplifies the process of changing your interface; to display new content, all you have to do is replace the root view. To install a view in your window, use theaddSubview: method. For example, to install a view that is managed by a view controller, you would use code similar to the following:

    每个窗口通常有一个单一的根视图对象(由相关的视图控制器管理),根视图控制器包含表现内容的所有其它视图。使用一个根视图简化了改变界面的过程;要想显示新内容,你只需要替换根视图即可。要想在窗口里加入一个视图,使用addSubview: 方法。比如, 加入一个由一个视图控制器管理的视图,你使用以下相似代码:

    [window addSubview:viewController.view];

    In place of the preceding code, you can alternatively configure the rootViewController property of the window in your nib file. This property offers a convenient way to configure the root view of the window using a nib file instead of programmatically. If this property is set when the window is loaded from its nib file, UIKit automatically installs the view from the associated view controller as the root view of the window. This property is used only to install the root view and is not used by the window to communicate with the view controller.

    以上代码,你也可以在你的nib文件里设置窗口的 rootViewController 属性。该属性提供了一个配置窗口根视图的便捷方法--用nib文件代替程序。 如果当窗口从它的nib文件被载入时,该属性已经被设置,UIKit自动从相关的视图控制器(作为窗口根视图)加载视图。该属性只在加载根视图时使用,它不用来让窗口跟视图控制器通信。

    You can use any view you want for a window’s root view. Depending on your interface design, the root view can be a generic UIView object that acts as a container for one or more subviews, the root view can be a standard system view, or the root view can be a custom view that you define. Some standard system views that are commonly used as root views include scroll views, table views, and image views.

     你可以使用任何你想要的视图作为窗口的根视图。 根据你的界面设计,根视图可以是一个普通的UIView 对象,它是一个或多个子视图的的容器, 也可以是一个标准系统视图,还可以是一个自定义视图。 有一些标准系统视图常常被用来作为根视图,包括滚动视图,表格视图,和图像视图等。

    When configuring the root view of the window, you are responsible for setting its initial size and position within the window. For applications that do not include a status bar, or that display a translucent status bar, set the view size to match the size of the window. For applications that show an opaque status bar, position your view below the status bar and reduce its size accordingly. Subtracting the status bar height from the height of your view prevents the top portion of your view from being obscured.

    当配置窗口的根视图时,你负责在窗口里给它设置初始化尺寸和位置。 那些不包含状态栏或显示一个半透明状态栏的应用程序,视图尺寸跟窗口尺寸相匹配。 对于那些显示一个不透明状态栏,把视图放在状态栏的下面,相应的所见它的尺寸。从视图高度减去状态栏的高度,避免视图顶部被状态栏遮挡。 

    Note: If the root view of your window is provided by a container view controller (such as a tab bar controller, navigation controller, or split-view controller), you do not need to set the initial size of the view yourself. The container view controller automatically sizes its view appropriately based on whether the status bar is visible.

     注意:如果窗口的根视图是由一个容器视图控制器提供(比如,标签栏控制器,导航控制器,或拆分视图控制器), 你不需要设置视图的初始化尺寸。 容器视图控制器会根据状态栏是否可见自动调整合适的尺寸。

    Changing the Window Level

    4、 改变窗口层次

    Each UIWindow object has a configurable windowLevel property that determines how that window is positioned relative to other windows. For the most part, you should not need to change the level of your application’s windows. New windows are automatically assigned to the normal window level at creation time. The normal window level indicates that the window presents application-related content. Higher window levels are reserved for information that needs to float above the application content, such as the system status bar or alert messages. And although you can assign windows to these levels yourself, the system usually does this for you when you use specific interfaces. For example, when you show or hide the status bar or display an alert view, the system automatically creates the needed windows to display those items.

    每个UIWindow 对象有一个可设置的windowLevel 属性,该属性决定了窗口相对于别的窗口如何定位。 大部分情况,你应该不需要改变应用程序窗口的层次。 新窗口在创建时自动分配到一个正常的窗口层。 正常窗口层表明窗口表现应用程序相关的内容。 高窗口层次保留给需要漂浮在应用程序内容上面的信息,比如系统状态栏或各种警报信息。尽管你可以指派这些层次给窗口,但是当你使用指定接口的时候,这些是由系统为你完成。

    Monitoring Window Changes

    三、监控窗口变化

    If you want to track the appearance or disappearance of windows inside your application, you can do so using these window-related notifications:

    如果你想要监控应用程序中窗口的出现和隐藏, 你可以使用这些窗口相关的通知:

    These notifications are delivered in response to programmatic changes in your application’s windows. Thus, when your application shows or hides a window, the UIWindowDidBecomeVisibleNotification andUIWindowDidBecomeHiddenNotification notifications are delivered accordingly. These notifications are not delivered when your application moves into the background execution state. Even though your window is not displayed on the screen while your application is in the background, it is still considered visible within the context of your application.

    当应用程序的窗口发生程序性改变时,这些通知将被传递。因此,当你的应用程序显示或隐藏一个窗口,UIWindowDidBecomeVisibleNotification 和 UIWindowDidBecomeHiddenNotification 通知也被相应的传递。这些通知在应用程序转入后台执行状态时将不被传递。 尽管当应用程序在后台时,窗口没有在屏幕上显示,但是它在应用程序的上下文中任然被认为是可见的。

    The UIWindowDidBecomeKeyNotification and UIWindowDidResignKeyNotification notifications help your application keep track of which window is the key window—that is, which window is currently receiving keyboard events and other non touch-related events. Whereas touch events are delivered to the window in which the touch occurred, events that do not have an associated coordinate value are delivered to the key window of your application. Only one window at a time may be key.

    UIWindowDidBecomeKeyNotification 和 UIWindowDidResignKeyNotification 通知帮助应用程序持续监控哪个窗口是关键窗口---就是,当前哪个窗口能接收键盘事件以及其它非触摸相关事件。 无论触摸事件被传递到事件发生窗口的哪里,那些没有一个相应坐标值的事件都被传递到应用程序的关键窗口。同一时间只能有一个关键窗口。

    Displaying Content on an External Display

    四、在外部显示器上显示内容

    To display content on an external display, you must create an additional window for your application and associate it with the screen object representing the external display. New windows are normally associated with the main screen by default. Changing the window’s associated screen object causes the contents of that window to be rerouted to the corresponding display. Once the window is associated with the correct screen, you can add views to it and show it just like you do for your application’s main screen.

    要想在一个外部显示器上显示内容,你必须给应用程序创建一个额外的窗口,并跟代表外部显示器的屏幕对象想关联。新窗口正常情况下都默认跟主屏幕相关联。 改变窗口的相关联屏幕对象会导致该窗口的内容被重新路由到相应的显示器上。 一旦窗口跟正确的屏幕相关联,你就可以给它添加视图,并像应用程序的主屏幕那样显示它。

    The UIScreen class maintains a list of screen objects representing the available hardware displays. Normally, there is only one screen object representing the main display for any iOS-based device, but devices that support connecting to an external display can have an additional screen object available. Devices that support an external display include iPhone and iPod touch devices that have Retina displays and the iPad. Older devices, such as iPhone 3GS, do not support external displays.

    UIScreen 类维护了一个屏幕对象列表,它们代表各种可用的硬件显示器。正常情况下,任何基于iOS的设备只有一个屏幕对象代表主显示器,但是那些支持连接到一个外部显示器的设备能有一个额外的屏幕对象。 支持一个外部显示器的设备包括iPhone 和 有Retina显示屏的iPod touch设备 以及iPad. 老设备,比如iPhone 3GS ,不支持外部显示器。

    Note: Because external displays are essentially a video-out connection, you should not expect touch events for views and controls in a window that is associated with an external display. In addition, it is your application’s responsibility to update the contents of the window as needed. Thus, to mirror the contents of your main window, your application would need to create a duplicate set of views for the external display’s window and update them in tandem with the views in your main window.

     注意: 因为外部显示器基本上是一个视频连接,你不应该期待窗口内的视图和控制器的触摸事件和能跟一个外部显示器相关联。另外,根据需要更新窗口的内容是应用程序的责任。 因此,要想镜像主窗口里的内容,应用程序应该需要给外部显示器窗口创建一套视图的复制并跟主窗口里的视图一起更新它们。

    The process for displaying content on an external display is described in the following sections. However, the following steps summarize the basic process:

    在外部显示器上显示内容的过程在以下段里描述。然而,以下步骤只概述了基本过程:

    1. At application startup, register for the screen connection and disconnection notifications.

       在应用程序启动时,注册屏幕连接和断开连接通知。

    2. When it is time to display content on the external display, create and configure a window.

      当要在外部显示器里显示内容时,创建并配置一个窗口。 

      • Use the screens property of UIScreen to obtain the screen object for the external display.

         用UIScreen类的screens 属性来获取外部显示器的屏幕对象。

      • Create a UIWindow object and size it appropriately for the screen (or for your content).

         创建一个UIWindow 对象,并为屏幕(或为你的内容)定制合适的尺寸。

      • Assign the UIScreen object for the external display to the screen property of the window.

         把外部显示器的UIScreen对象分配(assign)给窗口的screen 属性。

      • Adjust the resolution of the screen object as needed to support your content.

         根据需要调整屏幕对象的分辨率来支持你的内容。

      • Add any appropriate views to the window.

         给窗口添加任何合适的视图。

    3. Show the window and update it normally.

       正常的显示和更新窗口。

    Handling Screen Connection and Disconnection Notifications

    1、处理屏幕的连接和断开连接通知

    Screen connection and disconnection notifications are crucial for handling changes to external displays gracefully. When the user connects or disconnects a display, the system sends appropriate notifications to your application. You should use these notifications to update your application state and create or release the window associated with the external display.

    屏幕的连接和断开通知对于优雅的处理外部显示器的变化时至关重要的。 当用户连接或断开一个显示器,系统给应用程序发送适当的通知。你应用使用这些通知来更新应用程序状态以及创建或释放跟外部显示器相关的窗口。

    The important thing to remember about the connection and disconnection notifications is that they can come at any time, even when your application is suspended in the background. Therefore, it is best to observe the notifications from an object that is going to exist for the duration of your application’s runtime, such as your application delegate. If your application is suspended, the notifications are queued until your application exits the suspended state and starts running in either the foreground or background.

    请记住:连接和断开通知可以在任何时候发送,即使是应用程序暂停在后台。因此,最好在应用程序整个运行期间都存在的对象里观察通知,比如应用程序的委托。 如果应用程序被暂停, 通知排队等待直到应用程序退出暂停状态并开始在前台或后台运行。

    Listing 2-1 shows the code used to register for connection and disconnection notifications. This method is called by the application delegate at initialization time but you could register for these notifications from other places in your application, too. The implementation of the handler methods is shown in Listing 2-2.

    列表 2-1 显示了注册连接和断开通知的代码。该方法被应用程序在初始化时调用,但是你也可以在应用程序的别的地方注册这些通知。 处理方法的实现显示在列表2-2中。

    Listing 2-1  Registering for screen connect and disconnect notifications

    列表 2-1 为屏幕注册连接和断开通知

    - (void)setupScreenConnectionNotificationHandlers
    {
        NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
     
        [center addObserver:self selector:@selector(handleScreenConnectNotification:)
                name:UIScreenDidConnectNotification object:nil];
        [center addObserver:self selector:@selector(handleScreenDisconnectNotification:)
                name:UIScreenDidDisconnectNotification object:nil];
    }
     

    If your application is active when an external display is attached to the device, it should create a second window for that display and fill it with some content. The content does not need to be the final content you want to present. For example, if your application is not ready to use the extra screen, it can use the second window to display some placeholder content. If you do not create a window for the screen, or if you create a window but do not show it, a black field is displayed on the external display.

    如果当一个外部显示器被连接到设备时,应用程序是活动的, 那么它应该创建第二个窗口来显示并装入一些内容。这些内容并不需要是你想要呈现的最终内容。比如,如果应用程序没准备好使用额外的屏幕,它可以使用该第二个窗口来显示一些占位内容。如果你没有为屏幕创建一个窗口,或如果你创建了一个窗口但没显示,在外部显示器上就会显示一个空白区域。

    Listing 2-2 shows how to create a secondary window and fill it with some content. In this example, the application creates the window in the handler methods it uses to receive screen connection notifications. (For information about registering for connection and disconnection notifications, see Listing 2-1.) The handler method for the connection notification creates a secondary window, associates it with the newly connected screen and calls a method of the application’s main view controller to add some content to the window and show it. The handler method for the disconnection notification releases the window and notifies the main view controller so that it can adjust its presentation accordingly.

    列表2-2 显示了如何创建第二个窗口并装入一个内容。 该例子中, 应用程序在用来接收屏幕连接通知的处理方法内创建该窗口。(关于注册连接和断开通知的信息,请看 Listing 2-1) 连接通知的处理方法创建了一个附加窗口, 让它跟新连接相关联,并调用应用程序主视图控制器的方法来添加一些内容到窗口,然后显示它。 断开通知的处理方法释放了窗口并通知主视图控制器,这样他就能相应的调整它的外观。

    Listing 2-2  Handling connect and disconnect notifications

    列表 2-2 处理连接和断开通知

    - (void)handleScreenConnectNotification:(NSNotification*)aNotification
    {
        UIScreen*    newScreen = [aNotification object];
        CGRect        screenBounds = newScreen.bounds;
     
        if (!_secondWindow)
        {
            _secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
            _secondWindow.screen = newScreen;
     
            // Set the initial UI for the window.
            [viewController displaySelectionInSecondaryWindow:_secondWindow];
        }
    }
     
    - (void)handleScreenDisconnectNotification:(NSNotification*)aNotification
    {
        if (_secondWindow)
        {
            // Hide and then delete the window.
            _secondWindow.hidden = YES;
            [_secondWindow release];
            _secondWindow = nil;
     
            // Update the main screen based on what is showing here.
            [viewController displaySelectionOnMainScreen];
        }
     
    }

    Configuring a Window for an External Display

    2、为外部显示器配置一个窗口

    To display a window on an external screen, you must associate it with the correct screen object. This process involves locating the proper UIScreen object and assigning it to the window’s screen property. You can get the list of screen objects from the screens class method of UIScreen. The array returned by this method always contains at least one object representing the main screen. If a second object is present, that object represents a connected external display.

    要想在外接显示器上显示一个窗口, 你必须把它关联到正确的屏幕对象。 该进程涉及到定位正确的UIScreen 对象,并把它分配给窗口的screen 属性。你可以用UIScreen类的screens类方法获取屏幕对象的列表。该方法返回的数字总是至少包含一个对象,该对象代表主屏幕。 如果存在第二个对像,该对象代表一个外接显示器的连接。

    Listing 2-3 shows a method that is called at application startup to see if an external display is already attached. If it is, the method creates a window, associates it with the external display, and adds some placeholder content before showing the window. In this case, the placeholder content is a white background and a label indicating that there is no content to display. To show the window, this method changes the value of its hidden property rather than callingmakeKeyAndVisible. It does this because the window contains only static content and is not used to handle events.

    列表2-3 显示了一个在应用程序启动时被调用的方法,该方法用来查看一个外接显示器是否已被连接。如果是,该方法创建一个跟外接显示器相关联的窗口,并在窗口显示之前添加一些占位内容。 在这种情况下,占位内容是一个白背景,以及一个表明没有任何可显示内容的标签。 要想显示该窗口,该方法改变它的hidden 属性值,而不是调用 makeKeyAndVisible 方法。 它决定这么做的原因是窗口只包含静态内容并不用它来处理任何事件。

    Listing 2-3  Configuring a window for an external display

    列表 2-3 为一个外接显示器配置一个窗口

    - (void)checkForExistingScreenAndInitializeIfPresent
    {
        if ([[UIScreen screens] count] > 1)
        {
            // Associate the window with the second screen.
            // The main screen is always at index 0.
            UIScreen*    secondScreen = [[UIScreen screens] objectAtIndex:1];
            CGRect        screenBounds = secondScreen.bounds;
     
            _secondWindow = [[UIWindow alloc] initWithFrame:screenBounds];
            _secondWindow.screen = secondScreen;
     
            // Add a white background to the window
            UIView*            whiteField = [[UIView alloc] initWithFrame:screenBounds];
            whiteField.backgroundColor = [UIColor whiteColor];
     
            [_secondWindow addSubview:whiteField];
            [whiteField release];
     
            // Center a label in the view.
            NSString*    noContentString = [NSString stringWithFormat:@"<no content>"];
            CGSize        stringSize = [noContentString sizeWithFont:[UIFont systemFontOfSize:18]];
     
            CGRect        labelSize = CGRectMake((screenBounds.size.width - stringSize.width) / 2.0,
                                        (screenBounds.size.height - stringSize.height) / 2.0,
                                        stringSize.width, stringSize.height);
     
            UILabel*    noContentLabel = [[UILabel alloc] initWithFrame:labelSize];
            noContentLabel.text = noContentString;
            noContentLabel.font = [UIFont systemFontOfSize:18];
            [whiteField addSubview:noContentLabel];
     
            // Go ahead and show the window.
            _secondWindow.hidden = NO;
        }
    }

    Important: You should always associate a screen with a window before showing the window. While it is possible to change screens for a window that is currently visible, doing so is an expensive operation and should be avoided.

     重要提示:你应该总是在显示窗口之前把一个屏幕关联到窗口。 但是当目前可见的一个窗口可能改变屏幕时,这样做是一个高损耗的操作,应该避免。

    As soon as the window for an external screen is displayed, your application can begin updating it like any other window. You can add and remove subviews as needed, change the contents of subviews, animate changes to the views, and invalidate their contents as needed.

    一旦一个外界屏幕的窗口被显示,应用程序就可以像更新任何别的窗口一样更新该窗口。 你可以根据需要添加和删除子视图, 改变子视图的内容,动画视图的变化,以及根据需要让它们的内容无效。

    Configuring the Screen Mode of an External Display

    3、配置外接显示器的屏幕模式

    Depending on your content, you might want to change the screen mode before associating your window with it. Many screens support multiple resolutions, some of which use different pixel aspect ratios. Screen objects use the most common screen mode by default, but you can change that mode to one that is more suitable for your content. For example, if you are implementing a game using OpenGL ES and your textures are designed for a 640 x 480 pixel screen, you might change the screen mode for screens with higher default resolutions.

    根据你的内容,你可能想在关联屏幕模式和窗口之前改变屏幕模式。 很多屏幕支持多种分辨率,其中一些使用不同的像素高宽比( pixel aspect ratios). 默认时,屏幕对象使用最常用的屏幕模式,但是你可以把它改成更适合你的内容的模式。 比如,如果你正使用OpenGL ES实现一个游戏,你的结构是为640x480像素屏幕而设计的,你可能将屏幕的模式改为更高的默认分辨率。

    If you plan to use a screen mode other than the default one, you should apply that mode to the UIScreen object before associating the screen with a window. The UIScreenMode class defines the attributes of a single screen mode. You can get a list of the modes supported by a screen from its availableModes property and iterate through the list for one that matches your needs.

    如果你计划使用一个屏幕模式,不是默认那个, 你应该在关联屏幕和窗口前给UIScreen对象应用那个模式。UIScreenMode 类定义了一个单一屏幕模式的各种属性。 你可以从屏幕的availableModes属性里获取屏幕支持的模式列表, 然后遍历该列表来选择符合你需要的模式。

    For more information about screen modes, see UIScreenMode Class Reference.

    关于屏幕模式的更多信息,请看UIScreenMode Class Reference.

  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/patientAndPersist/p/3169367.html
Copyright © 2020-2023  润新知