├── App-Programming-Guide-for-tvOS ├── Controlling_the_User_Interface_On_the_Screen_with_an_Apple_Remote.md ├── Creating_Parallax_Artwork.md ├── Creating_a_Client-Server_App.md ├── Designing_the_Keyboard_Input_Experience.md ├── Detecting_Gestures_and_Button_Presses.md ├── Document_Revision_History.md ├── On-Demand_Resources.md ├── The_New_Apple_TV.md ├── Working_with_Game_Controllers.md └── iCloud_Storage.md ├── LICENSE ├── README.md └── SUMMARY.md /App-Programming-Guide-for-tvOS/Controlling_the_User_Interface_On_the_Screen_with_an_Apple_Remote.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##操作用户界面 24 | 25 | iOS设备上,用户通过直接触摸屏幕进行交互。但是Apple TV只能通过遥控器间接进行操作。用户在屏幕上导航,并且通过遥控选取某个物体。当用户导航到一个物体时,它就会获取焦点。在基于焦点的交互模型中,如果一个视图可以获取焦点,则用户可以将焦点移动到屏幕上的其它物体上。这样会触发焦点更新动作。获取焦点的视图会被作为用户下一个动作的目标。例如,如果屏幕上的一个按钮已经获取焦点了,当遥控器上的选取事件发生时,按钮的动作会被触发。 26 | 27 | UIKit框架只支持基于焦点的界面,并且在大部分情况下这种行为是由系统默认提供的。我们在程序中也可以触发焦点移动,但是不能够指定它的移动方向。例如`UIButton`对象可以获取焦点,但是`UILabel`对象不行。当使用用户自定义控件的时候,我们需要实现自定义的焦点获取行为。这个在“[在应用内支持焦点](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/WorkingwiththeAppleTVRemote.html#//apple_ref/doc/uid/TP40015241-CH5-SW2)”章节可以看到。UIKit控件如`UIButton`、`UITextField`、`UITableView`、`UICollectionView`、`UITextView`、`UISegmentedControl`和`UISearchBar`等都默认可以获取焦点。 28 | 29 | ####使用焦点引擎控制焦点 30 | 31 | UIKit中通过一个叫“焦点引擎”的东西管理控件的焦点的获取和移动。用户有多重方式控制焦点:遥控器(不同种类的)、游戏控制器、模拟器等等。焦点引擎监听输入源的焦点事件。当一个事件发生时,焦点引擎自动决定是否应该更新和通知我们的应用。焦点系统帮助我们在不同应用之间提供统一的用户体验,自动为应用提供对所有输入方法的支持,而开发者只要专注于应用本身的功能,而不是定义和重新发明基本的导航事件。 32 | 33 | 只有焦点引擎能够显式的更新焦点,意味着系统并没有提供API来直接在某个方向操作和移动焦点。只有在用户发送移动事件、系统和应用请求更新的时候,焦点引擎才会更新焦点。更多关于焦点的更新,见[《Updating Focus Programmatically》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/WorkingwiththeAppleTVRemote.html#//apple_ref/doc/uid/TP40015241-CH5-SW14)。 34 | 35 | 焦点引擎的控制使得焦点不会全屏乱跑,并且在不同的应用之间提供统一的操作方式。这样做可以防止造成用户感到困惑,同时开发者不需要去自己管理焦点。 36 | 37 | ####`UIFocusEnvironment`协议 38 | 39 | 焦点引擎通过`UIFocusEnvironment`协议与应用进行通信,定义一组视图的焦点行为。UIKit中的一些类能够响应这个协议,如`UIView`、`UIViewController`、`UIWindow`和`UIPresentationController`等。重写`UIFocusEnvironment`方法可以让我们对程序的焦点行为进行控制。 40 | 41 | ####用户移动焦点 42 | 焦点引擎根据遥控器或者其它输入设备的导航事件自动决定焦点的移动。用户可以在二维平面上移动焦点:上、下、左、右还有斜向移动(需要硬件支持)。例如用户往左滑动,焦点引擎将在当前焦点视图的左侧尝试寻找一个可以获取焦点的控件。如果存在这样一个控件,则让它获取焦点,否则继续停留在当前视图上。 43 | 44 | 焦点引擎自动处理输入设备所支持的复杂行为。包括由快速滑动引起的动量运动,根据焦点速度调节动画快慢,播放导航音乐,移动到屏幕外导致滚动。了解更多焦点相关的动画,见[《UIFocusAnimationCoordinator Class Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIFocusAnimationCoordinator_Class/index.html#//apple_ref/doc/uid/TP40015427)。 45 | 46 | ####决定焦点的移动 47 | 48 | 当用户移动焦点的时候,焦点引擎首先给应用程序界面创建一个快照,然后将所有可见区域中可以获取焦点的视图高亮。这意味着如果一个视图如果完全被另外的视图覆盖的话,它将被忽略。而那些只是部分被覆盖的视图,也只会考虑它的可见区域。通过这种技术,焦点引擎从当前视图开始,查找运动路径上的所有可以获取焦点的区域。搜索区域的大小与当前焦点视图的大小直接相关。 49 | 50 | **图3-1 焦点运动** 51 | 52 | ![焦点运动](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/large_view_2x.png) 53 | 54 | 如果焦点引擎找到了一个可以接受焦点的视图,它会通过`shouldUpdateFocusInContext:`代理方法给应用提供一个评估是否移动焦点的机会。焦点引擎按前一个和下一个的顺序通知每个焦点环境(先通知前一个视图,然后下一个视图,最后通知它们的父视图)。只要有一个视图返回`NO`,这次移动就会被取消。更多关于焦点环境的信息,见[《UIFocusEnvironmentProtocol Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIFocusEnvironment_Protocol/index.html#//apple_ref/doc/uid/TP40015223)。 55 | 56 | ####初始化焦点和焦点移动链 57 | 程序启动时,焦点引擎默认选择一个起始视图。通常是最靠近屏幕左上角的一个可获取焦点的视图。 58 | 59 | **图3-2 初始焦点视图的查找顺序** 60 | 61 | ![](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/search_hierarchy_2x.png) 62 | 63 | 应用程序可以通过`UIFocusEnvironment`协议为默认的焦点视图的查找提供信息。设置初始焦点的时候,焦点引擎首先会向窗口请求优先获取焦点的视图。窗口将返回根视图控制器的`preferredFocusedView`。由于返回的是一个响应`UIFocusEnvironment`协议的`UIView`对象,因此焦点引擎会继续询问哪一个是需要优先获取焦点的视图。整个查找过程形成一条优先焦点视图的查找链。焦点引擎将最后那个视图作为默认的视图获取焦点(Next focused view)。 64 | 65 | 下面是焦点引擎查找的一个示例: 66 | 67 | 1. 焦点引擎询问窗口的`preferredFocusedView`,返回根视图控制器的`preferredFocusedView`。 68 | 2. 根视图控制器(Tab view controller)返回它的选择视图控制器的`preferredFocusedView`。 69 | 3. 选择视图控制器覆盖`preferredFocusedView`方法,返回某个特定的`UIButton`对象。 70 | 4. `UIButton`对象默认返回它自己,并且能够获取焦点的话,就会被焦点引擎选中问下一个焦点视图(获取焦点)。 71 | 72 | 当焦点更新到某个视图时,新的焦点视图被设置为该视图焦点查找链最深的视图。另外一个例子是:当一个视图控制器被作为模态视图弹出到当前焦点视图上时,焦点呗设置到新的视图控制器上。 73 | 74 | ####焦点更新 75 | 76 | 当用户移动焦点的时候(如滑动遥控器),应用程序会请求更新焦点或者系统触发一个自动的更新。 77 | 78 | ####焦点更新剖析 79 | 80 | 当焦点更新或者移动到一个新的视图时,决定是选择当前视图的子视图还是另外一个视图的条件。 81 | 82 | - `focusedView`属性被更新为新的焦点视图或者它的优先焦点视图。 83 | - 焦点引擎通过调用`didUpdateFocusInContext:withAnimationCoordinator:`通知包含前一个焦点视图和下一个焦点视图的所有焦点环境,然后使用动画协调器调度焦点相关的动画。见[《UIFocusAnimationCoordinator》](https://developer.apple.com/library/prerelease/tvos/documentation/UIKit/Reference/UIFocusAnimationCoordinator_Class/index.html#//apple_ref/occ/cl/UIFocusAnimationCoordinator)。 84 | - 通知所有相关的焦点环境后,所有被协调的动画都同时执行。 85 | - 如果下一个焦点视图在一个滚动视图里,并且处于屏幕外面,滚动视图将会通过滚动内容使下一个焦点视图移动到屏幕上。 86 | 87 | ####系统产生的焦点更新动作 88 | 89 | 在许多环境下,必要的时候UIKit会自动更新焦点。下面是焦点自动更新的一些示例: 90 | 91 | - 焦点视图被移除。 92 | - `UITableView`或`UICollectionView`重新加载数据。 93 | - 弹出一个新的视图控制器。 94 | - 用户按**Menu**按钮返回。 95 | 96 | ####程序更新焦点 97 | 98 | 虽然大部分情况下,焦点会自动更新,但是在一些情况下我们还是需要在代码里改变焦点。焦点环境可以通过调用`setNeedsFocusUpdate`请求更新焦点。下面是几个通过程序更新焦点的例子: 99 | 100 | - 应用程序的内容发生改变,需要将焦点放置到用户关心的内容上。例如:音乐应用总是将焦点放置在当前正在播放的歌曲上。当一首歌结束的时候,应用程序应该将焦点更新到播放列表的下一曲上。 101 | - 用户了一个操作,需要将焦点移动到他所关注的内容上。例如:一个左侧显示菜单、右侧显示内容的分屏应用。用户移动左边的菜单项时,右边的内容会对应的发生改变。当用户选择一个菜单项,他们期望右边的内容会自动选中第一项。 102 | - 当一个自定义控件获取焦点的时候,需要按一定规则更新它内部的状态。例如:一个拾取器控件允许用户选中它。当用户使用遥控选中这个控件的时候,焦点被移动到这个控件内,让用户可以选择其中一个选项。点击遥控上的**Menu**按钮可以让控件再次获取焦点。在这种场景下,选中该控件会请求更新焦点,通过`preferredFocusedView`将焦点移动到其中一个子视图上。 103 | 104 | ####在应用中支持焦点 105 | 106 | 应用中的UIKit控件会自动支持焦点的管理。然而大多数应用中,我们都需要实现自定义焦点行为,例如当焦点改变的时候更新焦点状态、创建新的交互元素和执行自定义焦点动画。下面的章节介绍了关于自定义焦点行为的内容。 107 | 108 | `UIFocusEnvironment`控制视图结构与焦点相关的行为。这意味着`UIViewController`控制它的根视图和子视图的焦点相关行为,而`UIView`控制它本身与子视图的焦点行为。因此多个焦点环境可以控制同一个视图结构的焦点相关的行为——视图相互包含,并且都在同一个视图控制器中。控制视图相关的行为并不代表它就获取到了焦点。只是说明这个焦点环境能够控制焦点在它的视图结构中的移动方式,以及UI如何处理该结构中焦点的改变。 109 | 110 | ####在视图控制器中支持焦点 111 | 112 | 因为`UIViewController`响应`UIFocusEnvironment`,自定义视图控制器可以覆盖`UIFocusEnvironment`中的代理方法来实现自定义焦点行为。自定义视图控制器: 113 | 114 | - 覆盖`preferredFocusedView`来明确焦点默认从哪里开始。 115 | - 覆盖`shouldUpdateFocusInContext:`定义焦点如何移动。 116 | - 覆盖`didUpdateFocusInContext:withAnimationCoordinator:`响应焦点的更新时机并且改变应用的状态。 117 | 118 | 视图控制器可以通过调用`setNeedsFocusUpdate`请求焦点引擎来重置焦点到当前的`preferredFocusedView`上。注意,只有当该视图控制器包含一个已经获取焦点的视图时,`setNeedsFocusUpdate`才会起作用。 119 | 120 | ####在CollectionView和TableView中支持焦点 121 | 122 | 使用集合视图和表视图时,我们通过代理对象自定义焦点行为。这个模式同时也用于基于焦点的界面的实现。`UITableViewDelegate`和`UICollectionViewDelegate`协议定义了`UIFocusEnvironment`协议中相同的方法,但是只能给表视图和集合视图使用。 123 | 124 | 在集合视图和表视图中支持焦点的技巧: 125 | 126 | - 使用`UICollectionViewDelegate`中的`collectionView:canFocusItemAtIndexPath:`或者`UITableViewDelegate`中的`tableView:canFocusRowAtIndexPath:`方法表明一个Cell是否可以获取焦点。这与在自定义视图中重写`canBecomeFocused`方法的作用一样。 127 | - 使用`UICollectionView`和`UITableView`中的`remembersLastFocusedIndexPath`属性表示离开焦点离开后,再次获取焦点时是否应该停留在最后一次的位置。 128 | 129 | ####在自定义视图中支持焦点 130 | 131 | `UIViewController`、`UIView`都实现了`UIFocusEnvironment`协议,因此所有在**[在视图控制器中支持焦点](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/WorkingwiththeAppleTVRemote.html#//apple_ref/doc/uid/TP40015241-CH5-SW1)**提到的都可以在自定义视图中使用。因为视图能够获取焦点,所以实现自定义视图的焦点行为时,还需要考虑一些额外的东西: 132 | 133 | - 如果自定义视图需要能够获取焦点,重写`canBecomeFocused`方法,并返回`YES`(默认返回`NO`)。视图可以是一直都能够获取焦点或者只能在一些条件下获取焦点。例如`UIButton`在禁用状态是不能获取焦点的。 134 | - 如果一个视图需要将焦点重定向到领悟一个焦点(例如子视图),需要重写`preferredFocusedView`。 135 | - 重写`didUpdateFocusInContext:withAnimationCoordinator:`响应焦点改变事件,并更新程序状态。 136 | 137 | ####焦点相关动画 138 | 139 | 当焦点发生改变的时候,获取焦点的视图执行动画,而前一个视图动画进入无焦点状态。与应用中的其它动画不一样的是,UIKit会调整焦点动画的时长和动画曲线来达到某种系统级的行为。例如,当焦点快速移动的时候,动画的时长会虽用户的移动而加速。 140 | 141 | UIKit为支持焦点的视图类提供了系统定义的焦点动画。使用UIKit的内置类`UIFocusAnimationCoordinator`和`addCoordinatedAniamtions:completion:`方法可以为系统定义的行为创建动画。 142 | 143 | 添加到协调器的动画可以在获取焦点或者失去焦点的时候运行(不是同时),这取决于提供给协调器的焦点环境。获取焦点的视图和失去焦点的视图共同的父视图或者焦点获取视图的父视图,在焦点动画执行时,运行自己的动画。而失焦视图的父视图在失去焦点的时候执行动画。 144 | 145 | **图 3-3** 自定义焦点动画 146 | 147 | ![自定义焦点动画](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/animation_chart_2x.png) 148 | 149 | 视图在获取焦点或者失去焦点的时候一般拥有不同的动画。我们可以通过重写视图的`didUpdateFocusInContext:withAnimationCoordinator:`方法并且检查`context`来指定动画的类型。下面是重写`didUpdateFocusInContext:withAnimationCoordinator:`的例子。 150 | 151 | ```objc 152 | - (void)didUpdateFocusInContext:(UIFocusUpdateContext *)context withAnimationCoordinator:(UIFocusAnimationCoordinator *)coordinator 153 | { 154 | [super didUpdateFocusInContext:context withAnimationCoordinator:coordinator]; 155 | 156 | if (self == context.nextFocusedView) { 157 | [coordinator addCoordinatedAnimations:^{ 158 | // focusing animations 159 | } completion:^{ 160 | // completion 161 | }]; 162 | } else if (self == context.previouslyFocusedView) { 163 | [coordinator addCoordinatedAnimations:^{ 164 | // unfocusing animations 165 | } completion:^{ 166 | // completion 167 | }]; 168 | } 169 | } 170 | ``` 171 | 172 | 焦点视图和失焦视图的共同父视图有时需要同时执行动画。例如焦点在一个`UICollectionView`的Cell间移动的时候。这种情况下,推荐的方法是继承`UICollectionViewCell`并且在子类中使用上面的代码片段实现动画。 173 | 174 | ####调试焦点问题 175 | 176 | UIKit在应用运行的时候会帮助我们调试焦点的问题。 177 | 178 | ####为什么视图不能获取焦点? 179 | 180 | 有许多原因会导致视图不能获取焦点,下面列举了一些例子(但不是全部): 181 | 182 | - 视图的`canBecomeFocused`方法返回`NO`。 183 | - 视图的`hidden`属性被设置为`YES`。 184 | - 视图的`alpha`属性被设置为`0`。 185 | - 视图被设置为不能接受用户交互。 186 | - 视图被其它视图覆盖。 187 | 188 | UIKit为`UIView`提供了一个隐藏的方法`_whyIsThisViewNotFocusable`来帮助测试上面提到的几种情况。这个方法只在调试器中有用,并且会将可能的原因打印出来。 189 | 190 | ```bash 191 | (lldb) po [(UIView *)0x148db5234 _whyIsThisViewNotFocusable] 192 | ISSUE: This view has userInteractionEnabled set to NO. Views must allow user interaction to be focusable. 193 | ISSUE: This view returns NO from -canBecomeFocused. 194 | (lldb) po [(UIView *)0x14b644d70 _whyIsThisViewNotFocusable] 195 | ISSUE: One or more ancestors are not eligible for focus, preventing this view from being focusable. Details: 196 | 197 | : 198 | ISSUE: This view has userInteractionEnabled set to NO. Views must allow user interaction to be focusable. 199 | ``` 200 | 201 | ####为什么焦点没有移动到想要的地方? 202 | 203 | 有时焦点并没有移动到我们想要的地方,或者根本就不移动。焦点引擎给我们提供了许多的方便,但是有时还是需要给它更多的信息来帮助它进行决策。 204 | 205 | UIKit在`UIFocusUpdateContext`对象中给焦点引擎发送一个如何搜索下一个焦点视图的可视化表示。可以通过在`shouldUpdateFocusInContext:`或者`didUpdateFocusInContext:withAnimationCoordinator:`中设置断点查看这个图像。当执行到这些断点的时候,可以在调试器的`context`参数,并且打开**Quick Look**。 206 | 207 | **图 3-4** 在调试器中选取`context`参数 208 | 209 | ![在调试器中选取context参数](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/ContextParameter_2x.png) 210 | 211 | 如果是在一次用户操作中执行到断点(不是通过代码更新焦点),**Quick Look**显示一个搜索路径的图片来表示焦点引擎的搜索步骤。见**图 3-5**。 212 | 213 | **图 3-5** Quick Look示意图 214 | 215 | ![](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/QuickLookPresentationOfImage_2x.png) 216 | 217 | 这里是**Quick Look**图片传递的一些信息。 218 | 219 | - 前一个焦点视图(搜索的起点),红色。 220 | - 搜索路径,用红色点线表示。 221 | - 搜索路径上的所有可以获取焦点的`UIView`区域,用不同深度的紫色表示。 222 | - 搜索路径上所有可以获取焦点的`UIFocusGuide`区域用不同深度的蓝色表示。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Creating_Parallax_Artwork.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | ##创建视差插图 26 | 27 | 应用程序图标必须使用分层图片,而其它可以获取焦点的UI控件可以选择性使用分层图片。如果我们的界面使用UIKit视图和焦点API。当这些控件获取焦点的时候,自动读取合适的图层并生成视差效果。可以获取焦点的UI控件需要包含一个分层的图片。 28 | 29 | UIKit在运行时支持两种不同的包含分层数据的格式。它能够从一个新的分层格式(**.lsr**)图片或者资源目录下读取分层图片。系统中支持其它图片格式的地方都支持分层图片格式文件。例如游戏中心的成就图片就是使用的分层图片。可以使用Xcode或者Parallax Previewer应用创建**.lsr**文件。 30 | 31 | ##使用视差预览应用创建LSR图片 32 | 33 | [下载](https://developer.apple.com/tvos/download/)Parallax Previewer创建和预览**.lsr**图片。图7-1展示了Parallax Previewer的使用情况。它由如下几部分组成: 34 | 35 | 1. 分层图片区。包含每个分层的组成图片。 36 | 2. 预览区,包含和显示图层。 37 | 3. 视图尺寸,用于改变图片的查看尺寸。 38 | 4. 位置区,调整所选中的图层的位置。 39 | 5. 添加和删除图层。 40 | 6. 尺寸区,调整选中的图层尺寸。 41 | 7. 播放按钮,显示图片的视差效果。 42 | 8. Apple TV图标选择框,勾选给Apple TV的图标添加阴影效果。 43 | 9. 背景,点击改变视图区的背景。 44 | 45 | 图7-1 Parallax Previewer 46 | 47 | ![](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/ParallaxPreviewer_2x_2x.png) 48 | 49 | **.lsr**图片的创建流程: 50 | 51 | 1. 为每个图层导入单独的**.png**或者**.jpeg**文件。 52 | 2. 调整图层的尺寸和位置。 53 | 3. 点击**File > Export > LSR**创建新的LSR文件。 54 | 55 | ##使用Xcode创建LSR图片 56 | 57 | 将**.png**图片拖入应用程序的Assets.xcassets中,创建一个图片栈(Apple TV Image Stack)。每个**.png**代表视差图片中的一个图层。点击属性区的**Export**按钮导出图片。图7-2显示了一个应用程序图标。 58 | 59 | 图7-2 XCode创建视差图片 60 | 61 | ![](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/xcodeimages_2x.png) 62 | 63 | 将已有的**.lsr**文件直接拖入应用的资源目录就可以将它包含到应用程序中。当应用程序编译打包后,**.lsr**图片会被包含到**.car**文件中。 64 | 65 | ##创建LCR图片 66 | 67 | Xcode使用**.lsr**文件或者资源目录包含视差图片。这些文件在处理后被包含在应用程序里。如果我们想要加载一个没有存放在应用程序中的图片(或者按需加在资源)。需要将这些图片处理成**.lcr**格式的文件。使用`layerutil`命令可以创建**.lcr**图片。`layerutil`工具将**.lsr**文件转化为**.lcr**文件。 68 | 69 | 打开终端,并且使用如下命令创建**.lcr**图片。 70 | 71 | 表7-1 `layerutil`命令创建**.lcr**图片。 72 | 73 | ```bash 74 | xcrun —-sdk appletvos layerutil —-c 75 | ``` 76 | 77 | 创建的**.lcr**图片与LSR文件同名。我们可以使用`--o `选项给**.lcr**文件命名。 78 | 79 | ##使用视差图片 80 | 81 | 应用视差图片的步骤: 82 | 83 | - 创建`UIImage`对象。 84 | - 根据图片的位置选用不同的加载方式。 85 | 1. Bundle——使用`imageNamed:`加载。 86 | 2. 下载的文件——使用`imageWithContentsOfFile:`加载。 87 | - 使用加载的图片创建`UIImageView`对象。 88 | - 如果一个`UIImageView`是另外一个视图的一部分,需要将它的`adjustsImageWhenAncestorFocused`属性设为`YES`。 89 | 90 | 当视图获取焦点后,视差图片将会正确显示。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Creating_a_Client-Server_App.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##创建一个C/S应用 24 | 25 | 与其它类型的应用稍有不同,C/S应用是使用JavaScript和TVML开发的。Xcode应用的主要功能是访问主JavaScript文件和将从TVML文件创建的页面展示到屏幕上。图2-1展示了C/S模型。 26 | 27 | **图2-1** C/S模型 28 | ![C/S模型](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/flow_diagram_2x.png) 29 | 30 | 我们的JavaScript文件将TVML页面加载到内存并且压入导航栈中。当用户在应用中导航时,TVML页面会被出栈入栈。当用户关闭应用后,Apple TV显示主屏幕。图2-2显示了基本的工作流程。 31 | 32 | **图2-2**C/S应用工作流程 33 | ![C/S应用工作流程](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/flow_diagram2_2x.png) 34 | 35 | 创建C/S应用的步骤: 36 | 1 . 打开Xcode并且创建项目。 37 | 2 . 选择tvOS的**Single View Application**模版。 38 | 3 . 删除View Controller文件和Storyboard。 39 | 4 . 打开**info.plist**并且删除**Main storyboard**入口。 40 | 41 | >设置网络安全,见[《App Transport Security Technote》](https://developer.apple.com/library/prerelease/tvos/technotes/App-Transport-Security-Technote/index.html#//apple_ref/doc/uid/TP40016240)。 42 | 43 | 5. 修改**AppDelegate.swift**文件: 44 | 45 | - 添加`import TVMLKit`。 46 | - 将类的声明修改为`class AppDelegate: UIResponder, UIApplicationDelegate, TVApplicationControllerDelegate {`。 47 | - 添加变量:`var appController: TVApplicationController?`。 48 | - 修改`application:didFinishLaunchingWithOptions:`方法: 49 | 50 | ```swift 51 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 52 | self.window = UIWindow(frame:UIScreen.mainScreen().bounds) 53 | 54 | let appControllerContext = TVApplicationControllerContext() 55 | 56 | let javascriptURL = NSURL(string: String("JavaScript文件路径")) 57 | 58 | appControllerContext.javaScriptApplicationURL = javascriptURL! 59 | if let options = launchOptions 60 | { 61 | for (kind, value) in options 62 | { 63 | if let kindStr = kind as? String 64 | { 65 | appControllerContext.launchOptions[kindStr] = value 66 | } 67 | } 68 | } 69 | 70 | self.appController = TVApplicationController(context: appControllerContext, window: self.window, delegate: self) 71 | 72 | return true 73 | } 74 | ``` 75 | 76 | 6 . 第一个例子中的代码会将一个TVML页面加载并显示到模拟器或者电视机屏幕上(Apple TV连在电脑上)。更多关于JavaScript类的信息,见[《TVJS Framework Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/TVMLJS/Reference/TVJSFrameworkReference/index.html#//apple_ref/doc/uid/TP40016076)。 77 | 78 | ```js 79 | function getDocument(url) { 80 | var templateXHR = new XMLHttpRequest(); 81 | templateXHR.responseType = "document"; 82 | templateXHR.addEventListener("load", function() {pushDoc(templateXHR.responseXML);}, false); 83 | templateXHR.open("GET", url, true); 84 | templateXHR.send(); 85 | return templateXHR; 86 | } 87 | 88 | function pushDoc(document) { 89 | navigationDocument.pushDocument(document); 90 | } 91 | 92 | App.onLaunch = function(options) { 93 | var templateURL = 'Enter path to your server here/alertTemplate.tvml'; 94 | getDocument(templateURL); 95 | } 96 | 97 | App.onExit = function() { 98 | console.log('App finished'); 99 | } 100 | ``` 101 | 上面的JavaScript加载了一个显示警告的TVML页面,询问用户是否需要将应用升级为高级版本(增值版本)。下面是警告模版的代码。更多关于TVML的信息,见[《Apple TV Markup Language Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/LanguagesUtilities/Conceptual/ATV_Template_Guide/index.html#//apple_ref/doc/uid/TP40015064)。[中文版](https://github.com/DiveinEdu/Apple-TV-Markup-Language-Reference-in-Chinese) 102 | 103 | ```xml 104 | 105 | 106 | Update to premium 107 | Go add free by updating to the premium version 108 | 111 | 114 | 115 | 116 | ``` -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Designing_the_Keyboard_Input_Experience.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | ##设计键盘输入体验 26 | 27 | 由于没有硬件键盘,Apple TV上的键盘输入会比较困难。我们需要花费更多的时间来确保一个愉快的用户体验。如果可以的话,尽量设计自己的UI不要过多的输入文字。Apple TV有两种类型的键盘:正常类型和内嵌类型。 28 | 29 | ##键盘输入 30 | 31 | 使用`UIAlertController`和`UITextField`创建自定义键盘和定制键盘输入体验,如E-Mail键盘和数字键盘。`UIAlertController`和`UITextField`的所有可用选项都包含在`UIKit/UITextInputTrailts.h`中。`inputAccessoryView`和`inputAccessoryViewController`允许我们自定义键盘。 32 | 33 | ##使用UIAlertController 34 | 35 | 键盘的UI完全由UIKit控制,但是通过使用`UIAlertController`可用添加一些按钮和文本输入框。我们可以在键盘的上方放置一些标题和说明文字。这种键盘会更加好用。但是用户还是不得不在遥控上点击多次。 36 | 37 | ##使用UITextField 38 | 39 | 使用`UITextField`可以在屏幕上放置一个全屏的键盘。用户通过`Next`和`Previous`按钮在文本框之间移动。这样用户就不需要总是重复移动焦点、点击的操作。在所有文本框都被填好后会出现一个“完成”(Done)按钮,让用户返回前一个页面。开发者可以将键盘放置在任何位置,它们都能接受前进/后退的操作。但是这个键盘的使用比`UIAlertController`要复杂,因为我们需要创建所有的视图,并且将它们放置在合适的位置。 40 | 41 | ##高级UITextField键盘 42 | 43 | iOS上的第一响应者机制在tvOS上都能起作用。这个机制允许用户显示和隐藏一个界面,并且通过调用`becomeFirstResponder`方法让其中一个文本框称为第一响应者。成为第一响应者会自动弹出键盘界面,而不需要用户导航到文本框进行点击。当用户从键盘退出或者点击“完成”按钮时,通过第一响应者的回调函数获取不再接收键盘输入的文本框。 44 | 45 | ##内嵌UITextField输入 46 | 47 | 行内键盘在同一行内显示所有可能的输入结果。使用`UISearchController`创建一个可以和第三方内容完成整合的键盘。使用`UISearchController`的时候,还是有很少的自定义选项需要设置。我们不能再访问输入框本身、自定义输入特性以及添加附加的输入组件。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Detecting_Gestures_and_Button_Presses.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | 大多数UIKit的视图都会对用户的操作做出合适的反应,比如当用户在遥控上点击一个按钮,或者在触摸板上操作手势时。这跟iOS上的触摸事件一样。按钮点击事件在响应链上进行处理。`UIGestureRecognizer`和`UIResponder`类增加了新的方法来处理遥控上的按钮点击和释放。另外,Siri遥控的触摸板还支持拖动和滑动手势。 26 | 27 | ##使用手势识别器 28 | 29 | 点击手势识别器能够用来检测按钮的点击。默认情况下点击手势由**Select**按钮触发。`allowedPressTypes`属性能够指定触发某个手势的按钮类型。 30 | 31 | **表 4-1** 创建一个由**Play/Pause**按钮出发的手势识别器 32 | 33 | **表 4-1** 检测**Play/Pause**按钮(Swift/Objective-C) 34 | 35 | ```swift 36 | let tapRecognizer = UITapGestureRecognizer(target: self, action:"tapped:") 37 | tapRecognizer.allowedPressTypes = [NSNumber(integer: UIPressType.PlayPause.rawValue)]; 38 | self.view.addGestureRecognizer(tapRecognizer) 39 | ``` 40 | 41 | ```objc 42 | UITapRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self, action:@selector(tapped:)]; 43 | tapRecognizer.allowedPressTypes = @[@(UIPresstypePlayPause)]; 44 | [self.view addGestureRecognizer:tapRecognizer]; 45 | ``` 46 | 47 | 与此类似,滑动识别器和拖动识别器也可以用来检测遥控器触摸板上的事件。**表 4-2**演示了如何检测从左到右的滑动手势。 48 | 49 | **表 4-2** 检测滑动手势 50 | 51 | ```swift 52 | let swipeRecognizer = UISwipeGestureRecognizer(target: self, action:"swiped:") 53 | swipeRecognizer.direction = .Right 54 | self.view.addGestureRecognizer(swipeRecognizer) 55 | ``` 56 | 57 | ```objc 58 | UISwipeRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] addTarget:self, action:@selector(swiped:)]; 59 | swipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight; 60 | [self.view addGestureRecognizer: swipeRecognizer]; 61 | ``` 62 | 63 | ##底层事件处理 64 | 65 | tvOS使用`UIPress`对象替换`UITouch`来提供遥控器和其它输入设备的事件。`UIPress`对象描述了按钮对象以及它当前的状态。对于模拟按键,`UIPress`对象还会提供压力信息。`UIPress`对象使用`type`属性标识状态发生改变的物理按键,其它属性表示发生了哪些改变。 66 | 67 | `UIGestureRecognizer`和`UIResponder`对象能够实现一些可以在触发按钮事件时被调用的方法。这些方法会接收到一个描述该事件的`UIPressesEvent`对象和一组状态发生改变的按钮。**表 4-3**显示了一个视图控制器如何为一个选择事件实现底层处理。和触摸事件的处理一样,如果我们需要处理按钮事件,就需要实现所有的四个按钮处理方法。 68 | 69 | ```swift 70 | override func pressesBegan(presses: Set, withEvent event: UIPressesEvent?) { 71 | for item in presses { 72 | if item.type == .Select { 73 | self.view.backgroundColor = UIColor.greenColor() 74 | } 75 | } 76 | } 77 | 78 | override func pressesEnded(presses: Set, withEvent event: UIPressesEvent?) { 79 | for item in presses { 80 | if item.type == .Select { 81 | self.view.backgroundColor = UIColor.whiteColor() 82 | } 83 | } 84 | } 85 | 86 | override func pressesChanged(presses: Set, withEvent event: UIPressesEvent?) { 87 | // ignored 88 | } 89 | 90 | override func pressesCancelled(presses: Set, withEvent event: UIPressesEvent?) { 91 | for item in presses { 92 | if item.type == .Select { 93 | self.view.backgroundColor = UIColor.whiteColor() 94 | } 95 | } 96 | } 97 | ``` 98 | 99 | ```objc 100 | - (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event { 101 | for(UIPress *item in presses) { 102 | if(item.type == UIPressTypeSelect) { 103 | self.view.backgroundColor = UIColor.greenColor() 104 | } 105 | } 106 | } 107 | 108 | - (void)pressesEnded:(NSSet *)presses 109 | withEvent:(UIPressesEvent *)event { 110 | for(UIPress *item in presses) { 111 | if (item.type == UIPressTypeSelect) { 112 | self.view.backgroundColor = UIColor.whiteColor() 113 | } 114 | } 115 | } 116 | 117 | override func pressesChanged(presses: Set, withEvent event: UIPressesEvent?) { 118 | // ignored 119 | } 120 | 121 | - (void)pressesChanged:(NSSet *)presses 122 | withEvent:(UIPressesEvent *)event { 123 | for (UIPress *item in presses) { 124 | if (item.type == UIPressTypeSelect) { 125 | self.view.backgroundColor = UIColor.whiteColor() 126 | } 127 | } 128 | } 129 | ``` -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Document_Revision_History.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | ####文档版本历史 26 | 27 | 下表包含了**App Programming Guide for tvOS**的修改信息。 28 | 29 | |日期|记录| 30 | |-|-| 31 | |2015-09-22|新的文档描述如何编写Apple TV应用程序| -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/On-Demand_Resources.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | 按需加载资源是指应用程序的内容被托管在App Store,而不是存放在我们下载的应用程序包中。它们能够缩减应用程序包的大小、加快下载和丰富程序内容。应用程序请求一组按需加载的资源,操作系统负责管理下载和存储过程。应用程序使用资源,然后释放请求。在下载完成后,这些资源会在设备上存储多个启动周期,从而加快访问速度。 26 | 27 | 每个存储在Apple TV上的应用程序大小都被限制在200MB以内。为了创建一个大于这个数目的应用,我们必须将应用拆分为多个可下载的包。在Xcode中创建标签并将它们附加到必须的资源上。当我们的应用请求附加了标签的资源后,操作系统会自动下载请求的数据。我们必须等待下载完成后才能在应用中使用。 28 | 29 | 这些资源集被分为可以管理的组。比如我们将游戏第五关的资源放到一个标签下。确保在下载资源的时候要给用户UI上的提示。测试我们的应用,来找到合适的可以下载文件大小。更多关于按需请求资源,见“[On-Demand Resources Guide](https://developer.apple.com/library/prerelease/tvos/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/index.html#//apple_ref/doc/uid/TP40015083)”。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/The_New_Apple_TV.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##新的Apple TV 24 | 25 | 新的Apple TV不再只是一个单调的媒体播放器。它能够用来玩游戏、使用生产力工具、看电影和分享体验等。所有这些都给开发者提供了更多的机会。 26 | 27 | 新的Apple TV使用**最新的iOS**框架和一些**tvOS**特有的框架。Apple TV应用开发与iOS开发非常类似,但是还有一些诸如共享的多人体验是iOS设备所不具备的。该文档描述了Apple TV特有的能力,并且提供了关于开发tvOS应用的更多信息的链接。 28 | 29 | >Apple TV开发与发布需要一个新的开发者证书。我们可以通过类似创建iOS证书的方式获取。 30 | 31 | ####Apple TV的硬件信息 32 | 新的Apple TV硬件规格: 33 | 34 | - 64位A8处理器 35 | - 32GB或64GB存储空间 36 | - 2GB内存 37 | - 10/100Mbps以太网口 38 | - WiFi支持802.11a/b/g/n/ac 39 | - 1080p高清视频 40 | - HDMI 41 | - 新的Siri遥控/Apple TV遥控 42 | 43 | Apple TV遥控有两个特点——内置Siri和屏幕搜索功能。其中Siri遥控在以下国家可用: 44 | 45 | - 澳大利亚 46 | - 加拿大 47 | - 法国 48 | - 德国 49 | - 日本 50 | - 西班牙 51 | - 英国 52 | - 美国 53 | 54 | 其它国家的Apple TV提供的是Apple TV遥控。图1-1是新的遥控器。它有一下一些按钮: 55 | 56 | 1. 触摸板。滑动导航、点击选取、长按弹出上下文菜单。 57 | 2. 菜单按钮。点击返回上一层。 58 | 3. Siri/Search按钮。在支持Siri的国家,长按启动Siri遥控。在其它国家长按打开屏幕搜索。 59 | 4. Play/Pause按钮。播放和暂停多媒体。 60 | 5. Home按钮。按一次返回主屏幕,按两次显示已经启动的应用。长按进入休眠状态。 61 | 6. Volume按钮。控制电视机的音量。 62 | 7. 闪电接口(Lightning connector)。充电插头。 63 | 64 | **图1-1** Siri遥控和Apple TV遥控 65 | 66 | ![Siri遥控](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/remote_callouts_2x.png) 67 | 68 | ####客户端-服务器(C/S)应用 69 | 70 | 创建Apple TV的过程与创建iOS应用相同。我们可以创建游戏、工具、多媒体等应用。同时可以创建贯穿多个应用,拥有自定义用户界面的C/S应用。我们使用Web技术来构建C/S应用,例如HTTPS、XMLHTTPRequest、DOM以及JavaScript。通过苹果自定义的标记语言TVML创建用户界面,然后使用JavaScript实现应用的行为。TVMLKit框架在本地代码和JavaScript/TMVL之间起到桥梁的作用。 71 | 72 | 应用程序的初始化启动行为在一个JavaScript文件中进行定义。我们像往常一样创建二进制应用,并且使用TVMLKit框架加载JavaScript文件。JavaScript文件加载TVML页面并将它们显示在屏幕上。每个TVML文件表示屏幕上一个单独的页面。我们可以使用苹果提供的模版创建TVML页面。每个模版通过全屏方式展示信息。模版上的元素可以进行修改。关于TVML模版和元素的更多信息可以查看[《Apple TV Markup Language Reference》](https://github.com/DiveinEdu/Apple-TV-Markup-Language-Reference-in-Chinese)。 73 | 74 | Apple TV上所有的视频都是通过HTTP Live Streaming和FairPlay Streaming提供。详情可以查看[《About HTTP Live Streaming》](https://developer.apple.com/library/prerelease/tvos/referencelibrary/GettingStarted/AboutHTTPLiveStreaming/about/about.html#//apple_ref/doc/uid/TP40013978)和[《FairPlay Streaming Overview》](https://developer.apple.com/library/prerelease/tvos/featuredarticles/FairPlayStreaming_Overview/FPS/FPS.html#//apple_ref/doc/uid/TP40015216)。 75 | 76 | ####顶层 77 | 78 | 用户可以将任何Apple TV的应用放置在应用菜单的最上一行,最多五个应用图标。当用户选择其中一个的时候,屏幕上方就会显示这个应用相关的内容。我们把这里叫做“Top shelf”。顶层可以展示应用内容让用户可以进行预览,或者直接跳转到应用的某个位置。 79 | 80 | ####视差图片 81 | 82 | 分层的图片能够让封面图变得更加生动。当一个界面元素被用户选中高亮,但是还没有点击的时候,能够获取焦点。这时分层图片会随着用户在遥控器触摸板上的动作旋转。每层图片的旋转速度会有细微的差别,从而产生视差效果。这些细微的效果让用户的注意力更加集中。 83 | 84 | 我们的视差图片当然是由设计师创建的,但是如何将它们运用到应用中呢?`UIImageView`被改造成可以支持视差图片,因此大多数情况下我们只要对代码进行微调就可以了。整个工作流如何改变取决于我们是直接将图片添加到应用内还是从服务器动态加载。 85 | 86 | ####新的tvOS框架 87 | 88 | Apple tvOS引入了一下几个特有的框架。 89 | 90 | - TVMLJS。描述了C/S应用中用来加载TVML页面的JavaScript接口。见[《TVJS Framework Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/TVMLJS/Reference/TVJSFrameworkReference/index.html#//apple_ref/doc/uid/TP40016076)。 91 | - TVMLKit。提供一种整合JavaScript和TVML的方法。见[《TVMLKit Framework Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/TVMLKit/Reference/TVMLKit_Collection/index.html#//apple_ref/doc/uid/TP40016429)。 92 | - TVServices。描述了如何为应用添加顶部扩展[《TVServices Framework Reference》](https://developer.apple.com/library/prerelease/tvos/documentation/TVServices/Reference/TVServices_Ref/index.html#//apple_ref/doc/uid/TP40016412)。 93 | 94 | ####从iOS中继承的框架 95 | 96 | Apple tvOS从iOS继承了许多框架。 97 | 98 | - Accelerate 99 | - AudioToolbox 100 | - AudioUnit 101 | - AVFoundation 102 | - AVKit 103 | - CFNetwork 104 | - CloudKit 105 | - CoreBluetooth 106 | - CoreData 107 | - CoreFoundation 108 | - CoreGraphics 109 | - CoreImage 110 | - CoreLocation 111 | - CoreMedia 112 | - CoreSpotlight 113 | - CoreText 114 | - CoreVideo 115 | - Darwin 116 | - Foundation 117 | - GameController 118 | - GameKit 119 | - GameplayKit 120 | - GLKit 121 | - ImageIO 122 | - MachO 123 | - MediaAccessibility 124 | - MediaPlayer 125 | - MediaToolbox 126 | - Metal 127 | - MetalKit 128 | - MetalPerformanceShaders 129 | - MobileCoreServices 130 | - ModelIO 131 | - OpenGLES 132 | - SceneKit 133 | - Security 134 | - simd 135 | - SpriteKit 136 | - StoreKit 137 | - Swift Standard Library 138 | - SystemConfiguration 139 | - UIKit 140 | 141 | ####新用户界面的挑战 142 | 143 | Apple tvOS并没有提供鼠标给用户,并且也不能通过手势和触摸交互。相反,用户使用新的Siri遥控或者游戏控制器进行操作。 144 | 145 | 使用新的控制方式,整个用户体验都会变得完全不一样。Mac和iOS设备一般是单人体验。虽然用户可能会通过应用与其它人进行交互,但是同一个设备一般只有一个人使用。但是新的Apple TV的用户体验更加社会化。几个人可以一起坐在沙发上一边交流一边使用应用。在设计应用的使用将这些变化都考虑进去是非常重要的。 146 | 147 | ####资源限制 148 | 149 | Apple TV上的应用没有持久化的本地存储。这意味着每个应用都应该将数据存放在iCloud,并且通过一种用户体验较好的方式将它们获取到。 150 | 151 | 除了缺乏本地存储,Apple TV应用的大小也被限制在200MB。如果一个应用的大小超过了限制,就需要使用按需加载的方式将它们打包。知道什么时候加载以及如何价值新的资源对开发一款成功的应用非常重要。更多关于按需加载资源的信息,见[《On-Demand Resources Guide》](https://developer.apple.com/library/prerelease/tvos/documentation/FileManagement/Conceptual/On_Demand_Resources_Guide/index.html#//apple_ref/doc/uid/TP40015083)。 152 | 153 | 下一章:[《创建一个C/S应用》](./Creating_a_Client-Server_App.md)。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/Working_with_Game_Controllers.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | ##使用游戏控制器 26 | 27 | 用户可以像连接iOS设备一样将游戏控制器连接到Apple TV上。当一个游戏控制器连接到Apple TV上时,这个控制器也可以用来控制界面上的焦点移动。底层的游戏控制器输入被自动转化为上层的事件在响应链上进行传递。如果一个应用完全依赖于UIKit以及基于焦点的交互,那么可以不做任何修改就可以支持游戏控制器。遥控器和游戏控制器的事件对我们来说都是透明的,完全由系统自动处理。 28 | 29 | 如果我们需要获取底层的控制器输入,可以使用**Game Controller**框架。见[《游戏控制器编程》](https://developer.apple.com/library/prerelease/tvos/documentation/ServicesDiscovery/Conceptual/GameControllerPG/Introduction/Introduction.html#//apple_ref/doc/uid/TP40013276)。 30 | 31 | Apple TV上的游戏控制器框架有如下几个显著的变化: 32 | - 新的微型游戏控制器配置(`GCMicroGamepad`)表示Apple TV遥控的功能。 33 | - 新的视图控制器类(`GCEventViewController`)被用来将遥控和控制器的输入路由到应用中。 34 | 35 | ##支持游戏控制器的需求 36 | 37 | 支持游戏控制器需要遵循以下几个要求。这些要求主要用来确保游戏的可玩性。 38 | 39 | **游戏必须支持Apple TV遥控**。游戏不能强制用户使用控制器。 40 | **支持游戏控制器的tvOS游戏,必须支持扩展的控制器布局**。支持各式各样的tvOS游戏控制器。 41 | 42 | **必须支持暂停**。所有游戏控制器必须包含暂停按钮。当用户按暂停后,正在玩的游戏应该被暂停。而如果当时正处于菜单页面,按暂停按钮返回前一个页面。 43 | 44 | ##将Apple TV遥控器作为游戏控制器 45 | 46 | Apple TV遥控可以作为一个功能受限的控制器使用。和其它控制器一样,遥控器在Game Controller框架中也被当作一个`GCController`对象。Apple TV遥控支持`GCMotion`和`GCMicroGamepad`两种模式。只有Apple TV遥控支持微型手柄模式,想要支持其它游戏控制器,我们必须实现扩展的游戏手柄模式。 47 | 48 | 扩展的控制器有以下特征: 49 | 50 | - 遥控上的触控板可以用作十字键(D-pad),提供模拟数据输入。 51 | - 遥控在垂直和水平方向都能使用。由应用决定是否需要自动翻转输入数据。 52 | - 通过紧按触摸板,作为数字按钮(A)输入内容。 53 | - 遥控上的**Play/Pause**按钮用作数字键(X)。 54 | - 菜单按钮用作暂停按钮。 55 | 56 | ##确定控制器输入的目标 57 | 58 | 在iOS上,游戏控制器事件由Game Controller框架处理。默认情况下,tvOS上的UIKit框架处理底层的控制器输入,并且在响应链上传递上层事件。但是底层的游戏控制器事件默认不可用。因为所有事件都被UIKit框架处理了。如果我们需要直接读取控制器的输入,必须先关闭UIKit。如图6-1所示两条输入路径。 59 | 60 | 图6-1 控制器输入目标 61 | 62 | ![控制器输入目标](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/Art/GCEventViewController_2x.png) 63 | 64 | 例如,一个常见的游戏设计是:一个视图显示主菜单选项,第二个菜单显示游戏界面。主菜单可以使用UIKit元素来实现,这样它就可以与焦点行为保持一致。当游戏视图显示的时候,我们可以关闭UIKit的输入过程,从而使用游戏控制器来直接获取输入。 65 | 66 | 在tvOS上,当我们想要在游戏里直接处理输入的时候。需要使用`GCEventViewController`或者它的子类来显示游戏内容。当`GCEventViewController`对象的视图或自视图成为第一响应者后,游戏控制器的输入被视图控制器捕获到,并且发送给应用中的游戏控制器框架。 67 | 68 | 当视图控制器的视图结构中有一个视图成为第一响应者后,UIKit正常处理事件。一旦在响应链中有一个`GCEventViewController`对象,我们可以通过`controllerUserInteractionEnabled`属性开关事件的处理流程。如果我们的游戏混合了UIKit和Metal内容,当游戏暂停时,改变`controllerUserInteractionEnabled`的属性来打开UIKit交互。当选择菜单上的选项恢复游戏的时候,应该重新切换回游戏控制器。 -------------------------------------------------------------------------------- /App-Programming-Guide-for-tvOS/iCloud_Storage.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | 23 | ##主要内容 24 | 25 | Apple TV的存储空间非常有限,并且不保证存储在设备上的数据在用户下次打开程序的时候还继续存在。因此为了在多个设备上分析用户的数据,我们需要将用户的数据存储的其它地方。苹果给我们提供了两个选择:iCloud键值存储和CloudKit。 26 | 27 | 当存储空间小于1MB的时候,我们可以选择iCloud KVS。iCloud KVS自动在不同设备之间进行同步。只有应用拥有者才能访问存储在iCloud KVS上的数据。应用的其它用户不能够访问这些信息。更多信息,建“[设计iCloud中的键值数据](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html#//apple_ref/doc/uid/TP40012094-CH7)”。 28 | 29 | 如果需要存储更多数据,比如说超过1MB,我们需要在应用中实现CloudKit。CloudKit允许一个用户存储的数据被另一个用户访问。这个在一个用户的行为能够影响都另外的用户时非常有用。比如游戏中一个用户的动作能够直接影响另外的用户。更多关于在应用中实现CloudKit的信息,见”[Cloud Quick Start](https://developer.apple.com/library/prerelease/tvos/documentation/DataManagement/Conceptual/CloudKitQuickStart/Introduction/Introduction.html#//apple_ref/doc/uid/TP40014987)“。 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 戴维营教育 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # App-Programming-Guide-for-tvOS 2 | 中文版苹果官方《tvOS应用编程指南》 3 | 英文原版:[《App Programming Guide for tvOS》](https://developer.apple.com/library/prerelease/tvos/documentation/General/Conceptual/AppleTV_PG/index.html#//apple_ref/doc/uid/TP40015241-CH12-SW1) 4 | 5 | 本翻译没有获得**苹果公司**的授权,纯属学习爱好。 6 | 7 | ####欢迎大家帮忙翻译校正或者提供更好的Apple TV开发资料。 8 | ####交流群:85157830(AppleTV开发梦工厂) 9 | ####问答网站:[潜心俱乐部](http://divein.club) 10 | 11 | ##致谢 12 | ####翻译(按加入时间排序) 13 | - [戴维营教育](http://v.diveinedu.com) 14 | - [AndyLiao8](https://github.com/AndyLiao8) 15 | - [Cheetah.Kiong](https://github.com/wuqiong) 16 | - [wcrane](https://github.com/wcrane) 17 | 18 | ##在线阅读 19 | 20 | 本文档使用[Gitbook](http://diveinedu.gitbooks.io/app-programming-guide-for-tvos/)制作,可以直接在线阅读或者导出PDF、EPUB等格式。 21 | 22 | ##目录 23 | ####关于Apple TV 24 | #####[新的Apple TV](./App-Programming-Guide-for-tvOS/The_New_Apple_TV.md) 25 | 26 | ####构建Apple TV应用 27 | #####1. [创建一个C/S应用](./App-Programming-Guide-for-tvOS/Creating_a_Client-Server_App.md) 28 | #####2. [使用Apple遥控操作用户界面](./App-Programming-Guide-for-tvOS/Controlling_the_User_Interface_On_the_Screen_with_an_Apple_Remote.md) 29 | #####3. [检测手势和按钮点击事件](./App-Programming-Guide-for-tvOS/Detecting_Gestures_and_Button_Presses.md) 30 | #####4. [设计键盘输入体验](./App-Programming-Guide-for-tvOS/Designing_the_Keyboard_Input_Experience.md) 31 | #####5. [使用游戏控制器](./App-Programming-Guide-for-tvOS/Working_with_Game_Controllers.md) 32 | #####6. [创建视差插图](./App-Programming-Guide-for-tvOS/Creating_Parallax_Artwork.md) 33 | 34 | ####资源管理 35 | #####1. [iCloud存储](./App-Programming-Guide-for-tvOS/iCloud_Storage.md) 36 | #####2. [按需加载资源](./App-Programming-Guide-for-tvOS/On-Demand_Resources.md) 37 | 38 | ####版本历史 39 | #####[文档版本历史](./App-Programming-Guide-for-tvOS/Document_Revision_History.md) 40 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | * [新的Apple TV](App-Programming-Guide-for-tvOS/The_New_Apple_TV.md) 4 | * [创建一个C/S应用](App-Programming-Guide-for-tvOS/Creating_a_Client-Server_App.md) 5 | * [在tvOS遥控上操作用户界面](App-Programming-Guide-for-tvOS/Controlling_the_User_Interface_On_the_Screen_with_an_Apple_Remote.md) 6 | * [检测手势与按钮事件](App-Programming-Guide-for-tvOS/Detecting_Gestures_and_Button_Presses.md) 7 | * [设计键盘输入](App-Programming-Guide-for-tvOS/Designing_the_Keyboard_Input_Experience.md) 8 | * [使用游戏控制器](App-Programming-Guide-for-tvOS/Working_with_Game_Controllers.md) 9 | * [创建视差图片](App-Programming-Guide-for-tvOS/Creating_Parallax_Artwork.md) 10 | * [按需加载资源](App-Programming-Guide-for-tvOS/On-Demand_Resources.md) 11 | * [iCloud存储](App-Programming-Guide-for-tvOS/iCloud_Storage.md) 12 | * [文档历史](App-Programming-Guide-for-tvOS/Document_Revision_History.md) 13 | 14 | --------------------------------------------------------------------------------