Help us understand the problem. What is going on with this article?

Sketch.app Plugin の開発メモ

More than 1 year has passed since last update.

Sketch Plugin CookBook (ver.51まで)

:warning:Sketch 52でAPIが変更になっているため、動かない記述があります。:warning:

忘れやすい自分のための、Sketch.app向けプラグイン開発メモ。

:innocent: ツギハギで書いてきたため、内容をあまり精査できていません。ところどころ書き換えできずに間違ってます。さらにClass自体が非推奨になった(リファレンスからなくなった)ようで、この書き方は使えなくなる可能性が高いです。「使えなくなる」ではなく、JavaScript API経由で使えってことになりそうです。:innocent:

Sketchのプラグインは、CocoaScirptで開発する。とてもざっくり言うと、Objective-CをJavaScriptライクに扱う言語(キモイ)。記述はJavaScriptスタイルとObjective-Cスタイルがあり、混在もOK。

ドキュメントとか参考情報

クラスリファレンスが見たい場合は、こちらのコミットからローカルへクローンしてJekyllでビルドすれば復元できます。

フォーラム

メーリングリストとそのアーカイブ

こちらも参考に

デバッグ

公式ドキュメント:Debugging — Sketch Developer

公式ドキュメントではフィルタの設定を「sketch」としているが、プラグインのメッセージだけをみたいのであれば、「sketch plugin」とした方が良い、と思う。

Class Dump

class-dumpというコマンドラインツールをインストールすると、メソッドやプロパティを調べることができる。Class-dumpの配布ページからファイルをダウンロードし、中にあるclass-dump/usr/local/binあたりへコピーする。

$ cp /Volumes/class-dump-3.5/class-dump /usr/local/bin/class-dump

ターミナルで次のコマンドを叩けば、プロパディやメソッドを取得できる。

# 含まれるフレームワークすべて
$ class-dump /Applications/Sketch.app

# フレームワークを指定
$ class-dump /Applications/Sketch.app/Contents/Frameworks/CocoaScript.framework

# ファイルとしてホームディレクトリへ書き出す場合
$ class-dump /Applications/Sketch.app > ~/sketch-class-dump.txt

参考記事でも紹介されていたSketch Headersで、同様の情報が閲覧できますので、お好きな方で。

オブジェクトの構成を出力するtreeAsDictionary()

オブジェクトの構造はtreeAsDictionary()を使うとログに吐き出すことができ、プロパティ名からメソッドを憶測できる。

// 選択しているシェイプの構造をログで出力
var sel = context.selection;
var shape = sel[0];
log( shape.frame().treeAsDictionary() );

これを実行すると、次の出力を得ることができる。

{
    "<class>" = MSRect;
    constrainProportions = 0;
    height = 159;
    width = 145;
    x = 179;
    y = 169;
}

クラスやインスタンスが持つメソッドを出力するinstanceMethods()classMethods()

また、class-dumpを紹介したものの、instanceMethods()classMethods()を使うと、そのクラスが持っているメソッドを吐き出すこともできる。

// 選択しているシェイプの構造をログで出力
var sel = context.selection;
var shape = sel[0];
log( shape.frame().class().mocha().instanceMethods() );

これを実行すると、次の出力を得ることができる(

(
    "<MOMethodDescription: 0x6100004266c0 : selector=makeOriginIntegral, typeEncoding=v16@0:8>",
    "<MOMethodDescription: 0x610000426700 : selector=makeRectIntegral, typeEncoding=v16@0:8>",
// 長いため中略
    "<MOMethodDescription: 0x610000428260 : selector=setOrigin:, typeEncoding=v32@0:8{CGPoint=dd}16>",
    "<MOMethodDescription: 0x610000428300 : selector=setRect:, typeEncoding=v48@0:8{CGRect={CGPoint=dd}{CGSize=dd}}16>"
)

ちなみにclassMethods()のものはnew()しなくても使える。

プロパティを出力するproperties()

// プロパティのダンプ
var sel = context.selection;
var shape = sel[0];
log( shape.frame().class().mocha().properties() );

Atom向けのプラグイン実行パッケージ

Atomから直接Sketchプラグインを実行できるパッケージ。パッケージマネージャなどでインストールしCommand + Rすると、定義されてているメソッドをパレットから選択して実行できる。

Sketch Scripter

ちなみにAutherはContent Generator Pluginの人。

プラグインの構造

PLUGINNAME.sketchplugin
 └ Contents
    └ Sketch
       ├ SCRIPT.sketchscript
       └ manifest.json

Pluginsメニューへの表示はmanifest.jsonで管理するため、SCRIPT.sketchscriptは複数あっても良い。拡張子も.js.cocoascriptでも大丈夫。ライブラリなどはSketchディレクトリ内にさらにディレクトリを作成し、その中に突っ込んでもOK。外部のスクリプトを読み込むには、@importを使ってファイルの先頭へ次のように書く。

@import 'lib/script.js';

旧形式のプラグインについて

以前はディレクトリへ実行ファイルのそのものである.sketchpluginを突っ込んでおけば良かったが、3.3から形式が変更になっている。3.4からPreferencesへプラグインマネージャーが実装され、manifest.jsonがないと「Legacy Plugins」として1つにまとめられてプラグインを管理できなくなるので注意。

この旧形式でも41現在、きちんとメンテナンスされていれば実行は可能だが、Legacy PluginはPluginsメニューの別メニューにまとめられてしまう。今後、いつ使えなくなるかわからないため、よく使うプラグインが旧形式なら要注意。

こちらを参照:Plugin News — Sketch Developer

manifest.json

manifest.jsonは、Pluginsメニューやプラグインマネージャーで表示する内容を設定するファイル。下記は、拙作「Sketch CSS Sprite Mixin」のファイルの一部を抽出。こちらはがんばって書いている感じなので、最低限の記述は「Sketch3のプラグインを開発する」を参照のこと。

manifest.json
{
    "author": "littlebusters", // プラグインマネージャーで表示
    "menu" : {
        "isRoot" : false, // Pluginsメニュー直下へ表示するかどうか
        "shortcut" : "",
        "items" : [ // メニュー上の並びを設定。commands[INDEX].identifierを指定する。3.3では無効
            "css-sprite-mixin-scss",
            "css-sprite-mixin-sass",
            "css-sprite-mixin-less",
            "-", // 3.4.1より、ハイフンを入れるとセパレータとして表示されるように
            "css-sprite-mixin-stylus"
        ],
        "title" : "Sketch CSS Sprite Mixin" // Pluginsメニューでのフォルダ名
    },
    "identifier": "net.creative-tweet.css-sprite-mixin",
    "version": "1.1.0", // プラグインマネージャーで表示
    "description" : "Generate a code of CSS Sprite Mixin to Clipboard in Sketch.", // プラグインマネージャーで表示
    "name" : "Sketch CSS Sprite Mixin", // プラグインマネージャー上の名前。指定しない場合は、ファイル名から取得される
    "commands" : [
        {
            "name": "Scss", // Pluginsメニュー上の表示
            "identifier": "css-sprite-mixin-scss",
            "handler" : "getScss", // 下のscript内にあるメソッドを指定
            "script": "css-sprite-mixin.sketchscript" // スクリプトファイルを指定
        }
    ]
}

Global Variable

メソッドにcontextという引数を渡して実行してやる。旧形式でいうdocや選択しているレイヤーを取得するには次の通り。

var onRun = function(context) {
    var doc = context.document;
    var sel = context.selection;
}

サンプルコード

docとなっているところは、事前にvar doc = context.document;となっている前提とするか、context.documentと読み替えてください。

非推奨になっているmethod

  • MSArray.length() -> MSArray.count() // 3.8
  • setPatternImage() -> SetImage() // 3.8
  • addLayerOfType() -> それぞれのクラスからインスタンスを作成する // 3.8
  • convertToSymbol() -> convertArtboardToSymbol() // 41
  • MSColor -> MSImmutableColor // 41

バージョンの取り方

Bohemian Coding的には最新版しかサポートしない感じですが、とりあえずバージョンによる分岐をする場合に必要なバージョンの取得方法。ちなみに、3.8の次は3.9かと思ったら39になってしまったので、39以降はmajorには二桁の数字が入ります。

var appVer = {}
appVer.full = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
appVer.major    = ( appVer.full.split( '.' ) )[0];
appVer.minor    = ( appVer.full.split( '.' ) )[1] || 0;
appVer.revision = ( appVer.full.split( '.' ) )[2] || 0;

ページ関連

参考
- Sketch Command/Pages

現在のページを取得

// JS Style
var doc = context.document;
var currentPage = doc.currentPage();

// Obj-c style
var doc = context.document;
var currentPage = [doc currentPage];

ドキュメント内のページ数

// JS Style
var doc = context.document;
var docPages = doc.pages();
log( docPages.count() ); // ページ数を表示

// Obj-c style
var doc = context.document;
var docPages = [doc pages];
log( [docPages count] ); // ページ数を表示

新しいページを追加

// JS Style
var doc = context.document;
doc.addBlankPage();

// Obj-c style
var doc = context.document;
[doc addBlankPage];

現在のページ名を取得

// JS Style
var doc = context.document;
var currentPage = doc.currentPage();
log( currentPage.name() );

// Obj-c style
var doc = context.document;
var currentPage = [doc currentPage];
log( [currentPage name] );

現在のページ名を変更

// JS Style
var doc = context.document;
var currentPage = doc.currentPage();
currentPage.setName( 'Page Name' );

// Obj-c style
var doc = context.document;
var currentPage = doc.currentPage();
[[currentPage] setName:'Page Name'];

アートボード関連

アートボードの一覧を取得

// JS Style
var doc = context.document;
var artboards = doc.currentPage().artboards();
if ( 0 < artboards.count() ) {
    for ( var i = 0; i < artboards.count(); i++ ) {
        log( artboards[i].name() );
        log( artboards[i].frame().width() );
        log( artboards[i].frame().height() );
        log( artboards[i].frame().x() );
        log( artboards[i].frame().y() );
    }
}

// Obj-c style
var doc = context.document;
var artboards = [[doc currentPage] artboards];
if ( 0 < [artboards count] ) {
    for ( var i = 0; i < [artboards count]; i++ ) {
        log( [[artboards objectAtIndex:i] name] );
        log( [[[artboards objectAtIndex:i] frame] width] );
        log( [[[artboards objectAtIndex:i] frame] height] );
        log( [[[artboards objectAtIndex:i] frame] x] );
        log( [[[artboards objectAtIndex:i] frame] y] );
    }
}

現在のアートボードを取得

// JS Style
var doc = context.document;
var currentArtboard = doc.currentPage().currentArtboard();
if ( 0 > currentArtboard.count() ) {
    log( currentArtboard.name() );
}

// Obj-c style
var doc = context.document;
var artboard = [[doc currentPage] currentArtboard];
if ( 0 < [artboards count] ) {
    log( [currentArtboard name] );
}

アートボードを作成

// JS Style
var doc = context.document;
var artboard = MSArtboardGroup.new();
artboard.setName( 'Artboard Name' );
artboard.frame().setX( 0 );
artboard.frame().setY( 0 );
artboard.frame().setWidth( 480 );
artboard.frame().setHeight( 720 );
doc.addLayer( artboard );

// Obj-c style
var doc = context.document;
var artboard = [MSArtboardGroup new];
[artboard setName: 'Artboard Name'];
[[artboard frame] setX: 0];
[[artboard frame] setY: 0];
[[artboard frame] setWidth: 480];
[[artboard frame] setHeight: 720];
[doc addLayer: artboard];

複数のアートボードを追加する場合は、doc.addLayer()の部分を次のように変更する。

// JS Style
var currentPage = doc.currentPage();
currentPage.addLayers( NSArray.arrayWithObjects( artboard ) );

// Obj-c Style
var currentPage = [doc currentPage];
[currentPage addLayers:[NSArray arrayWithObjects: artboard]];

現在のアートボードへガイドラインを追加する

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var vRuler = artboard.verticalRulerData();
var hRuler = artboard.horizontalRulerData();
vRuler.addGuideWithValue( 100 ); // 垂直
hRuler.addGuideWithValue( 100 ); // 水平

現在のアートボードのグリッドを設定する

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var grid = MSSimpleGrid.new();
grid.setGridSize( 16 );
artboard.grid = grid;

レイヤーの作成と設定

グループの作成

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var group = MSLayerGroup.new();
group.setName( 'Group Name' );
artboard.addLayers( [group] );

矩形(Rectangle)を作成

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var rectangle = MSRectangleShape.new();
rectangle.name = 'Layer Name';
rectangle.frame().x = 0;
rectangle.frame().y = 0;
rectangle.frame().width = 100;
rectangle.frame().height = 150;

var shape = MSShapeGroup.shapeWithPath( rectangle );
artboard.addLayers( [shape] );

ベジェを作成

参考
- Sketch Plugins Cookbook

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var bezierPath = NSBezierPath.bezierPath();

bezierPath.moveToPoint( NSMakePoint( 0, 0 ) ); // パスを開始する座標

// 直線を引く
bezierPath.lineToPoint( NSMakePoint( 50, 50 ) ); // アンカーポイントの座標

// 曲線を引く
var ancher        = NSMakePoint( 200, 200 ); // アンカーポイントの座標
var currentHandle = NSMakePoint( 150, 200 ); // 作成するアンカーポイントのハンドルの座標
var prevHandle    = NSMakePoint(  50, 100 ); // 元のアンカーポイントのハンドルの座標
// 曲線を生成
[bezierPath curveToPoint:ancher controlPoint1:prevHandle controlPoint2:currentHandle];

// パスを閉じる
bezierLine.closePath();

var shape = MSShapeGroup.shapeWithBezierPath( bezierPath );
artboard.addLayers( [shape] ); // ベジェシェイプをアートボードへ追加

マスクの作成

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

// マスクの影響を抑える為にグループを作成
var group = MSLayerGroup.new();
group.setName( 'Mask Group' );

// グループ内にマスクの矩形を作成

var maskRect = MSRectangleShape.new();
maskRect.name = 'Mask';
maskRect.frame().x = 0;
maskRect.frame().y = 0;
maskRect.frame().width = 100;
maskRect.frame().height = 150;

var mask = MSShapeGroup.shapeWithPath( maskRect );
group.addLayers( [mask] );

// マスク化
mask.setHasClippingMask( true );
// マスク化による親レイヤーの境界や座標を更新

ビットマップを読み込む

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

// 読み込むファイルのパスを設定
var filePath = '/Users/USERNAME/file/to/path.png';

var image = NSImage.new().initWithContentsOfFile( filePath );
var imageData = MSImageData.alloc().initWithImage_convertColorSpace_(image, true);
var bitmap = MSBitmapLayer.new();
bitmap.image = imageData;
bitmap.name = 'Imported Bitmap';
bitmap.frame().x = 0;
bitmap.frame().y = 0;

artboard.addLayers( [bitmap] );

スライスを作成

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var slice = MSSliceLayer.new();
slice.name = 'Slice Name';
slice.frame().x = 0;
slice.frame().y = 0;
slice.frame().width = 100;
slice.frame().height = 150;

artboard.addSlice( slice );

Radiusの設定

// Rectangleツールで作成した矩形を選択した状態で
var sel = context.selection;
var rect = sel.firstObject().layers().firstObject();

rect.cornerRadiusFloat = 10;

// 個別にRadiusを設定する場合は次の通り
// rect.cornerRadiusString = "7/0/0/10";

Blending Modeの設定

// 矩形レイヤー(rectangle)を作成したのち
var contextSettings = rectangle.style().contextSettings();
contextSettings.blendMode = 1;

Blend Modeの数値は、こちらを参照のこと

レイヤー自体のOpacity設定

// Blending Modeの設定のコードの後に
contextSettings.opacity = 0.5; // 0から1の値

スタイリング

Fill(Flat Color)を設定

// 矩形レイヤー(rectangle)を作成したのち
// Fillを追加してプロパティを取得
var fill = rectangle.style().addStylePartOfType( 0 );
// Fillに適用するカラーを設定
var color = MSImmutableColor.colorWithSVGString( '#ff0000' );
color.alpha = 0.8;
// Fillにカラーを適用
fill.color = color;

addStylePartOfType()した場合、デフォルトとしてFlat Colorが適用される。Gradientから変更する場合は、fill.setFillType( 0 )とする。

Fill(Gradient)を設定

// 矩形レイヤー(rectangle)を作成したのち
// Fillを追加してプロパティを取得
var fill = rectangle.style().addStylePartOfType( 0 );

// Fillの種類をGradientに変更
fill.setFillType( 1 );
// Gradientプロパティを取得
var gradient = fill.gradient();
// Gradient Typeの設定 / 0: Linear / 1: Radial / 2: Angular
gradient.setGradientType( 0 );
// Gradient Stopを追加 / value: 0..1
gradient.addStopAtLength( 0.5 );
// Gradient Stopに適用するカラーと透明度を設定
var gradientColor = MSImmutableColor.colorWithSVGString( '#ff0000' );
gradientColor.alpha = 0.8;
// Gradient Stopにカラーを適用
gradient.setColor_atIndex_( gradientColor, 1 );
// Gradient Stopの位置を設定
gradient.setPoint_atIndex_( CGPointMake( 1, 1 ), 1 );

Gradient Stopの位置を設定するCGPointMake()は、レイヤーの大きさに対する割合をX・Yで指定する。
例えばW100×H100のレイヤーで、CGPointMake( 0.4, 0.5 )と指定すれば、オブジェクトの左上起点でX40/Y50の位置へGradient Stopが移動する。ただし、atIndexを両端以外で指定している場合、両端を結ぶ直線上の範囲で移動が行われる。

Fill(Pattern)を設定

// 矩形レイヤー(rectangle)を作成したのち
// Fillを追加してプロパティを取得
var fill = rectangle.style().addStylePartOfType( 0 );

// Fillの種類をPatternに変更
fill.setFillType( 4 );
// 整列方法を設定 / 0: Tile / Fill: 1
fill.setPatternFillType( 1 );

// パターン画像のパスから画像データを作ってFillへ設定する
var imageData = MSImageData.alloc().initWithImage_convertColorSpace_( '/file/to/path/document.png', false );
fill.setImage( imageData );

Fill(Noise)を設定

// 矩形レイヤー(rectangle)を作成したものとする
// Fillを追加してプロパティを取得
var fill = rectangle.style().addStylePartOfType( 0 );

// Fillの種類をNoiseに変更
fill.fillType = 5; // fill.setFillType( 5 )でもOK
// ノイズの種類を指定 / 0: Original / 1: Black / 2: White / 3: Color
fill.noiseIndex = 3;
// IntensityはOpacityとして設定する
fill.contextSettings().opacity = 0.5;

ドロップシャドウ / インナーシャドウ

// 矩形 rectangle を作成済みとして
// 2: ドロップシャドウ / 3: インナーシャドウ
var effect = addStylePart( rectangle, 2 );

// ぼかしの大きさ
effect.blurRadius = 10;

// XY座標
effect.offsetX = 0;
effect.offsetY = 0;

// スプレッドの大きさ
effect.spread = 0;

// 色と不透明度
var color = MSImmutableColor.colorWithSVGString( getHexColor( attrs[i].ShadowColor ) );
color.alpha = getOpacity( attrs[i].ShadowColor );
effect.color = color;

ぼかし各種

// 矩形レイヤー(rectangle)を作成したものとする
var effect = rectangle.style().blur();

// ぼかし効果を有効化
effect.isEnabled = 1;

// 0: ガウス / 1: モーション / 2: ズーム / 3: バックグラウンド(多分)
effect.type = 2;

// ぼかしの大きさ
effect.radius = 10;

テキストレイヤーの作成

var doc = context.document;
var artboard = doc.currentPage().currentArtboard();

var text = MSTextLayer.new();

// 0: Auto(デフォルト) / 1: テキストボックスの幅を固定
text.textBehaviour = 1;

// テキストに文字列を入れる
text.stringValue = 'テキストの内容だよ';

// フォントサイズの設定
text.fontSize = '24';

// フォントの設定(Postscript名で指定する)
text.fontPostscriptName = 'フォント名';

// テキストカラーの設定
text.textColor = MSImmutableColor.colorWithSVGString( '#ff0000' );

// テキストボックスの大きさを最適化
text.adjustFrameToFit();

// パラグラフを設定する
var pragraph = NSMutableParagraphStyle.new();
pragraph.minimumLineHeight = 12;
pragraph.maximumLineHeight = 24;
text.addAttribute_value_( NSParagraphStyleAttributeName, pragraph );

// テキストの揃え - 0: 左 / 1: 右 / 2: 中央
text.setTextAlignment( 0 );

// サイズや位置、レイヤー名なども設定できます
artboard.addLayers( [text] );

文字の一部の設定を変更する

// 変更する範囲を作成(0文字から2文字目まで)
var range = NSMakeRange( 0, 2 );

// フォント名をサイズを指定
var textFont = NSFont.fontWithName_size_( 'フォント名(Postscript)', 24 );

// 色を指定
var color = MSImmutableColor.colorWithSVGString( '#ff0000' );

// 一部の変更を実行
text.setIsEditingText( true );
text.addAttribute_value_forRange_( NSFontAttributeName, textFont, range );
text.addAttribute_value_forRange_( NSForegroundColorAttributeName, color, range );
text.setIsEditingText( false );

// パラグラフも設定できますが、多分一部だけを変えることはないでしょうね
text.addAttribute_value_forRange_( NSParagraphStyleAttributeName, pragraph, range );

Symbol

アートボードからシンボルを作成する

あらかじめSymbolにするアートボードを作成しておくこと。

MSSymbolMaster.convertArtboardToSymbol( artboard );
// artboard = あらかじめ作成していたアートボード

ただこれではインスタンスを作成しづらいので、オブジェクトに放り込んでおくと良い…かも?

var symbols['symbolName'] = MSSymbolMaster.convertArtboardToSymbol( artboard );

Symbol Instanceの作成

var doc = context.document;
var cp  = doc.currentPage();
for( var i = 0; i < doc.pages().count(); i++ ) {
    if( 'Symbols' == doc.pages()[i].name() ) {
        var symbolsPage = doc.pages()[i];
        break;
    }
}

var symbolInstance = symbolsPage.artboards()[0].newSymbolInstance();
symbolInstance.setName( 'Symbol Instance' );
symbolInstance.frame().x = 0;
symbolInstance.frame().y = 100;
cp.addLayers( [symbolInstance] );

メッセージ・ダイアログ関連

参考
- User Input & Feedback

ウィンドウ下部へメッセージ

// JS Style
doc.showMessage( 'Message' );

// Obj-c style
[doc showMessage: 'Meaasage'];

Cocoaでモーダルダイアログ

アイコンとかも設定できるはず。

// JS Style
var userInput = COSAlertWindow.new();

//ダイアログタイトル
userInput.setMessageText( 'Dialog Title' );

// テキストフィールド
userInput.addTextLabelWithValue( 'Text Field Title' );
userInput.addTextFieldWithValue( 'Text Field Placeholder' );

// チェックボックス
var checkbox = NSButton.alloc().initWithFrame( NSMakeRect( 0, 0, 300, 18 ) );
checkbox.setButtonType( NSSwitchButton );
checkbox.setTitle( 'Switch Button Title' );
checkbox.setTag( 'value' );
checkbox.setState( false );
userInput.addAccessoryView( checkbox );

// ラジオボタン
var radiobutton = NSButton.alloc().initWithFrame( NSMakeRect( 0, 0, 300, 18 ) );
radiobutton.setButtonType( NSRadioButton );
radiobutton.setTitle( 'Radio Button Title' );
radiobutton.setTag( 'value' );
radiobutton.setState( true );
userInput.addAccessoryView( radiobutton );

// ボタン
userInput.addButtonWithTitle('OK');

// 実行
userInput.runModal();


// Obj-c style
var userInput = [COSAlertWindow new];

//ダイアログタイトル
[userInput setMessageText:'Dialog Title'];

// テキストフィールド
[userInput addTextLabelWithValue:'Text Field Title'];
[userInput addTextFieldWithValue:'Text Field Placeholder'];

// チェックボックス
var checkbox = [[NSButton alloc] initWithFrame:NSMakeRect( 0, 0, 300, 18 )];
[checkbox setButtonType:NSSwitchButton];
[checkbox setTitle: 'Switch Button Title'];
[checkbox setTag: 'value'];
[checkbox setState: false];
[userInput addAccessoryView: checkbox];

// ラジオボタン
var radiobutton = [[NSButton alloc] initWithFrame:NSMakeRect( 0, 0, 300, 18 )];
[radiobutton setButtonType: NSRadioButton];
[radiobutton setTitle: 'Radio Button Title'];
[radiobutton setTag: 'value'];
[radiobutton setState: true];
[userInput addAccessoryView: radiobutton];

// ボタン
[userInput addButtonWithTitle: 'OK'];

// 実行
[userInput runModal];

setButtonTypeはこのあたりを参照

Fw.jsf でいう、prompot();

// JS Style
var userInput = doc.askForUserInput_initialValue( 'Message', 'Default Value' );

// Obj-c style
var position = [doc askForUserInput: 'Message' initialValue: 'Default Value'];

JavaScript スタイルの書き方が分からなかったが、「_」でつなぐと良いことを教わった。

JSONファイルを選択してパース

ただし、runModalForDirectoryが10.6で非推奨になっているので、他の方法を探す(10.10でも一応動作可能)。

var openPanel = NSOpenPanel.openPanel();
    openPanel.setTitle( "Choose a JSON File" ); // ダイアログのタイトル
    openPanel.setCanCreateDirectories = false; // ディレクトリの作成を許可するか
    openPanel.setCanChooseFiles = true; // ファイル選択を許可するか

var fileTypes = ['json']; // 選択できるファイルタイプを設定
var openPanelButtonPressed = openPanel.runModalForDirectory_file_types_( nil, nil, fileTypes );

if ( openPanelButtonPressed == NSFileHandlingPanelOKButton ) {
    var filePath = openPanel.URL().path();
    var json = JSON.parse( NSString.stringWithContentsOfFile( filePath ) ); 
    log( 'Open File from: ' + filePath );
} else {
    return false;
}

そのほか

フォントの一覧を取得

var fontList = NSFontManager.sharedFontManager().availableFontFamilies();

フォントファミリーを取得

var fontFamilies = NSFontManager.sharedFontManager().availableMembersOfFontFamily('Helvetica Neue');

引数として、フォント名を渡す。PostScript名はNGで、「フォントの一覧」で取得したフォント名を使うこと。

ArrayからJSONに

例えば上記の「フォントの一覧」から作成する場合

var fontList = NSFontManager.sharedFontManager().availableFontFamilies();
var data = NSJSONSerialization.dataWithJSONObject_options_error_(fontList, 0, nil);
var json = NSString.alloc().initWithData_encoding_(data, 4);

Plugins Directoryへの登録

オリジナルドキュメント:Contributing

GitHubやウェブサイト等へアクセスし、ダウンロードできるように準備しておく。

  1. Sketch Plugins DirectoryのリポジトリをForkし、ローカルへCloneする。
  2. plugins.jsonを編集する。
    1. Object({}の括り)をコピペする。
    2. それぞれの項目を英語で埋める。Google翻訳したような英語でも問題なさそう。
      最低限、description(プラグインの説明)・name(リポジトリ名)・title(プラグイン名)・owner(リポジトリの所有者名)を埋める。
      そのほかの情報として、owner(作者名 リポジトリ所有者名以外を使う場合)・homepage(リポジトリ以外でプラグインを配布している場合のリンク先)・lastUpdated(最終更新日)がある。
    3. 不安なら、適当なJSON linterを通しておく。
  3. Terminal.appで、Cloneしたディレクトリへ移動し、rakeコマンドを実行すると、plugins.jsonに合わせて、README.mdが更新される。
  4. リモートのリポジトリへプッシュし、元のリポジトリへPull Requestを送る。メッセージは何でもOK。
littlebusters
デザインの人。とりあえずなんでも放り込みます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした