SlideShare une entreprise Scribd logo
1  sur  134
iOSDC 2017/09/17
Yuji Hato
Apple TV tvOS入門
About me
Yuji Hato
CyberAgent, Inc. / AbemaTV, Inc.
dekatotoro
@dekatotoro
Contributed services
Apple TV
Apple TV
・64-bit A8 processor
・32GB or 64GB of storage
・2GB of RAM
・10/100Mbps Ethernet
・WiFi 802.11a/b/g/n/ac
・1080p resolution
・HDMI 1.4
Apple TV
4th generation
・A10X Fusion
・32GB or 64GB of storage
・3GB of RAM
・Gigabit Ethernet
・Wi-Fi with MIMO 802.11ac
・2160p resolution
・HDMI 2.0
4K
32GB 15,800円
64GB 20,800円
※2016/09に値下げ
・32GB 18,400円 →15,800円(2,600円値下げ)
・64GB 24,800円 →20,800円(4,000円値下げ)
Apple TV (tvOS)
4th generation 4K
32GB 19,800円
64GB 21,800円
Remote
https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
Remote
https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
Remote
Swipe Click Tap
https://developer.apple.com/tvos/human-interface-guidelines/remote-and-controllers/
Remote
Development Method
Development Method
iOSとほぼ同様に開発
・Traditional Apps
TVMLとTVJSをで開発
・Client-Server Apps
Limited App Size
Limited App Size
200MB 4GB
Data Storage
Limited Local Storage
Service Online/Local Persistent/Temporary limit
iCloud Key-Value Store
(KVS)
Online Persistent 1MB max
CloudKit Online Persistent -
UserDefaults Local Persistent 500KB max
Keychain Local Persistent -
CacheDirectory Local Temporary May be purged
TemporaryDirectory Local Temporary May be purged
Limited Local Storage
Service Online/Local Persistent/Temporary limit
iCloud Key-Value Store
(KVS)
Online Persistent 1MB max
CloudKit Online Persistent -
UserDefaults Local Persistent 500KB max
Keychain Local Persistent -
CacheDirectory Local Temporary May be purged
TemporaryDirectory Local Temporary May be purged
Limited Local Storage
Service Online/Local Persistent/Temporary limit
iCloud Key-Value Store
(KVS)
Online Persistent 1MB max
CloudKit Online Persistent -
UserDefaults Local Persistent 500KB max
Keychain Local Persistent -
CacheDirectory Local Temporary May be purged
TemporaryDirectory Local Temporary May be purged
Limited Local Storage
Service Online/Local Persistent/Temporary limit
iCloud Key-Value Store
(KVS)
Online Persistent 1MB max
CloudKit Online Persistent -
UserDefaults Local Persistent 500KB max
Keychain Local Persistent -
CacheDirectory Local Temporary May be purged
TemporaryDirectory Local Temporary May be purged
User Interaction
https://developer.apple.com/tvos/human-interface-guidelines/overview/
User Interaction
Focus
https://developer.apple.com/tvos/human-interface-guidelines/app-architecture/focus-and-selection/
Parallax
User Interaction
https://developer.apple.com/tvos/human-interface-guidelines/visual-design/video/
Video
User Interaction
Icons and Images
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/
Icons and Images
App Icon.
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/app-icon/
Layered Images.
Icons and Images
Layered Images.
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/
Icons and Images
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/
Top Shelf Images.
Icons and Images
https://developer.apple.com/tvos/human-interface-guidelines/icons-and-images/
Top Shelf Images.
Icons and Images
Layout
Layout
1920 x 1080
3840 x 21604K
https://developer.apple.com/tvos/human-interface-guidelines/visual-design/
Layout
https://support.apple.com/ja-jp/HT202763
Layout
https://developer.apple.com/tvos/human-interface-guidelines/visual-design/
Layout
https://developer.apple.com/tvos/human-interface-guidelines/visual-design/
Layout
https://developer.apple.com/tvos/human-interface-guidelines/visual-design/layout/
Layout
Interface Elements
Tab Bars
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
TableView
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
CollectionView
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Split Views
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Text Fields
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Keyboards
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Search
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Button
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Navigation Bars
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Navigation Bars
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Page Controls
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Activity Indicators
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Alerts
Interface Elements
https://developer.apple.com/tvos/human-interface-guidelines/interface-elements/
Gesture
Gesture
Gesture
• Swipe
• Touch
• Select
Gesture
UITapGestureRecognizer
• upArrow
• downArrow
• leftArrow
• rightArrow
• select
• menu
• playPause
Gesture
UITapGestureRecognizer
let gesture = UITapGestureRecognizer(target: self, action: #selector(menuButtonPressed(_:)))
gesture.allowedPressTypes = [NSNumber(value: UIPressType.menu.rawValue)]
view.addGestureRecognizer(gesture)
Gesture
UITapGestureRecognizer
gesture.allowedPressTypes = [NSNumber(value: UIPressType.menu.rawValue)]
Gesture
UISwipeGestureRecognizer
• right
• left
• up
• down
Gesture
let gesture = UISwipeGestureRecognizer(target: self, action: #selector(swipeUp(_:)))
gesture.direction = .up
view.addGestureRecognizer(gesture)
UISwipeGestureRecognizer
Gesture
gesture.direction = .up
UISwipeGestureRecognizer
Focus
https://developer.apple.com/tvos/human-interface-guidelines/overview/
Focus
Focus
Focusはいつ更新されるの?
Focus
• システムが更新を要求したとき
• ユーザーの操作
• アプリケーションが更新を要求したとき
Focus
Focusは誰が更新するの?
Focus
https://developer.apple.com/library/content/documentation/General/Conceptual/AppleTV_PG/WorkingwiththeAppleTVRemote.html
Focus Engine
Focus
Focus Engineが検索する範囲は、現在Focusされて
いるViewの大きさに応じて決まり、そのViewを起点
として、動きの方向にあるFocus可能な領域を見つけ
て更新
Focus Engine
Focus
Focus Engineは、View階層のFocus動作を定義する
UIFocusEnvironmentプロトコルに従ってFocusを制
御
Focus Engine
Focus
https://devstreaming-cdn.apple.com/videos/wwdc/2017/224sn8vw625k1e86/224/224_focus_interaction_in_tvos_11.pdf
UIFocusEnvironment
Focus
public var preferredFocusEnvironments: [UIFocusEnvironment] { get }
public func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool
public func setNeedsFocusUpdate()
public func updateFocusIfNeeded()
public func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator:
UIFocusAnimationCoordinator)
@available(tvOS 11.0, *)
optional public func soundIdentifierForFocusUpdate(in context: UIFocusUpdateContext) ->
UIFocusSoundIdentifier?
UIFocusEnvironmentプロトコル
Focus
public var preferredFocusEnvironments: [UIFocusEnvironment] { get }
UIFocusEnvironmentプロトコル
Focus
public func shouldUpdateFocus(in context: UIFocusUpdateContext) -> Bool
UIFocusEnvironmentプロトコル
Focus
public func setNeedsFocusUpdate()
public func updateFocusIfNeeded()
UIFocusEnvironmentプロトコル
Focus
public func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator:
UIFocusAnimationCoordinator)
UIFocusEnvironmentプロトコル
Focus
https://devstreaming-cdn.apple.com/videos/wwdc/2017/224sn8vw625k1e86/224/224_focus_interaction_in_tvos_11.pdf
UIFocusEnvironment
Focus
@available(tvOS 11.0, *)
optional public func soundIdentifierForFocusUpdate(in context: UIFocusUpdateContext) ->
UIFocusSoundIdentifier?
UIFocusEnvironmentプロトコル
Focus
UIFocusEnvironmentに準拠しているクラス
Focus
• UIView
• UIViewController
• UIPresentationController
Focus
@available(tvOS 10.0, *)
public protocol UIFocusItem : UIFocusEnvironment {
public var canBecomeFocused: Bool { get }
}
UIFocusItemプロトコル
Focus
Focus可能なUIKitのクラス
Focus
• UIButton
• UITextField
• UITableView
• UICollectionView
• UITextView
• UISegmentedControl
• UISearchBar
• etc..
Focus
https://devstreaming-cdn.apple.com/videos/wwdc/2017/224sn8vw625k1e86/224/224_focus_interaction_in_tvos_11.pdf
Focus
UILabelなどデフォルトでフォーカスされないViewを
フォーカスさせるには?
Focus
class CustomLabel: UILabel {
isUserInteractionEnabled = true
isUserInteractionEnabled = true
override var canBecomeFocused: Bool {
return true
}
}
} }
UILabel for Focus
Focus
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator:
UIFocusAnimationCoordinator) {
super.didUpdateFocus(in: context, with: coordinator)
// Focus
if context.nextFocusedView == self {
coordinator.addCoordinatedFocusingAnimations({ [weak self] context in
self?.transform = CGAffineTransform(scaleX: 1.4, y: 1.4)
}, completion: nil)
}
// UnFocus
if context.previouslyFocusedView == self {
coordinator.addCoordinatedUnfocusingAnimations({ [weak self] context in
self?.transform = CGAffineTransform.identity
}, completion: nil)
}
}
UILabel for Focus
Focus
// Focus
if context.nextFocusedView == self {
coordinator.addCoordinatedFocusingAnimations({ [weak self] context in
self?.transform = CGAffineTransform(scaleX: 1.4, y: 1.4)
}, completion: nil)
}
UILabel for Focus
Focus
// UnFocus
if context.previouslyFocusedView == self {
coordinator.addCoordinatedUnfocusingAnimations({ [weak self] context in
self?.transform = CGAffineTransform.identity
}, completion: nil)
}
UILabel for Focus
Focus
UILabel for Focus
Focus
UITableView, UICollectionViewのFocusは?
Focus
Focus用のdelegateがtvOS用にあります
Focus
UITableViewDelegate for Focus
@available(tvOS 9.0, *)
optional public func tableView(_ tableView: UITableView, canFocusRowAt
indexPath: IndexPath) -> Bool
@available(tvOS 9.0, *)
optional public func tableView(_ tableView: UITableView,
shouldUpdateFocusIn context: UITableViewFocusUpdateContext) -> Bool
@available(tvOS 9.0, *)
optional public func tableView(_ tableView: UITableView, didUpdateFocusIn
context: UITableViewFocusUpdateContext, with coordinator:
UIFocusAnimationCoordinator)
@available(tvOS 9.0, *)
optional public func indexPathForPreferredFocusedView(in tableView:
UITableView) -> IndexPath?
Focus
@available(tvOS 9.0, *)
optional public func collectionView(_ collectionView: UICollectionView, canFocusItemAt indexPath:
IndexPath) -> Bool
@available(tvOS 9.0, *)
optional public func collectionView(_ collectionView: UICollectionView, shouldUpdateFocusIn context:
UICollectionViewFocusUpdateContext) -> Bool
@available(tvOS 9.0, *)
optional public func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context:
UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator)
@available(tvOS 9.0, *)
optional public func indexPathForPreferredFocusedView(in collectionView: UICollectionView) ->
IndexPath?
@available(tvOS 9.0, *)
optional public func collectionView(_ collectionView: UICollectionView,
targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath
proposedIndexPath: IndexPath) -> IndexPath
@available(tvOS 9.0, *)
optional public func collectionView(_ collectionView: UICollectionView,
targetContentOffsetForProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint
UICollectionViewDelegate for Focus
Focus
@available(tvOS 9.0, *)
open var remembersLastFocusedIndexPath: Bool
UITableView, UICollectionView for Focus
Focus
UIImageViewのFocusは?
Focus
@available(tvOS 9.0, *)
open var adjustsImageWhenAncestorFocused: Bool
@available(tvOS 9.0, *)
open var focusedFrameGuide: UILayoutGuide { get }
@available(tvOS 11.0, *)
open var overlayContentView: UIView { get }
@available(tvOS 11.0, *)
open var masksFocusEffectToContents: Bool
UIImageView for Focus
Focus
@available(tvOS 9.0, *)
open var adjustsImageWhenAncestorFocused: Bool
UIImageView for Focus
Focus
imageView.adjustsImageWhenAncestorFocused = true
UIImageView for Focus
https://developer.apple.com/tvos/human-interface-guidelines/overview/focus-and-parallax/
Focus
UIImageView for Focus
@available(tvOS 11.0, *)
open var overlayContentView: UIView { get }
Focus
UIImageView for Focus
Focus
let overlayView = UIView(frame: imageView.frame)
overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
imageView.overlayContentView.addSubview(overlayView)
UIImageView for Focus
Focus
imageView.overlayContentView.addSubview(overlayView)
UIImageView for Focus
Focus
// UICollectionView delegate
func collectionView(_ collectionView: UICollectionView, didUpdateFocusIn context:
UICollectionViewFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
// Focus
if let cell = context.nextFocusedView as? CostomCollectionViewCell {
coordinator.addCoordinatedFocusingAnimations({ context in
cell.imageView.overlayContentView.alpha = 0
}, completion: nil)
}
// UnFocus
if let cell = context.previouslyFocusedView as? CostomCollectionViewCell {
coordinator.addCoordinatedUnfocusingAnimations({ context in
cell.imageView.overlayContentView.alpha = 1
}, completion: nil)
}
}
UIImageView for Focus
Focus
// Focus
if let cell = context.nextFocusedView as? CostomCollectionViewCell {
coordinator.addCoordinatedFocusingAnimations({ context in
cell.imageView.overlayContentView.alpha = 0
}, completion: nil)
}
UIImageView for Focus
Focus
// UnFocus
if let cell = context.previouslyFocusedView as? CostomCollectionViewCell {
coordinator.addCoordinatedUnfocusingAnimations({ context in
cell.imageView.overlayContentView.alpha = 1
}, completion: nil)
}
UIImageView for Focus
Focus
UIImageView for Focus
Focus
Focus Update Notification
Focus
Focus Update Notification
extension NSNotification.Name {
@available(tvOS 11.0, *)
public static let UIFocusDidUpdate: NSNotification.Name
@available(tvOS 11.0, *)
public static let UIFocusMovementDidFail: NSNotification.Name
}
@available(tvOS 11.0, *)
public let UIFocusUpdateContextKey: String
@available(tvOS 11.0, *)
public let UIFocusUpdateAnimationCoordinatorKey: String
Focus
Focus Update Notification
@available(tvOS 11.0, *)
public static let UIFocusDidUpdate: NSNotification.Name
Focus
Focus Update Notification
@available(tvOS 11.0, *)
public static let UIFocusMovementDidFail: NSNotification.Name
}
Focus
UIFocusGuide?
Focus
@available(tvOS 9.0, *)
open class UIFocusGuide : UILayoutGuide {
open var isEnabled: Bool
@available(tvOS 10.0, *)
open var preferredFocusEnvironments: [UIFocusEnvironment]!
}
UIFocusGuide
Focus
UIFocusGuide
Focus
UIFocusGuide
Focus
UIFocusGuide
Focus
UIFocusGuide
Focus
UIFocusGuide
Focus
UIFocusGuide
FocusGuide
Focus
UIFocusGuide
FocusGuide
preferredFocusEnvironments
Focus
UIFocusGuide
Focus
focusGuide = UIFocusGuide()
view.addLayoutGuide(focusGuide)
// Anchor the top left of the focus guide.
focusGuide.topAnchor.constraint(equalTo: button.topAnchor).isActive = true
focusGuide.leftAnchor.constraint(equalTo: collectionView.leftAnchor).isActive = true
// Anchor the width and height of the focus guide.
focusGuide.heightAnchor.constraint(equalTo: button.heightAnchor).isActive = true
focusGuide.widthAnchor.constraint(equalTo: collectionView.widthAnchor).isActive = true
focusGuide.preferredFocusEnvironments = [button]
UIFocusGuide
Focus
focusGuide = UIFocusGuide()
view.addLayoutGuide(focusGuide)
UIFocusGuide
Focus
// Anchor the top left of the focus guide.
focusGuide.topAnchor.constraint(equalTo: button.topAnchor).isActive = true
focusGuide.leftAnchor.constraint(equalTo: collectionView.leftAnchor).isActive = true
UIFocusGuide
Focus
// Anchor the width and height of the focus guide.
focusGuide.heightAnchor.constraint(equalTo: button.heightAnchor).isActive = true
focusGuide.widthAnchor.constraint(equalTo: collectionView.widthAnchor).isActive = true
UIFocusGuide
Focus
focusGuide.preferredFocusEnvironments = [button]
UIFocusGuide
Focus
Focusがうまくいかない場合
Focus
• canBecomeFocusedがfalseになってないか
• isHiddenがtrueになってないか
• alphaが0でないか
• isUserInteractionEnabledがfalseになってないか
• viewが隠れていないか
Focusがうまくいかない場合
Focus
Focusのdebug
Focus
Focus Update Logging
Focus
The result of the focus update was determined from the following
preferred focus search:
|
| Starting preferred focus search:
| |--> Searching <UIFocusSystem 0x60000028dc00>...
| |--> Searching <UIScreen 0x6080001d3fb0>...
| |--> Searching <UIWindow 0x7fb79cb02af0>...
| |--> Searching
<tvos_sample_for_iosdc.RootViewController 0x7fb79c904da0>...
| |--> Searching <UIView
Focus Update Logging
Focus
po UIFocusDebugger.status()
<UIButton 0x7f97bac05b90> is currently focused.
UIFocusDebugger
Focus
po UIFocusDebugger.simulateFocusUpdateRequest(from:
imageView)
Simulating a fake focus update request from <UIImageView 0x7ff3ce2106d0>...
(<tvos_sample_for_iosdc.MainCollectionViewCell 0x7ff3ce20fe60> is currently focused)
The following issues were found that would normally prevent this environment's request from being accepted by the focus
system (these will be ignored for the purposes of this test):
- ISSUE: This environment does not contain the currently focused item.
Starting preferred focus search:
|--> Searching <UIImageView 0x7ff3ce2106d0>...
No more preferences for this environment, and there are no focusable items in this environment to prefer by default.
This environment does not prefer a valid focusable item, nor any other environments.
Simulated Result: Successfully updated focus to nil.
UIFocusDebugger
Focus
po UIFocusDebugger.checkFocusability(for: label)
The following issues were found that would prevent this item from being focusable:
- ISSUE: This view has isUserInteractionEnabled set to NO. Views must allow user
interaction to be focusable.
UIFocusDebugger
Conclusion
Conclusion
• iOSとの違いはFocus
• 標準のUI/UXに準拠しよう
• tvOS対応は難しくない
Thank you
参考資料
https://developer.apple.com/videos/play/wwdc2017/209/
https://developer.apple.com/videos/play/wwdc2017/224
https://developer.apple.com/tvos/resources/

Contenu connexe

Similaire à Apple TV tvOS入門 Iosdc2017

Manual Layout Revisited
Manual Layout RevisitedManual Layout Revisited
Manual Layout Revisitedgillygize
 
Developing for the Epson Moverio + App Challenge Announcement
Developing for the Epson Moverio + App Challenge AnnouncementDeveloping for the Epson Moverio + App Challenge Announcement
Developing for the Epson Moverio + App Challenge AnnouncementPrelaunch Labs, Inc.
 
打造你的第一個iPhone APP
打造你的第一個iPhone APP打造你的第一個iPhone APP
打造你的第一個iPhone APP彼得潘 Pan
 
Desigining for auto_layout
Desigining for auto_layoutDesigining for auto_layout
Desigining for auto_layoutJosh Burton
 
AbemaTV on tvOS
AbemaTV on tvOSAbemaTV on tvOS
AbemaTV on tvOSYuji Hato
 
From desktop to big screens
From desktop to big screens From desktop to big screens
From desktop to big screens Zdenek Zenger
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 
iPhone Design Workshop
iPhone Design WorkshopiPhone Design Workshop
iPhone Design WorkshopRick Messer
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material DesignYasin Yildirim
 
Why design matters?
Why design matters?Why design matters?
Why design matters?Ozlem Bilis
 
Altimeter Digital GPS + Map Viewer + Camera + Climb Calc
Altimeter Digital GPS + Map Viewer + Camera + Climb CalcAltimeter Digital GPS + Map Viewer + Camera + Climb Calc
Altimeter Digital GPS + Map Viewer + Camera + Climb CalcGreta Helder
 
Titanium appcelerator sdk
Titanium appcelerator sdkTitanium appcelerator sdk
Titanium appcelerator sdkAlessio Ricco
 
Develop apps for (Apple) TV
Develop apps for (Apple) TVDevelop apps for (Apple) TV
Develop apps for (Apple) TVCodemotion
 
Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Aaron Gustafson
 

Similaire à Apple TV tvOS入門 Iosdc2017 (20)

Manual Layout Revisited
Manual Layout RevisitedManual Layout Revisited
Manual Layout Revisited
 
Developing for the Epson Moverio + App Challenge Announcement
Developing for the Epson Moverio + App Challenge AnnouncementDeveloping for the Epson Moverio + App Challenge Announcement
Developing for the Epson Moverio + App Challenge Announcement
 
打造你的第一個iPhone APP
打造你的第一個iPhone APP打造你的第一個iPhone APP
打造你的第一個iPhone APP
 
Desigining for auto_layout
Desigining for auto_layoutDesigining for auto_layout
Desigining for auto_layout
 
Porting Tablet Apps to the Amazon Fire TV
Porting Tablet Apps to the Amazon Fire TVPorting Tablet Apps to the Amazon Fire TV
Porting Tablet Apps to the Amazon Fire TV
 
AbemaTV on tvOS
AbemaTV on tvOSAbemaTV on tvOS
AbemaTV on tvOS
 
From desktop to big screens
From desktop to big screens From desktop to big screens
From desktop to big screens
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
iPhone Design Workshop
iPhone Design WorkshopiPhone Design Workshop
iPhone Design Workshop
 
Web app
Web appWeb app
Web app
 
I os11
I os11I os11
I os11
 
Getting Started With Material Design
Getting Started With Material DesignGetting Started With Material Design
Getting Started With Material Design
 
Why design matters?
Why design matters?Why design matters?
Why design matters?
 
Altimeter Digital GPS + Map Viewer + Camera + Climb Calc
Altimeter Digital GPS + Map Viewer + Camera + Climb CalcAltimeter Digital GPS + Map Viewer + Camera + Climb Calc
Altimeter Digital GPS + Map Viewer + Camera + Climb Calc
 
Titanium appcelerator sdk
Titanium appcelerator sdkTitanium appcelerator sdk
Titanium appcelerator sdk
 
Droidcon2014 - Android UX
Droidcon2014 - Android UXDroidcon2014 - Android UX
Droidcon2014 - Android UX
 
Multitasking
MultitaskingMultitasking
Multitasking
 
Develop apps for (Apple) TV
Develop apps for (Apple) TVDevelop apps for (Apple) TV
Develop apps for (Apple) TV
 
Develop apps for (Apple) TV
Develop apps for (Apple) TVDevelop apps for (Apple) TV
Develop apps for (Apple) TV
 
Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]Adapting to Reality [Guest Lecture, March 2021]
Adapting to Reality [Guest Lecture, March 2021]
 

Plus de Yuji Hato

継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」
継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」
継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」Yuji Hato
 
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Yuji Hato
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術Yuji Hato
 
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSourcesYuji Hato
 
AbemaTV モバイルアプリの開発体制と開発プロセスの話
AbemaTV モバイルアプリの開発体制と開発プロセスの話AbemaTV モバイルアプリの開発体制と開発プロセスの話
AbemaTV モバイルアプリの開発体制と開発プロセスの話Yuji Hato
 
Flux with RxSwift
Flux with RxSwiftFlux with RxSwift
Flux with RxSwiftYuji Hato
 
CarPlayの対応方法と日本での現状
CarPlayの対応方法と日本での現状CarPlayの対応方法と日本での現状
CarPlayの対応方法と日本での現状Yuji Hato
 
AWA with Realm
AWA with RealmAWA with Realm
AWA with RealmYuji Hato
 

Plus de Yuji Hato (8)

継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」
継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」
継続的な開発スタイル 「AbemaTV iOSアプリを週一でリリースしている話」
 
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ - Adaptive UI  - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
Adaptive UI - 解像度の異なるデバイスや画面の向きに対応する 最適なレイアウトへ -
 
iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術iOSDC 2018 動画をなめらかに動かす技術
iOSDC 2018 動画をなめらかに動かす技術
 
5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources5分で学ぶ差分更新とRxDataSources
5分で学ぶ差分更新とRxDataSources
 
AbemaTV モバイルアプリの開発体制と開発プロセスの話
AbemaTV モバイルアプリの開発体制と開発プロセスの話AbemaTV モバイルアプリの開発体制と開発プロセスの話
AbemaTV モバイルアプリの開発体制と開発プロセスの話
 
Flux with RxSwift
Flux with RxSwiftFlux with RxSwift
Flux with RxSwift
 
CarPlayの対応方法と日本での現状
CarPlayの対応方法と日本での現状CarPlayの対応方法と日本での現状
CarPlayの対応方法と日本での現状
 
AWA with Realm
AWA with RealmAWA with Realm
AWA with Realm
 

Dernier

Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Mater
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 

Dernier (20)

Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)Ahmed Motair CV April 2024 (Senior SW Developer)
Ahmed Motair CV April 2024 (Senior SW Developer)
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 

Apple TV tvOS入門 Iosdc2017

Notes de l'éditeur

  1. はい、それではApple TV tvOS入門ということで発表したいと思います。よろしくお願いします。
  2. まず簡単に自己紹介です。 波戸と申します。ネット上ではだいたいdekatotoroという名前で活動していて、 AbemaTVのiOSとtvOSアプリの開発しています。
  3. はい、今日はtvOSの概要や基本とフォーカスについてお話ししたいと思います。 まず、Apple TVの概要について見ていきたいと思います。
  4. 第4世代Apple TVは2015年10月30日に発売されました。先日発表されたApple TV 4Kは09/22日発売されます
  5. スペックですが、第4世代がCPUはA8のデュアルコアでメモリが2GB、4KがA10Xでメモリは3Gになっています。
  6. ちなみに値段はspecの割にiPhoneに比べると安く感じる気がします
  7. はい、次に、Apple TVに付属するリモコンですが、
  8. こんな感じで
  9. 上のマットな部分はTouch Surfaceと呼ばれている部分で、SwipeやClick, Tapができます。物理ボタンとして、Menu、Home、Siri、Play/PauseとVolumeボタンがあります。
  10. Swipeは左右上下で Clickは押し込む感じ Tapは左右上下の位置で軽く触るイメージになります。
  11. 次にtvOSの開発方法ですが、
  12. 大きく分けて2つあります Traditional AppsとClient server appsの2つです Traditional AppsはiOSと同様に開発するもので、 Client server AppsはTVMLやTVJSといったApple独自のWeb技術を使って開発する手法になります。 今回は通常のTraditional Appsの開発についての話になります。
  13. アプリサイズの制限があって、
  14. 以前は200MBの制限があったんですが、現在は4Gに緩和されています。 ゲームなどサイズが大きくなるものもあると思うので、その場合は オンデマンドリソースやCacheDirectoryを使う必要があります。
  15. tvOSのデータの保存も制限がいくつかあって、
  16. 図のような感じにまとめました
  17. iCloudにデータを保存と取得ができますというのと、
  18. UserDefaultsが500kの制限がありますよーというのと、
  19. TmpDirectory, CacheDirectoryは、OSによって消される可能性がありますーというものです アプリケーションの実行中は削除されませんが、tvOSではDocumentsディレクトリは使えないので、RealmとかSqliteのようなdatabase fileもcacheDirectoryに保存することになります。なので、purgeされる可能性を考えると、DBはdisk保存じゃなくてonMemoryを検討してもいいかもしれません。
  20. はい、次にtvOSのUser Interactionについて代表的な部分を紹介します。
  21. tvOSではFocusという概念があって、基本的にView間の移動はFocusによって行います。
  22. 次に画像ですが、 ImageViewにadjustsImageWhenAncestorFocusedというpropertyがあってこれをtrueにしておけば、focus時にparallaxのようなインタラクションになります。
  23. あとは、tvOSと相性の良い動画ですが、 デフォルトのAVPlayerControllerを使用することで、このようなseekやstart/stop操作など簡単に実装できます。
  24. 次にIconと画像ですが、
  25. これはAppStoreの画像で、App Iconが並んでいます。 で、このcollectionで並んでるApp Iconはfocusしてグリグリできるようになっていて、
  26. えー、App IconはLayeredImageというもので作成するのですが、 これは設定アプリの例で、5枚の画像をレイヤードしてできたもので、 よく見ないとわかりませんが、Focus時にグリグリすると、layeredした画像がparallaxぽい動きになります。
  27. ちょっと小さくて見にくいと思いますが、LayeredImageは実際のサイズと、フォーカス時に見切れないサイズ、アンフォーカス時のサイズが定義されているので、これを参考にして作ることができます。App Icon以外にもアプリでLayeredImageを使うことができて、埋め込みのLayeredImageはlsr、サーバから取得するものはlcrというformatで使うことができます。 埋め込みの場合はXcodeでもできますが、layeredImageを生成するためのツールも用意されています。
  28. はい、あとはTop Shelf Imageですが、tvOSのホーム画面でfocusした時の上に表示する大きい画像も用意する必要があります。
  29. Top Shelf Imageはコンテンツのリストを見せたりなどのカスタムもできます。
  30. はい、次にLayoutについてAppleが推奨しているレイアウトを紹介します。
  31. アプリの画面レイアウトは1920 x 1080、4Kの場合はその2倍で16:9の画面解像度に設計します。
  32. 全体的なデザインですが、古いTVだと端が見切れて隠れてしまうことがあるので、 コンテンツから、画面の上下から60ピクセル、側面から90ピクセルで余白を空けておくことが推奨されています。
  33. 古いTVなどで端が見切れて隠れてしまう現象は、 縦が見切れるオーバースキャンと、横幅が狭まるアンダースキャン などがあり、 テレビやプロジェクター側の設定で調整すると直る場合があるんですけど、 ユーザーがなかなか気づかないことが多いと思うので、見切れても問題ないように、先ほどのように余白を設けたデザインにしたほうが良さそうです。。
  34. あとはフォーカスして拡大しても問題ないようにパディングを設けてください、というのと、
  35. 大きな要素でもコンテンツを1画面に伸ばさず、複数あるというヒントを残すと良いですと推奨しています。
  36. こんな感じでレイアウトのテンプレートをAppleが公開しているので 、これを参考にすると良いと思います。
  37. はい、次にUIの部品についてざっと見ていきます
  38. tvOSのTab Barはこんな感じで、上に表示されます。 UITabBarControllerを使って実装すると簡単で 多くのアプリのメニューはtabかサイドメニューとなっています
  39. Table Viewはfocusするとdefaultでfocusアニメーションがついて拡大してくれます。
  40. 次にコレクションViewですが、デフォルトではfocusアニメーションはありません。cellの中にImageViewがあればImage拡大の設定ができますが、cell自体のfocusアニメーションをつけたい場合は自分で実装する必要があります。
  41. はい、SplitViewはこんな感じで、この例のように 左がlistで右がコンテンツ表示というのが多いと思いますが、 tvOSだと結構使用するレイアウトじゃないかと思います。
  42. で、TextFieldで
  43. keyboradはこんな感じで、TextFieldなどにfocusした時に表示されます。
  44. UISearchBarはこんな感じです。
  45. こちらはButtonです、AbemaTVではカスタムボタンをいくつか使っていますが systemボタンを使うとデフォルトでfocusアニメーションがついて拡大してくれたりするので、デザイン上カスタマイズする必要がなければ、systemボタンが良いと思います。
  46. Navigation barは上にナビゲーションを表示します。
  47. 例として純正の設定アプリがNavigation barを使って、現在いるnavigation階層のtitleを表示するように使用しています。 navigationbarにtranslucentを設定していれば、レイアウトによってはnavigation領域にもコンテンツが表示されるので、グラデーションをかけて徐々にViewが消える感じを出しているアプリが多いように思います。
  48. はい、あとはUIPageControlで、iOSとほとんど一緒ですね
  49. これは、ローディングに使うUIActivityIndicatorViewです。
  50. これはUIAlertControllerで、popupではなく画面全体に表示される感じになります。
  51. はい、次にGestureについて説明します
  52. 先程説明した通りApple TVのリモコンはTouch Surfaceと物理ボタンを使って操作します。
  53. リモコンのTouch SurfaceのSwipe/Touch/Selectの操作は、GestureRecognizerやEventで検知できます。
  54. UITapGestureRecognizerのallowedPressTypesにUIPressTypeを指定できます。up/down/left/rightはTouch Surfaceを左右上下の位置で軽く触る、selectはTouch Surfaceを押し込む、menu/playPauseは物理ボタンの押下で発生するイベントです。
  55. PressTypeがmenuのGestureを扱うコードはこんな感じで
  56. allowedPressTypesにUIPressType.menuを指定します
  57. UISwipeGestureRecognizerはDirectionを指定できます。Touch Surfaceの左右上下のSwipeの入力イベントになります。
  58. directionがupのSwipeGestureを扱うコードはこんな感じで
  59. directionにupを指定します
  60. 次にtvOSで一番重要なFocusについてです
  61. iOSとtvOSの一番大きな違いとしてフォーカスがあります iOSデバイスの場合、ユーザーは直接、タッチスクリーン上でインターフェイスを操作しますが、Apple TVでは、リモコンで画面上のある項目にナビゲートした後、リモコンのボタンを押して選択する、といった操作になるので、画面上の各項目は、そこにナビゲートすると「フォーカスされた」状態になり、ユーザーアクションの対象になるといった動作になります。
  62. フォーカスはいつ更新されるのかということですが、
  63. 大きく分けて3つにないります ユーザーの操作と、システムが更新を要求したときと、アプリケーションが更新を要求したときです。 システムが更新を要求するときはフォーカスされているビューを、ビュー階層から削除したときとか、UITableViewやUICollectionViewがデータを再読み込みしたときなどです。
  64. このフォーカスの更新は誰がやっているのということですが、
  65. フォーカスエンジンがフォーカスするViewを決定してくれています。フォーカスを更新できるのはフォーカスエンジンのみで、どのビューにフォーカスをあてるか直接指定するAPIなくて、フォーカスエンジンがフォーカスを更新します。
  66. Focus Engineが検索する範囲は、現在FocusされているViewの大きさに応じて決まり、そのViewを起点として動きの方向にあるFocus可能な領域を見つけて更新します
  67. Focus EngineはView階層のFocus動作を定義するUIFocusEnvironmentプロトコルに従ってFocusを制御します
  68. UIFocusEnvironmentはFocus可能なItemの階層で構成されています
  69. UIFocusEnvironmentプロトコルの定義はこのようになっています。
  70. まずpreferredFocusEnvironmentsですが、アプリケーションが、どのビューにフォーカスをあてるべきか、これ使ってフォーカスエンジンに指定できます。
  71. shouldUpdateFocusは、フォーカスエンジンが移動する前に、移動先が適切かどうかアプリが判断するタイミングになります。移動元と移動先のビューを含むフォーカス環境それぞれについて、shouldUpdateFocusInContext:メソッドを呼び出して、移動元のビュー、移動先のビュー、2つの親であるビュー、という順序で呼び出していきます。いずれかひとつでも、戻り値がfalseの場合があれば、移動は行われない動きになります
  72. 次にこの2つですが、setNeedsFocusUpdateでフォーカスエンジンに更新をリクエスト、即座に更新したい場合はupdateFocusIfNeededを呼び出します。ここら辺はAutoLayoutと似てますね
  73. didUpdateFocusはFocusされる時に呼ばれます
  74. FocusEnvironmentのチェーンを辿って呼び出されていきます
  75. 最後に tvOS11で追加されたsoundIdentifierForFocusUpdateですがこれを使うとフォーカス時の音を個別に変更できるようになります
  76. はい、FocusEnvironmentに準拠しているクラスですが、
  77. UIView, UIViewController, UIPresentationControllerがあります
  78. 先程図にでてきましたが、FocusされるものはUIFocusItemプロトコルに準拠している必要があり、canBecomeFocusedを実装してあります。
  79. デフォルトでフォーカスされるものはUIButton, UITextField、TableView, CollectionViewなどがあります。
  80. 他にもtvOS10からはspriteKitのSKNode、tvOS11からはSceneKit のSCNNode などもあります
  81. UILabelをフォーカスできるようにする例です canBecomeFocusedをoverrideしてtrueを返します
  82. didUpdateFocusもoverrideしてフォーカス時の動きを付けます
  83. フォーカス時にtransform scaleを1.4にして
  84. アンフォーカス時にtransformを戻します
  85. この実装で、このようなLabelを作ることができます
  86. UITableViewとUICollectionViewのフォーカスですが、
  87. Focus用のDelegatがtvOS用にあります
  88. tableviewですが、 フォーカス可能かどうかのcanFocusRowAt IndexPath フォーカスするべきかどうかのshouldUpdateFocusIn Context フォーカス時のdidUpdateFocusIn Context フォーカスエンジンに指定するindexPathForPreferredFocusedView の4つがtvOS用に追加されています
  89. collectionViewもtableViewと同様のものプラスで、cellの移動やanimation時のdelegateがtvOS用に追加されています
  90. あとはremembersLastFocusedIndexPathというpropertyがあり これは例えばtableViewから別のViewに移動後、またtableViewに戻った時に前回のindexにフォーカスしたい場合にtrueにしておきます
  91. はい、次にUIImageViewのフォーカスですが
  92. フォーカス用のUIImageのpropertyがあります
  93. adjustsImageWhenAncestorFocusedをtrueにするとフォーカス時の拡大/縮小とparallaxアニメーションがつきます
  94. あとはtvOS11から追加されたoverlayContentViewですが、
  95. このようなadjustsImageWhenAncestorFocusedがtrueのimageViewが並んでる画面で、画像にblack alpha0.5のviewをかぶせて、フォーカス時は外したい場合の例です。 tvOS10までだとフォーカス時の拡大縮小やparallaxが合わせるのが大変で、画像を合成したりしてけっこう手間なのですが、tvOS11以降はこれを使うと簡単にできます
  96. コードの例になります
  97. overlay用のviewをoverlayContentViewにaddSubViewして
  98. collectionViewのdidUpdateFocusのdelegateでoverlayContentViewを表示/非表示します
  99. フォーカス時にoverlayContentViewのalphaを0にして
  100. アンフォーカス時にoverlayContentViewのalphaを1に戻します
  101. この例のようにprogressViewを被せたい場合など、何か画像に被せたい場合に便利です
  102. 次にtvOS11でフォーカス用のNotificationが追加されています
  103. フォーカスさてた時のNotificationと
  104. フォーカスの移動に失敗した時のNotificationです
  105. 最後にUIFocusGuideについてです
  106. UIFocusGuideはフォーカス用のガイドで、UILayoutGuideを継承していて、フォーカス用にpreferredFocusEnvironmentsが定義されています
  107. 例えばこのような画面で
  108. このCellからButtonへのフォーカスは
  109. できるのですが、
  110. こちらのCellからButtonの場合
  111. デフォルトだとフォーカスできません これは先程説明しましたが、Focus Engineが検索する範囲は、現在FocusされているViewの大きさに応じて決まるからです
  112. この場合にFocusGuideを追加ます FocusGuideをcollectionViewと同じ横幅で置き
  113. preferredFocusEnvironmentsでbuttonを返すようにします
  114. そうすると右の方からもfocusが可能になります
  115. コードの例です
  116. フォーカスガイドを作成してviewに追加します
  117. topAnchorをbuttonのtopAnchorにleftAnchorをcollectionViewのleftAnchorにします
  118. heightをbuttonのheightAnchor、widthをcollectionViewのwidthAnchorにして
  119. preferredFocusEnvironmentsにbuttonを設定します レイアウトの指定はNSLayoutAnchorと同じような感じになります
  120. Focusがうまくいかな場合は、canBecomeFocusedがfalseじゃないか、isHiddenがtrueになってないかなど基本的なことをまずチェックするとよいと思います。
  121. あとtvOS11からdebug機能が強化されています
  122. UIFocusUpdateLoggingEnabled YESを設定するとFocusに関するログがはかれるようになります
  123. これは起動時のログですが、フォーカスエンジンの初期フォーカス決定のpreferredFocusチェーンのログがはかれています
  124. あとはLLDBからUIFocusDebuggerを使ってdebugできます focusのstatusを確認できたり
  125. フォーカス更新をシミュレートしたり
  126. viewがフォカースできるか確認できたりと デバッグの機能も強化されて開発しやすくなっています
  127. はい、最後にまとめです
  128. - まず、標準のUI/UXに準拠しましょう、ということで基本的にtvOSはリモコンを使って操作するので、iOSほど自由度もなく、他のアプリも標準のUIを採用しているところが多いので、準拠しておくと無難です。 - 次にiOSとの違いはFocusということで、今日いくつか説明させていただきましたがfocus周りは少し癖があります。 -最後、tvOS対応は難しくないということで、フォーカスさえ押さえておけば普段iOS開発をしている方はすんなり開発できるのではないかと思います。最近けっこう日本のtvOSアプリも増えてきているので、いちユーザーとして嬉しく思っています
  129. はい、以上になります。 ありがとうございました!