Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Retina Mac

Retina Mac

Weizhong Yang

August 26, 2012
Tweet

More Decks by Weizhong Yang

Other Decks in Technology

Transcript

  1. 如何⽀支援 Mac OS X
    的⾼高解析度模式
    楊維中 a.k.a zonble
    [email protected]
    Sunday, August 26,

    View Slide

  2. 萬惡的根源
    Sunday, August 26,

    View Slide

  3. 開發環境
    • MacBook Pro 2012
    • 沒有新機器怎麼辦?
    • 使⽤用模擬環境
    Sunday, August 26,

    View Slide

  4. 模擬環境
    Sunday, August 26,

    View Slide

  5. 模擬環境
    Sunday, August 26,

    View Slide

  6. 模擬環境
    Quartz Debug
    Sunday, August 26,

    View Slide

  7. 模擬環境
    Sunday, August 26,

    View Slide

  8. 模擬環境
    Sunday, August 26,

    View Slide

  9. Sunday, August 26,

    View Slide

  10. 如何⽀支援?
    • 使⽤用兩倍圖檔
    • 改⽤用向量圖形
    Sunday, August 26,

    View Slide

  11. 使⽤用兩倍圖檔
    • 跟 iOS ⼀一樣
    • 所有⽤用到的圖⽚片
    的檔名加上
    @2x,然後加到
    應⽤用程式中
    Sunday, August 26,

    View Slide

  12. 使⽤用向量圖
    • 向量圖檔格式很
    多:Adobe
    Illustrator、
    Corel Draw、
    SVG…
    • Mac OS X 系統
    ⽀支援的向量格
    式,簡單,就是
    PDF
    Sunday, August 26,

    View Slide

  13. Core Animation
    • CALayer 必須要⼿手動調整屬性,才有辦
    法⽀支援 Retina Display
    • contents 直接給 @2x 圖⽚片是沒⽤用的
    • 必須⼿手動設定 contentScale
    Sunday, August 26,

    View Slide

  14. iOS 上⾯面
    • aLayer. contentsScale = [UISCreen
    mainScreen].scale
    • 反正⼀一般來說,我們的 UI 只會出現在
    mainScreen 上。雖然可以外接投影機,
    使⽤用另外⼀一個 UIScreen,但是⼀一般不會
    有⼈人去寫這種 App
    Sunday, August 26,

    View Slide

  15. Mac OS X
    • CALayer 不⼀一定會出現在哪個 Screen 裡頭,
    ⽽而是要由⺫⽬目前 layer 所在的 Window 決定是否
    要使⽤用⾼高解析度
    • 詢問 NSWindow 的 -backingScaleFactor
    • Window 還可以在不同 Screen (主螢幕、延
    伸螢幕)之間移動
    • contentsScale 需要隨時改變
    • 還有…向下相容,你應該不會只⽀支援 10.7.4
    以上的系統
    Sunday, August 26,

    View Slide

  16. 改變解析度的時機
    • Layer 被放到某個 Window 的時候
    • 因為 Window 移動⽽而造成 Window 的
    scale 改變的時候(Notification)
    • 以下範例是假設 rootLayer 這個物件被擺
    在某個 NSView 裡頭
    Sunday, August 26,

    View Slide

  17. Layer 被放到某個
    Window 的時候
    - (void)viewDidMoveToWindow {
    if ([rootLayer respondsToSelector:@selector(contentsScale)]) {
    // 舊版的 OS 的 CALayer 不⼀一定會有 contentsScale
    // 舊版的 OS 的 Window 也不⼀一定會有 backingScaleFactor…
    CGFloat scale = [(id)[self window] backingScaleFactor];
    [(id)rootLayer setContentsScale:scale];
    }
    }
    Sunday, August 26,

    View Slide

  18. 訂閱 Window 移動⽽而
    解析度改變的通知
    • 訂閱
    NSWindowDidChangeBackingPropertiesN
    otification
    • 但因為舊版系統沒有,所以直接訂閱字
    串 @”
    NSWindowDidChangeBackingPropertiesN
    otification”
    Sunday, August 26,

    View Slide

  19. 訂閱 Window 移動⽽而
    解析度改變的通知
    • 在 viewDidMoveToWindow 訂閱
    • 在 removeFromSuperview 取消
    • 我們先來把剛剛那段修改 contentsScale
    的程式拆出來
    Sunday, August 26,

    View Slide

  20. 拆出來的 private
    method
    - (void)_updateContentScale {
    if (![self window]) {
    return;
    }
    if ([rootLayer respondsToSelector:@selector(contentsScale)]) {
    CGFloat scale = [(id)[self window] backingScaleFactor];
    [(id)rootLayer setContentsScale:scale];
    }
    }
    Sunday, August 26,

    View Slide

  21. 訂閱通知
    - (void)viewDidMoveToWindow {
    [[NSNotificationCenter defaultCenter] addObserver:self
    selector:@selector(scale
    DidChange:) name:@"NSWindowDidChangeBackingPropertiesNotification"
    object:[self window]];
    [self _updateContentScale];
    }
    - (void)removeFromSuperview {
    [super removeFromSuperview];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    }
    - (void)scaleDidChange:(NSNotification *)n {
    [self _updateContentScale];
    }
    Sunday, August 26,

    View Slide

  22. 向下相容
    • ⽤用舊版的 SDK 編譯,compiler 會跟你抱
    怨沒有 contentsScale 與
    backingScaleFactor… 很討厭
    Sunday, August 26,

    View Slide

  23. 為了向下相容弄出來
    的⻤⿁鬼 Category…
    @interface NSObject (RetinaDisplay)
    - (void)setContentsScale:(CGFloat)inScale;
    - (CGFloat)backingScaleFactor;
    @end
    Sunday, August 26,

    View Slide

  24. That’a all!
    Sunday, August 26,

    View Slide