Xcodeのエディタでは標準でvimは使えないけど、何か方法はないかなと? Xcodeのコード補完は素晴らしいけど、やっぱり非効率な面も多々。
という事で、調べてみる。
うーん、XcodeでVimを使うんじゃなくて
VimでXcodeをビルドするってことなのね・・・残念
最近、githubでソースを公開してる人も増えてるのでOSXでも構築することに。
marportsでインストールです。
sudo port selfupdate sudo port install git-core tig
tigはgithubを見やすくするツールみたいだ。
3D!とまではいかないが、Quartzでグラフィックの基本処理を。
Quartzで描画する大まかなポイント
(1) 描画用のUIViewクラスを作る (2) 表示するxibのviewを(1)で作成したUIViewに変更する (3) drawRect:(CGRect)rect を実装する (4) UIGraphicsGetCurrentContext()でcontextを取得し、CGContextのメソッドで描画する
4の手順や数学的な事はサイトにはよくのってるけど、1〜3の方法(これだけじゃないと思うけど)が抜けてるので実際に描画にいたれなかったり。。。。 特に、drawRect:(CGRect)rectメソッドが何の前触れもなく記述されているから混乱します(自分も迷ったw)
drawRect:(CGRect)rectはUIviewに定義されているメソッドで、画面更新処理の時に実行されます。 同じインターフェイス内のsetNeedDisplayでも呼ぶ事ができるようです。
(1) 描画用のUIViewクラスは、Objective-c classの作成で、UIViewにチェックして作る。 ※今回はScoreViewと命名した
(2) グラフィックを表示するxibを開いて、viewのクラスをScoreViewに変更する
(3) drawRect:(CGRect)rect を実装する
#import "ScoreView.h"
@implementation ScoreView
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
NSLog(@"drawRect");
context = UIGraphicsGetCurrentContext();
//CGContextTranslateCTM(context, 0, rect.size.height);
//CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextSetRGBStrokeColor(context, 0.0f, 0.0f, 0.0f, 1.0);
CGContextSetLineWidth(context, 1);
scoreValues = [[NSArray alloc] initWithObjects:
[self drawBar:1];
CGContextFlush(context);
}
-(void) drawBar:(NSInteger) barNumber {
float barWidth = 80.0f;
float marginX = 10.0f + ((barNumber - 1) * barWidth);
float marginY = 20.0f;
float barPosX = 0.0f;
float barPosY = 0.0f;
float barInterval = 5.0f;
float startPosX = 0.0f;
float startPosY = 0.0f;
float endPosX = 0.0f;
float endPosY = 0.0f;
for (int i = 0; i <= 4; i++) {
startPosX = marginX + barPosX;
startPosY = marginY + barPosY + i * barInterval;
endPosX = startPosX + barWidth;
endPosY = startPosY;
CGContextBeginPath(context);
CGContextMoveToPoint(context, startPosX, startPosY);
CGContextAddLineToPoint(context, endPosX, endPosY);
CGContextDrawPath(context, kCGPathStroke);
}
}
@end
以下のコードを追加すると、座標系が左下を原点(0, 0)とした処理になります。
CGContextTranslateCTM(context, 0, rect.size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
またタッチして手書き描画する場合は、以下のイベントメソッドを利用する
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
NSLog(@"touchesBegan");
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent*)event {
NSLog(@"touchesMoved");
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent*)event {
NSLog(@"touchesEnded");
}
-(void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event {
NSLog(@"touchesCancelled");
}
ネットワークプログラムを作る場合は、事前のネットワークの確認は必須ですね。 と言うのも先日、社内でデモしようと思ったらアプリが動かない・・・
バグか?と思ったら、
単にWebテストサーバ(自分のWindows)がスリープしてたw
という訳で、Apple DeveloperサイトにReachabilityっていうサンプルコードがあるみたい。
Apple Developer > Reachability
・iPhone Reachability ネットワーク接続を確認する
で、やってみたけど動作が怪しかったので、NSURLConnectionを直接使って実装してみることにした。
・NSURLConnection (非同期) ・NSURLConnectionを使ってサーバーからデータを受信する
NSURLConnectionに非同期通信用のdelegateメソッドが用意されているので実装する。
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"----didReceiveData----");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"----connectionDidFinishLoading----");
}
-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error{
NSLog(@"----Connection failed! Error - %@ %d %@----",
[error domain],
[error code],
[error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"ネットワークエラー"
message:@"サーバに接続できません"
delegate:self
cancelButtonTitle:@"閉じる"
otherButtonTitles:nil
];
[alert show];
[alert release];
if([error code] == NSURLErrorNotConnectedToInternet){
return;
}
}
NSURLErrorNotConnectedToInternetでiPhone自体がネットワーク自体に接続しているかもチェックできる。
ネットワークチェックのメイン処理を実装する。
-(BOOL)checkNetwork:(NSString *)host {
NSLog(@"---checkNetwork---");
NSURLRequest *reqest = [NSURLRequest requestWithURL:[NSURL URLWithString:host]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:reqest delegate:self];
if (connection) {
NSLog(@"Success");
return YES;
} else {
NSLog(@"Error");
return NO;
}
}
とりあえず同期処理で作成してみたが、非同期通信をする場合はdidReceiveDataに処理を書く感じになるのかな?
Reachabilityは時間空いた時に調査かな??
JavaScript(ActionScriptもか)使ってるとレイヤーの重なりって結構面倒だったりする。 実行順を把握していないと、各要素の重なりがわけわかめになったり・・・
と言うわけで、HTML(CSS)内のz-indexの最大値を取得して変更するスクリプトが必要 ここのソースをほぼそのまま使ってみる。 [Javascript] z-indexの最も大きい値を取ってくる
function topZIndex(id) {
$(id).css('z-index', getMaxZIndex() + 1);
}
var getMaxZIndex = function(){
var largestZIndex = 0;
var defaultView = document.defaultView;
var func = function(tagname){
var elements = document.getElementsByTagName(tagname);
for (var i=0; i< elements.length; i++){
var element = elements[i];
var zIndex = element.style.zIndex;
if (!zIndex) {
var css = element.currentStyle || defaultView.getComputedStyle(element, null);
zIndex = css ? css.zIndex : 0;
}
zIndex -= 0;
if(largestZIndex < zIndex) largestZIndex=zIndex;
}
};
if(arguments.length == 0) {
func('*');
} else {
for(var i=0; i
ただこれだと、z-indexがアクションごとに無限に増加してしまうので改良の余地あり。
てか、こんなのありかよw
IEでaddEventListenerが使えない!
CSSもまともに動かないし、どんだけダメブラウザなんだIE・・・ IEではattachEventでイベント登録するらしい。
if (uploadFileField.addEventListener) {
uploadFileField.addEventListener('change', onChange, false);
} else if (uploadFileField.attachEvent) {
//IE対策
uploadFileField.attachEvent('change', onChange, false);
}
もう独自路線止めて、WebKitでいいよ。。。
hostsファイルを編集
sudo vi /private/etc/hosts
127.0.0.1 localhost 192.168.1.52 colinux 255.255.255.255 broadcasthost ::1 localhost fe80::1%lo0 localhost
プロセスを切る
sudo kill -HUP `cat /var/run/lookupd.pid`
最近のFireFoxは重過ぎてもう限界! てことで会社PCの標準ブラウザをGoogle Chromeにした。 Operaも悪くないんだけど。
てか、むちゃくちゃ快適
とりあえず、インストールしたプラグインは
・Bookmarks Menu ・Docs PDF/PowerPoint Viewer(by Google) ・Downloads ・Evernote ウェブクリッパー ・Firebug Lite for Google Chrome ・Google bookmarks ・Google Mail Checker ・Google Translate ・IE Tab ・Metrist - Twitter Client ・webページショット
第二階層から第一階層に戻る場合、第一階層のtitleをつけないとNavigationBarのボタンが表示されません。
凄く悩んだ・・・
ただ階層毎にNavigationBarのItemを多用する場合は、その階層にNavigationBarを持ったほうが現実的な気もする。 コーディングでitemを追加することもできるだろうが、ビジュアル的にわかりにくそう。
関係ないけど、ホリエモンつぶやきすぎw
これもWordpressでSyntaxHighlighterをインストールすると以下のように簡略化して入力できる。
[cpp]
ソース
これを
<pre class="brush:xxx">ソース</pre>
に変換するスクリプト。
調べたら「wordpress/wp-content/plugins/syntax_highlighter.php」で処理しているようだ。
てな訳で、同じ仕様で自作してみることに。
function syntax_highlight_header() {
$syntaxHighlighter = SyntaxHighlighter::getInstance();
$syntaxHighlighter->showHeader();
}
function syntax_highlight_decode($body) {
if ($body) {
$syntaxHighlighter = SyntaxHighlighter::getInstance();
$syntaxHighlighter->convertContent($body);
}
}
class SyntaxHighlighter {
var $types = array(
'as3' => array('brush' =>'AS3'),
'bash' => array('brush' => 'Bash'),
'cpp' => array('brush' => 'Cpp'),
'csharp' => array('brush' => 'CSharp'),
'css' => array('brush' => 'Css'),
'delphi' => array('brush' => 'Delphi'),
'coldfusion' => array('brush' => 'ColdFusion'),
'java' => array('brush' => 'Java'),
'javafx' => array('brush' => 'JavaFX'),
'jscript' => array('brush' => 'JScript'),
'diff' => array('brush' => 'Diff'),
'erlang' => array('brush' => 'Erlang'),
'groovy' => array('brush' => 'Groovy'),
'perl' => array('brush' => 'Perl'),
'php' => array('brush' => 'Php'),
'plain' => array('brush' => 'Plain'),
'powershell' => array('brush' => 'PowerShell'),
'python' => array('brush' => 'Python'),
'ruby' => array('brush' => 'Ruby'),
'shell' => array('brush' => 'Sass'),
'scala' => array('brush' => 'Scala'),
'sql' => array('brush' => 'Sql'),
'vb' => array('brush' => 'vb'),
'xhtml' => array('brush' => 'Xml'),
);
private static $instance = null;
public static function getInstance() {
if (SyntaxHighlighter::$instance == null) {
SyntaxHighlighter::$instance = new SyntaxHighlighter();
}
return SyntaxHighlighter::$instance;
}
public function showHeader() {
$tags[] = $this->javascript_tag('dp.SyntaxHighlighter/src/shCore');
if (is_array($this->types)) {
foreach ($this->types as $key => $value) {
$tags[] = $this->javascript_tag("dp.SyntaxHighlighter/scripts/shBrush{$value['brush']}");
}
}
$tag = implode("\n", $tags);
echo($tag);
}
public function convertContent($body) {
$bodys = explode("\n", $body);
if (is_array($bodys)) {
$isCode = false;
foreach($bodys as $key => $line) {
$start_code = $this->syntaxHighliterCode($line);
if ($start_code) {
$code = $start_code;
$tag.= "&ltpre class=\"brush:{$code}\">\n";
} else {
if ($code) {
if ($this->isSyntaxHighliterEndTag($line, $code)) {
$tag.= "</pre>\n";
$code = null;
} else {
$tag.= "{$line}\n";
}
} else {
$line = html_entity_decode(strip_tags($line), ENT_QUOTES, mb_internal_encoding());
$line = "{$line}\n";
$line = nl2br($line);
$tag.= $line;
}
}
}
}
echo($tag);
}
private function syntaxHighliterCode($value) {
$pattern = '/^\[[a-zA-Z0-9]+\]/';
if (preg_match($pattern, $value, $matchs)) {
$code = substr($matchs[0], 1, strlen($matchs[0]) - 2);
$code = strtolower($code);
if ($this->types[$code]) {
return $code;
}
}
}
private function isSyntaxHighliterEndTag($value, $target) {
$pattern = '/^\[\/[a-zA-Z0-9]+\]/';
if (preg_match($pattern, $value, $matchs)) {
$code = substr($matchs[0], 2, strlen($matchs[0]) - 3);
$code = strtolower($code);
return ($target == $code);
}
}
private function javascript_tag($name) {
if (is_string($name) && !empty($name)) {
return "&ltscript type=\"text/javascript\" src=\"{$GLOBALS['controller']->relative_base}javascripts/{$name}.js\">\n";
}
}
}
htmlヘッダーでsyntax_highlight_header()を呼んで、ブログの本文syntax_highlight_decode($text)で変換してやります。
あとDBに保存するときは、htmlentitiesでエスケープしました。
htmlentities(本文, ENT_QUOTES, mb_internal_encoding());
即席でバグバグだと思うけど、とりあえずコンバートできました。 正規表現でパースする部分が美しくないし、singlton使う意味がないかも・・・