Retina mac

2,083 views

Published on

1 Comment
0 Likes
Statistics
Notes
  • Be the first to like this

No Downloads
Views
Total views
2,083
On SlideShare
0
From Embeds
0
Number of Embeds
831
Actions
Shares
0
Downloads
16
Comments
1
Likes
0
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Retina mac

    1. 1. 如何支援 Mac OS X 的高解析度模式 楊維中 a.k.a zonble
    2. 2. 萬惡的根源
    3. 3. 開發環境• MacBook Pro 2012• 沒有新機器怎麼辦?• 使用模擬環境
    4. 4. 模擬環境
    5. 5. 模擬環境
    6. 6. 模擬環境Quartz Debug
    7. 7. 模擬環境
    8. 8. 模擬環境
    9. 9. 如何支援?• 使用兩倍圖• 改用向量圖形
    10. 10. 使用兩倍圖• 跟 iOS 一樣• 所有用到的圖片 的 名加上 @2x,然後加到
    11. 11. 使用向量圖• 向量圖 格式很 多:Adobe Illustrator、 Corel Draw、 SVG…• Mac OS X 系統 支援的向量格
    12. 12. Core Animation• CALayer 必須要手動調整屬性,才有辦 法支援 Retina Display• contents 直接給 @2x 圖片是沒用的• 必須手動設定 contentScale
    13. 13. iOS 上面• aLayer. contentsScale = [UISCreen mainScreen].scale• 反正一般來說,我們的 UI 只會出現在 mainScreen 上。雖然可以外接投影機, 使用另外一個 UIScreen,但是一般不會 有人去寫 種 App
    14. 14. Mac OS X• CALayer 不一定會出現在 個 Screen 裡頭,而是要由 目前 layer 所在的 Window 決定是否要使用高解析度 • 詢問 NSWindow 的 -backingScaleFactor• Window 還可以在不同 Screen (主螢幕、延伸螢幕) 之間移動 • contentsScale 需要隨時改變• 還有…向下相容,你應該不會只支援 10.7.4 以上的系 統
    15. 15. 改變解析度的時機• Layer 被放到某個 Window 的時候• 因為 Window 移動而造成 Window 的 scale 改變的時候(Notification)• 以下範例是假設 rootLayer 個物件被擺 在某個 NSView 裡頭
    16. 16. Layer 被放到某個- (void)viewDidMoveToWindow { if ([rootLayer respondsToSelector:@selector(contentsScale)]) {// 舊版的 OS 的 CALayer 不一定會有 contentsScale// 舊版的 OS 的 Window 也不一定會有 backingScaleFactor… CGFloat scale = [(id)[self window] backingScaleFactor]; [(id)rootLayer setContentsScale:scale]; }}
    17. 17. 訂閱 Window 移動而• 訂閱 NSWindowDidChangeBackingPropertiesN otification• 但因為舊版系統沒有,所以直接訂閱字 串 @” NSWindowDidChangeBackingPropertiesN otification”
    18. 18. 訂閱 Window 移動而• 在 viewDidMoveToWindow 訂閱• 在 removeFromSuperview 取消• 我們先來把剛剛那段修改 contentsScale 的程式拆出來
    19. 19. 拆出來的 private- (void)_updateContentScale { if (![self window]) { return; } if ([rootLayer respondsToSelector:@selector(contentsScale)]) { CGFloat scale = [(id)[self window] backingScaleFactor]; [(id)rootLayer setContentsScale:scale]; }}
    20. 20. 訂閱通知- (void)viewDidMoveToWindow { [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(scaleDidChange:) name:@"NSWindowDidChangeBackingPropertiesNotification"object:[self window]]; [self _updateContentScale];}- (void)removeFromSuperview { [super removeFromSuperview]; [[NSNotificationCenter defaultCenter] removeObserver:self];}- (void)scaleDidChange:(NSNotification *)n { [self _updateContentScale];}
    21. 21. 向下相容• 用舊版的 SDK 編譯,compiler 會跟你抱 怨沒有 contentsScale 與 backingScaleFactor… 很討厭
    22. 22. 為了向下相容弄出來@interface NSObject (RetinaDisplay)- (void)setContentsScale:(CGFloat)inScale;- (CGFloat)backingScaleFactor;@end
    23. 23. That’a all!

    ×