ラベル xcode6 の投稿を表示しています。 すべての投稿を表示
ラベル xcode6 の投稿を表示しています。 すべての投稿を表示

2015年5月6日水曜日

Core Animation Lesson.(カスタム描画/Lesson1-7)

Core Animation Lesson.(Lesson1-7)
カスタム描画.(Lesson1-7)

CALayerのcontentsプロパティを設定するとこだけが背景画像を描画する方法では有りません。UIViewのdrawRectメソッドを実装する事でCoreGraphicsやUIKitを利用し、ダイレクトに背景画像を描画することができます。drawRectメソッドにはデフォルト実装が有りませんが、Viewが最初に表示された時に一度呼び出され、以降は更新が必要になった場合に自動的に呼び出されます。明示的に再描画が必要な時はsetNeedsDisplayを呼び出す事で再描画が行われますので、再描画したいからといってコード内からdrawRectメソッドを直接呼び出してはいけません。

drawRectメソッドの実装

UIViewクラスを継承した新しいクラスを作成し、Storyboard上でViewを配置しCustomクラスとして新しく作成したクラスを指定します。

図. カスタムクラスの設定
drawRectメソッドでは、青色に塗りつぶされた楕円を描画するコードになっています。(以下コード)
class Lesson1_7View: UIView {

    // custom draw
    override func drawRect(rect: CGRect) {
        // get context
        let context: CGContext! = UIGraphicsGetCurrentContext()
        
        // draw with context
        // set fill color
        CGContextSetFillColorWithColor(context, UIColor.blueColor().CGColor)
        // draw ellpise in rect
        CGContextFillEllipseInRect(context, rect)

    }
}
図. カスタム描画
独自に追加したレイヤへのカスタム描画

CALayerにはdelegateプロパティが存在します。それがCALayerDelegateで、displayLayerとdrawLayer メソッドが定義されています。iOSの場合はUIViewを新たに作成するとCALayerも必ず生成されます。この予め生成されているCALayerの場合はUIView側でCALayerDelegateが実装されているため、改めて個別に実装する必要はありません。素直にdrawRectメソッドを実装すれば良いでしょう。

逆に新たに作成したCALayerでカスタム描画したい場合にCALayerDelegateを実装する必要があります。因みに、CALayerDelegateはCALayerクラスにNSObjectのエクステンション(カテゴリ)で定義されており、リファレンスにはInformal Protocolと表現されています。ですので、明示的にCALayerDelegateを採用するコード(クラス定義)を書く必要は無いようです。

extension NSObject {
    
    /* If defined, called by the default implementation of the -display
     * method, in which case it should implement the entire display
     * process (typically by setting the `contents' property). */
    
    func displayLayer(layer: CALayer!)
    
    /* If defined, called by the default implementation of -drawInContext: */
    
    func drawLayer(layer: CALayer!, inContext ctx: CGContext!)
    
    /* Called by the default -layoutSublayers implementation before the layout
     * manager is checked. Note that if the delegate method is invoked, the
     * layout manager will be ignored. */
    
    func layoutSublayersOfLayer(layer: CALayer!)
    
    /* If defined, called by the default implementation of the
     * -actionForKey: method. Should return an object implementating the
     * CAAction protocol. May return 'nil' if the delegate doesn't specify
     * a behavior for the current event. Returning the null object (i.e.
     * '[NSNull null]') explicitly forces no further search. (I.e. the
     * +defaultActionForKey: method will not be called.) */
    
    func actionForLayer(layer: CALayer!, forKey event: String!) -> CAAction!
}
コード. CALayerクラス内にあるエクステンション定義(Swift)

CALayerはdelegateが設定されているかを調べます。そして、設定されている場合はdisplayLayerメソッドが実装されているか確認します。実装されている場合は呼び出しを行い、もしdisplayLayer実装されていなかった場合はさらにdrawLayerメソッドが実装されているか確認し、実装されている場合はdrawLayerメソッドを呼び出します。
要するに、displayLayer → drawLayer の順で呼び出されるわけですが、displayLayerが実装されている場合はdrawLayerが実装されていても、呼び出されませんので注意が必要です。

新たにCALayerを作成して、そのレイヤをカスタム描画してみます。新たに作成したレイヤには赤色の円を描いています。

図. 独自に追加したレイヤのカスタム描画
class Lesson1_7ViewController: UIViewController {
    @IBOutlet weak var myView: Lesson1_7View!
    
    private var newLayer: CALayer!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // create new layer
        newLayer = CALayer()
        newLayer.frame = CGRectMake(0, 0, 100, 100)
        newLayer.contentsScale = UIScreen.mainScreen().scale
        // set delegate
        newLayer.delegate = self
        
        // add new layer to uiview hosted layer
        myView.layer.addSublayer(newLayer)
        
        // display new layer
        newLayer.display()
    }
    
    override func viewDidDisappear(animated: Bool) {
        // clean up
        newLayer.delegate = nil
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

/***
    override func displayLayer(layer: CALayer!) {
        //
    }
***/
    
    override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
        NSLog("perform drawLayer.")
        //
        CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
        CGContextFillEllipseInRect(ctx, layer.frame)
    }
}

以下コードが新しいレイヤを作成し、delegateを設定しています。

// create new layer
newLayer = CALayer()
newLayer.frame = CGRectMake(0, 0, 100, 100)
newLayer.contentsScale = UIScreen.mainScreen().scale

// set delegate
newLayer.delegate = self

そして、以下がカスタムコード描画部分です。CGContextオブジェクトが引数にあるので、drawLayerメソッドの方を実装しています。drawLayerを呼び出したいため、displayLayerメソッドはコメントアウトにしています。

override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
    NSLog("perform drawLayer.")
    //
    CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)
    CGContextFillEllipseInRect(ctx, layer.frame)
}



今回使用したサンプルプログラムはGithub上のCoreAnimationLessonに置いています。


AD.

2015年4月12日日曜日

Core Animation Lesson.(Lesson1-4〜)

前回(Core Animation Lesson1(Lesson1-1〜)) から引き続きCALayerのプロパティについて調査しました。

contentsScaleプロパティ(CALayer)

本プロパティ値はレイヤ上の背景画像とView上のピクセルサイズ比率を定義するプロパティです。要するにRetinaディスプレイか否かを設定します。contentsScaleの値は通常のディスプレイで1.0を指し、Retinaディスプレイの場合は2.0となります。デフォルト値は1.0です。 この値は以下の様にUIScreenクラスから取得するのが一般的のようです。

    // set contentsScale to The Retina value
    myView.layer.contentsScale = UIScreen.mainScreen().scale

但し、CALayerのcontentsGravityにfill/fit系の拡大縮小のオプションを指定している場合、contentsScaleの値意味を持たなくなるので、注意が必要です。

表. CALayerのcontentsScaleの値について
contentsScale 概要
1.0 1Pointが1Pixcelの通常ディスプレイを指す。
2.0 1Pointが2x2(4Pixcels)のRetinaディスプレイを指す。


下の表示イメージは同一画像をRetina/非Retinaで表示してみた例です。
図. Retinaディスプレイ[←左図](contentsScale=2.0)と
非Retinaディスプレイ[右図→](contentsScale=1.0)
masksToBoundsプロパティ(CALayer)

Viewよりも大きい画像はViewからはみ出して表示されてしまいますが、CALayerのmasksToBoundsプロパティを設定することで抑止できます。値はBool値でtrueが設定されるとマスクされます。また、このプロパティはUIViewのclipesToBindsプロパティと同等の機能となります。

図. masksToBounds=false

図. masksToBounds=true


以下、サンプルコードです。SegmentedControlボタンでcontentsScale, SwitchボタンでmasksToBoundsのオンオフを設定しています。

import UIKit

class Lesson1_4ViewController: UIViewController {

    @IBOutlet weak var myView: UIView!
    @IBOutlet weak var mySegmentedControl: UISegmentedControl!
    @IBOutlet weak var mySwitch: UISwitch!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        
        // image
        let image = UIImage(named: "chess.png")
        myView.layer.contents = image?.CGImage
        myView.layer.contentsGravity = kCAGravityCenter
        
        // set default contentsScale to The Retina value
        myView.layer.contentsScale = UIScreen.mainScreen().scale
        // set default clip setting
        myView.layer.masksToBounds = true
        
        // set action for segmented control
        mySegmentedControl.addTarget(self, action: "segmentedValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
        // set action for switch
        mySwitch.addTarget(self, action: "switchValueChanged:", forControlEvents: UIControlEvents.ValueChanged)
        
        // dump contentsScale
        println("contentsScale : \(myView.layer.contentsScale)")
        println("image Scale   : \(image?.scale)")
        println("UIScreen scale: \(UIScreen.mainScreen().scale)")
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
    func segmentedValueChanged(target: UISegmentedControl) {
        if (target.selectedSegmentIndex == 0) {
            myView.layer.contentsScale = 1.0
            
        } else {
            myView.layer.contentsScale = 2.0
            
        }
    }
    
    func switchValueChanged(target: UISwitch) {
        if target.on {
            myView.layer.masksToBounds = true
        } else {
            myView.layer.masksToBounds = false
        }
    }
}
contentsRectプロパティ(CALayer)

指定された範囲をクリップするイメージですが、大きな画像ファイルに小さいイメージをパックする事で、小さいイメージを個々に読み込むより、大きなファイルを一回だけ読み込ませる方が読み込み時間、使用メモリ量のパフォーマンスに優れています。ゲームの様に小さな画像を多数使用する場合にメリットが大きい様です。また、contentsRectの単位はpoint単位では無くunit coordinate単位であることにも注意が必要です。

以下の図は、1枚の画像ファイルにAとBが横並びで描画されています。その画像ファイルを1回だけ読み込み、contentsRectプロパティを利用し元画像の必要な部分(AとB)をクリッピングし縦並びで表示しています。


以下、ソースコードですが、CALayerのcontentsには元画像を設定しcontentsRectプロパティにてそれぞれ必要な領域を指定しています。contentsRectはCGRect型で指定する値はUnitCoordinate単位となります。UnitCoordinate単位については後述します。

import UIKit

class Lesson1_5ViewController: UIViewController {

    @IBOutlet weak var viewA: UIView!
    @IBOutlet weak var viewB: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        // load image once.
        let image = UIImage(named: "AB.png")
        
        // A
        viewA.layer.contents = image?.CGImage
        viewA.layer.contentsRect = CGRectMake(0, 0, 0.5, 1.0)
        
        // B
        viewB.layer.contents = image?.CGImage
        viewB.layer.contentsRect = CGRectMake(0.5, 0, 0.5, 1.0)
        
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
Point, Unit単位について
表. Point, Unit単位について
Coordinate Type 概要
Point Pointは仮想的なPixelであり、デバイスの解像度によって変化する。通常デバイスでは1Pointが1Pixelとなるが、Retina Display では、2x2の計4Pixelsとなる。
Unit Unit単位は0.0〜1.0まで指定可能な比率で指定する便利な指定方法で、1.0が100%のサイズを意味している。比率で指定しているため、元の画像のサイズが変更されても再調整する必要が無いのが利点。

以下図はUnit単位を表しています。右下が最大値である(1, 1)を表し、中心点は(0,5, 0,5)となります。

図. Unit単位について
contentsCenterプロパティ(CALayer)

このプロパティは、プロパティ名から想像される機能と異なり、イメージの伸縮エリアについての設定が行われます。これは、インターフェースビルダーからも設定可能な値で、デフォルト値はUnit単位で(0,0,1,1)となり全域が一様に伸縮する設定となっています。contentCenterで指定した矩形の外側はそれぞれの位置により伸縮の方向が異なります。

以下のイメージを考えてみます。分かりやすいように方眼紙のようなマス目をが描かれているイメージを描画しています。この画像イメージにcontentsCenterプロパティを指定してみます。

図(↓)contentsCenterとして(0.25, 0.25, 0.5, 0.5)を指定しました。方眼紙のイメージで分かりやすいかと思ったのですが、全然分かり難いですね。良く見てみると分かりますが、方眼紙のマス目の高さや幅ががcontentsCenterで指定した矩形内と外で異なっていることに気づくと思います。

図(↓)contentsCenterで指定した矩形枠内と外での引き伸ばしについて、赤枠は縦横均等、緑は縦、青は横、黄色は無しとなっています。

contentsCenterはViewのプロパティとしてGUIからも設定可能です。


今回使用したサンプルプログラムはGithub上のCoreAnimationLessonに置いています。


2015年3月16日月曜日

Core Animation Lesson.(Lesson1)

Core Animationに関して、画像、座標、エフェクト、トランスフォーム、アニメーション等をシリーズ化してまとめていきたいと考えています。

Core Animationとは

Core Animationと聞くと、なにかアニメーションに特化した小難しいFrameworkのような印象を受けてしまいますが、アニメーション自体はCore Animationが提供する数ある特徴の一部であり、アニメーションだけに特化したFrameworkではありません。Core Animationはビジュアルコンテンツを画面描画する機能群から構成された共通基盤で、より高速に動作するよう設計されています。

UIViewとCALayer

Core Animation はどの様にして使うのでしょうか。それは、UIViewクラスで既に使用されています。 UIViewは、画像やテキスト、動画等のコンテンツの描画、タッチやジェスチャー入力に対応するクラスで、subviewとして子のViewを階層構造で管理しています。加えて、Core Graphicsベースの描画、アファイン変換(回転や拡大縮小)と簡単なアニメーションをサポートします。それら機能はCore AnimationのCALayerというクラスにより提供されています。

CALayerはUIViewととても良く似たコンセプトで設計されています。UIViewは矩形のオブジェクトでViewを階層構造で管理可能です。同様にCALayerも矩形オブジェクトであり、Layer自身に子のLayerをsublayersとして追加することが可能で親子関係を構築する事が出来ます。

Viewの階層構造イメージ図(View Debuggingしただけですが)

CALayerがUIViewと大きく異なっている点は、CALayer自身はレスポンダチェインに属さないために、タッチイベントを処理出来ないことに加えて、主に以下の特徴が挙げられます。

CALayerの主な特徴
  • ドロップシャドウ、角丸、カラードボーダー
  • 3D座量変換、ポジショニング
  • アルファマスク
  • マルチステップ、非連続的なアニメーション
※これら機能は改めて紹介したいと思います。
背景描画について(Lesson1)

CALayerを使用した背景色・背景画像の表示と、背景画像の見せ方(表示位置・拡大/縮小)に関するUIView及びCALayerのプロパティ値について。

単色背景の描画(Lesson1-1)

それでは、CALayerを使用して背景を描画してみましょう。UIViewを生成すると、iOSの場合デフォルトで必ず1つCALayerが生成されます。そのCALayerは使用せずに、新たに一つCALayerを生成して描画してみます。

青色の固定サイズの矩形を明示的に新しいCALayerを作成して、青色の背景色を設定します。CALayerのaddSublayerメソッドで新しいLayerを追加します。 サンプル実装ではUIVIew を1つ追加し、その上に描画します。

import UIKit

class Lesson1_1ViewController: UIViewController {
    @IBOutlet weak var myView: UIView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // create new layer
        let myLayer = CALayer()
        myLayer.frame = CGRectMake(10, 10, 200, 200)
        myLayer.backgroundColor = UIColor.blueColor().CGColor

        // add new layer to backing layer
        myView.layer.addSublayer(myLayer)
        
    }
}

CALayerのbackgroundColorプロパティはUIViewクラスのそれがUIColor?型であるのと違い、CGColor!型であることに注意して下さい。

画像の描画(Lesson1-2)

それでは簡単な画像を描画してみます。画像はUIImageのインスタンスを作成し、そのCGImageプロパティ値をCALayerのcontentsプロパティへ設定しているだけです。Lesson1-1と違ってCALayerはUIViewで暗黙的に作成されたCALayerを使用しています。このレイヤはUIViewクラスのlayerプロパティで参照することが出来ます。因みに、画像はチェスの駒です。

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // initialize segmented control
        mySegmentedControl.addTarget(self, action: "segmentedValueChanged:", forControlEvents: UIControlEvents.ValueChanged)


        // image content
        let image = UIImage(named: "chess.png")
        
        // set image to layer contents
        myView.layer.contents = image?.CGImage
        
    }

残念なことに、よく見てみると駒が少し太って表示されていることに気付くと思います。 画像を枠内にどのように表示するかはUIViewクラスのcontentModeプロパティで設定することが出来ます。この値は、UIViewContentMode列挙型で定義されていて、デフォルトはScaleToFillとなっているため画面一杯に表示されることになります。正しい比率を維持したまま画面に表示するにはScaleAspectFitを設定すると良いでしょう。

myView.contentMode = UIViewContentMode.ScaleAspectFit
枠内にフィットするように画像サイズを自動調整(アスペクト比は維持)

UIViewContentModeの各値は以下の様に定義されています。詳細はドキュメントを参照下さい。

enum UIViewContentMode : Int {
    case ScaleToFill    // default 
    case ScaleAspectFit // 枠内にフィットするように自動調整(同アスペクト比)
    case ScaleAspectFill// 枠内を埋めるように自動調整(同アスペクト比)
    case Redraw
    case Center
    case Top
    case Bottom
    case Left
    case Right
    case TopLeft
    case TopRight
    case BottomLeft
    case BottomRight
}
UIViewContentMode.ScaleAspectFill
UIViewContentMode.Center
UIViewContentMode.Bottom
CALayerによる画像サイズ調整(Lesson1-3)

Lesson1-2ではUIViewクラスのcontentModeプロパティにより画像表示を調整しましたが、CALayerクラスにも同様のプロパティ値が存在します。それが、contentsGravityプロパティです。 contentsGravityはNSString型で定義されています。 正しい比率を維持したまま画面に表示するにはkCAGravityResizeAspectを指定します。

let kCAGravityCenter: NSString!
let kCAGravityTop: NSString!              // NOTICE!
let kCAGravityBottom: NSString!           // NOTICE!
let kCAGravityLeft: NSString!
let kCAGravityRight: NSString!
let kCAGravityTopLeft: NSString!
let kCAGravityTopRight: NSString!
let kCAGravityBottomLeft: NSString!
let kCAGravityBottomRight: NSString!
let kCAGravityResize: NSString!           // default
let kCAGravityResizeAspect: NSString!     // 枠内にフィットするように自動生成(同アスペクト比)
let kCAGravityResizeAspectFill: NSString! // 枠内を埋めるように自動調整(同アスペクト比)

しかし、kCAGravityTop, kCAGravityBottom を指定すると表示が上下逆になることに気付きます。これはiOSとOS XによるデフォルトのY軸の向きが異なることが原因で、iOSの場合は左上、OS Xの場合は左下が起点となります。 geometryFlippedプロパティをtrueに設定すれば思った通りの結果になるはずです。

iOS/OS XのY軸向きの違い

続きは次回。次回はCALayerのプロパティであるcontentsScale/masksToBounds/contentsRect/contentsCenter について調査したいと考えています。

説明に使用したサンプル・アプリケーションはGitHub上のCoreAnimationLessonとして配置していますので、参考にどうぞ。今後CoreAnimationに関するサンプルは本リポジトリ上に実装していく予定です。


2014年10月16日木曜日

Xcode6でView Debuggingすると必ずkernel panicになる場合の対処法

View Debuggingを行い、3Dローテーションすると落ちる

Xcode6の新機能であるView Debuggingですが、私の環境だと必ずkernel panicが発生しOSごと落ちてしまいます。(再現率100%)

カーネルパニック時のログ(一部抜粋)
panic(cpu 0 caller 0xffffff800cedc43e): Kernel trap at 0xffffff7f8e882115, type 14=page fault, registers:
CR0: 0x000000008001003b, CR2: 0x00000000000089f4, CR3: 0x0000000022d92000, CR4: 0x0000000000000660
RAX: 0x0000000020000901, RBX: 0x00000000000000fc, RCX: 0x0000000000000000, RDX: 0xffffff80ffd92c30
RSP: 0xffffff81182cb8b0, RBP: 0xffffff81182cb8e0, RSI: 0x0000000000000000, RDI: 0x0000000000000000
R8:  0xffffff8100386000, R9:  0x0000000000010000, R10: 0x00000000000000b6, R11: 0x00000000000000b6
R12: 0xffffff80df56c000, R13: 0xffffff80df570813, R14: 0x0000000000000000, R15: 0xffffff81182cb9f8
RFL: 0x0000000000010202, RIP: 0xffffff7f8e882115, CS:  0x0000000000000008, SS:  0x0000000000000010
Fault CR2: 0x00000000000089f4, Error code: 0x0000000000000000, Fault CPU: 0x0

Backtrace (CPU 0), Frame : Return Address
0xffffff81182cb540 : 0xffffff800ce22f79
0xffffff81182cb5c0 : 0xffffff800cedc43e
0xffffff81182cb790 : 0xffffff800cef3976
0xffffff81182cb7b0 : 0xffffff7f8e882115
0xffffff81182cb8e0 : 0xffffff7f8e84efea
0xffffff81182cba60 : 0xffffff7f8e87e940
0xffffff81182cbb20 : 0xffffff7f8e84dad9
0xffffff81182cbb70 : 0xffffff800d2cf146
0xffffff81182cbb90 : 0xffffff800d2d0741
0xffffff81182cbbf0 : 0xffffff800d2ce1af
0xffffff81182cbd40 : 0xffffff800ceb6998
0xffffff81182cbe50 : 0xffffff800ce26bc1
0xffffff81182cbe80 : 0xffffff800ce139c5
0xffffff81182cbef0 : 0xffffff800ce1e013
0xffffff81182cbf70 : 0xffffff800cec9b9d
0xffffff81182cbfb0 : 0xffffff800cef4196
      Kernel Extensions in backtrace:
         com.apple.GeForceTesla(8.2.4)[B0074750-2FC6-3E26-BEA0-5AD5469686CF]@0xffffff7f8e83c000->0xffffff7f8e906fff
            dependency: com.apple.iokit.IOPCIFamily(2.9)[2852ACFE-FD28-3C37-9B39-885201BB8D25]@0xffffff7f8d4bf000
            dependency: com.apple.iokit.IONDRVSupport(2.4.1)[D41125CE-69BD-32E7-9B1D-4E83431662DD]@0xffffff7f8d8e0000
            dependency: com.apple.iokit.IOGraphicsFamily(2.4.1)[75D81741-64C1-3941-ADFA-9D6B6C434EE4]@0xffffff7f8d89d000
            dependency: com.apple.nvidia.classic.NVDAResmanTesla(8.2.4)[D61B2BB9-4289-318D-9197-5E1E13B1FF32]@0xffffff7f8d8f0000

BSD process name corresponding to current thread: Xcode
恐らくNVIDIAのGPUドライバが原因っぽいですね。
発生対象と対処

ネットで調べてもあまり同様の事象を発見出来なかったことから、あまり多くのユーザでは発生していないか、View Debuggingが使われていないかのどちらかと思います。まあ、前者でしょうか。 私のPCはMacBook Pro 15-inch, Mid 2010 で、この端末はGPUとしてIntelの統合グラフィックスとNVIDIAのGPUの2つ載っており、必要に応じて自動的に切り替えられています。 NVIDIAのGPUはGeForce GT 330Mが使用されています。 kernel panic時のログからNVIDIAのGPUドライバで落ちていることはわかっているので、Intel統合グラフィックスに固定してあげればこの問題を回避できるというわけです。 GPUの切り替えはユーティリティを利用します。gfxCardStatusというユーティリティが良いでしょう。Google ChromeやTwitterアプリなどはデフォルトでNVIDIAの高性能GPUを使用するので、Intel統合グラフィックスを 利用するにはアプリケーションを終了する必要があることに注意して下さい。私はこれで切り替えてからView Debuggingしたら見事に動作しました。

gfxCardStatusを起動するとメニューバーに常駐するので、以下のように統合グラフィックスを固定で使用するように指定します。この際、高性能GPUで動作しているアプリケーションが存在するとエラーダイアログが表示され、対象のアプリケーションを教えてくれます。
Xcode6でView Debuggingを起動(上段のキャプチャ)。グリグリ動きます(下段のキャプチャ)

あ〜、新しいマシン欲しいな〜。

2014年10月5日日曜日

Xcode6ではStoryboardで指定するSegue名が変更されている

Storyboardで指定するSegue(セグエ)名

Xcode6ではSegue名が変更され、以前まで使用していたpush, modal等のSegueはDeprecated Segueとなり非推奨となってしまいました。互換性のために残されていると考えられるので、今後は新しいSegueを使用した方が良いでしょう。

新しいSegue(セグエ)名について
Segue(セグエ)名の対応表
Xcode5 Xcode6 機能概要
Push Show NavigationControllerのNavigationスタックにViewControllerを追加します。画面はアニメーションしながら次の画面(ViewController)を表示します。Navigation用の戻るボタンやエッジスワイプで元の画面に簡単に戻れます。
Model Present Modally 現在の画面(ViewController)の上に新しい画面(ViewController)を表示します。新しい画面はNaivationControllerでは管理されません。
Popover Present As Popover 主にiPadで吹き出しスタイルの表示を行います。
Replace Show Detail 主にiPadで現在表示している画面(ViewController)の差し替えを行います。iPadの設定アプリで項目の選択で右側ペインの画面さ差し替わっていくイメージです。
Accessory ActionのSegue(セグエ)について

今まであまり使ったことがなかったので、調べてみました。このAccessory Actionセグエはアクセサリアイコンが選択された時用のセグエになるようです。例えば、TableViewではセルのAccessoryを指定することが可能で、そのアクセサリが選択された場合とテーブルセル自体が選択された時を区別するためにセグエが別に定義されているようです。


AD.