<< Prev Page Next Page >>

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。


PicPages2をリリースしました


PicPages2



自炊ブックビューアをApp Storeにリリースしました。設定項目が少なくて迷いがないのが売り!?

あと、UIPageViewを使ってめくりアニメーションしてます。UIPageView結構使うの面倒くさい。iPadでは2ページ見開きとかしたいんだけどそっちはまだ途中なのでiPad版のリリースはナシで。ていうかiPad持ってないのでモチベーションがなかなか維持しない…

ソースコード一揃いgithubに置いたよ。UIPageView使うとことか参考になれば。Swiftの試行錯誤しながらなのでOptionalの扱いがふらふらしてる。そのうち直すかなあ。

サードパーティのライブラリ関係は載せてないのでこのままではビルド通らないのであしからず。

FMDBのビルドがどうしても上手く行かなくてsqlite3のラッパーライブラリとか自分で作った直後にSwiftDataの存在を知った。まあ練習にはなったし自分で作ったライブラリのほうが自分で使いやすいからいいかーとか。

iOSってStringのメソッド名が長いからこういうextension作っておくと正規表現を簡単に扱うメソッド生やせたりして便利だったりとか。iOSの正規表現ほんとめちゃくちゃ面倒だからねー。

CocoaPodでハマりにハマって、結論として、SwiftのプロジェクトではまだCocoaPod使わないほうが楽ってことがわかったのでCocoaPod無し。


スポンサーサイト

UIScrollViewとAutoLayoutでハマった話

UIScrollViewの中にUIImageViewを一つだけ表示するっていうUIを作ってたんですがね。

表示する画像によって、UIImageViewの大きさをいろいろ変化させたいので、XCode上でConstraintsをあらかじめ設定しておけないので、コードのほうでなんとかしないといけないのです。

当初、

  1. XCode上でUIScrollViewにUIImageViewを貼り付け(自動的に、UIImageViewの大きさがニュニュっと大きくなるよね)
  2. UIImageViewにはConstraints設定なし
  3. UIViewControllerのviewDidLoadでUIImageViewのサイズ設定
    override func viewDidLoad() { (略) imageView.frame.size = CGFrame(x:0, y:0, width: imgWidth, height: imgHeight) (略) }

ってやってたわけです。(あ、気づいた?そう、Swiftです。いいよねSwift)

しかしどーうしてもUIImageViewの大きさが600x600になってしまう。

それはもういろいろ調べて試しました。UIScrollViewとAutoLayout | Professional Programmerとかほうぼうで、

scrollView.setTranslatesAutoresizingMaskIntoConstraints(false)

ってやるのがいいとか見て試してダメだったりとか。

調べる途中で、Visual Format Language for Autolayout - Command Shiftとか見つけて、Visual Formatがかけるようになっちゃったりとか。

しかし解決しない。

で、ふと気づきました。600x600のサイズってのは、これはあきらかにXCodeのStoryboardで設定されてる初期値なわけです。このサイズにするConstraintsが勝手にくっついてるのではないか?

そして、過去の経験から、UIScrollViewは複数のUIViewが重なって構成されているってことを知ってるので、調べるためのコードはこれだ!

for c in imageView.superview!.constraints() { println("constraints : \(c)") }

scrollViewのconstraints()ではなく、imageView.superviewを調べるのがミソです。

で、やっぱり付いてました。サイズを600x600にする制約。

となれば、あとは簡単。ついてる制約をごっそり削除しちゃえばいいのです。

var sv = imageView.superview! sv.removeConstraints(sv.constraints())

これで、あとは自前でVisual Format使ってConstraints設定するもよし、CGFrameで自由なレイアウトにするもよし。よかったよかった。


cocoaの長ったらしいメソッドにつきあわない

Objective-Cは既存のクラスに勝手にメソッド生やせるようになっているのを利用して、よく使う長ったらしい記述を短くすることにしてみた。

NSString


isEqualToString -> eq
stringByAppendingString -> plus
stringByAppendingPathComponent -> plusPath
lastPathComponent -> filename
lastPathComponent + stringByDeletingPathExtension -> basename
stringByDeletingLastPathComponent -> dirname
正規表現に最初にマッチした部分文字列を配列で返す -> match:pattern
正規表現にマッチした文字列の配列の配列を返す -> matches:pattern
これは。快適なんじゃね?もうね、Objective-Cの正規表現がウザすぎて死ぬので。
あとおまけ
NSLocalizedString(name, comment) -> res(name)
すごいしょっちゅう使うのに補完候補の先頭に出てこなくてたくさんタイプするのが面倒なので。

UIView、CALayer


frame.origin.x -> left
frame.origin.x + frame.size.width -> right
frame.origin.y -> top
frame.origin.y + frame.size.height -> bottom
frame.size.width -> width
frame.size.height -> height
サイズを変えずに移動 -> eMove:x :y
相対移動 -> eOffset:x :y
サイズだけ変更 -> eSize:width :height
他のViewと同じサイズにする -> eSameSize:view
親View一杯に広げる -> eFitToSuperview
左に寄せる -> eFitLeft
右に寄せる -> eFitRight
上に寄せる -> eFitTop
下に寄せる -> eFitBottom
フェードイン -> eFadein
フェードアウト -> eFadeout
他のViewと一緒にスライド -> eSlideWith:view :x :y
あら便利。あらあら。これは気持ちいい。

実際にどうやるかは、【コラム】ダイナミックObjective-C (8) カテゴリ - 動的なメソッドの追加によるクラスの拡張 | エンタープライズ | マイコミジャーナル参照。


XCode4のプロジェクトテンプレートが作れない!

XCode3では、自分がよく使うframeworkとか、よく使うマクロを予め定義したヘッダファイルとか、自分が整理しやすいディレクトリ構成とかをもったプロジェクトテンプレートをXCode上で作り込むことができて、それをプロジェクトの新規作成をするときに選択することが出来た。
仕組みはとても単純で、テンプレート中のファイル名とディレクトリ名とテキストファイルの内容を一切合切、
___PROJECTNAME___→プロジェクト名
___PROJECTNAMEASIDENTIFIER___→プロジェクト名のスペースをアンダースコアに置換した文字列
に置換するというものだった。

XCode4で、自分が作ったプロジェクトテンプレートが選べなくなっていたので、くそっと思って同じようにプロジェクトテンプレートを作ろうと思った。

調べた。

なるほど、XCode上ではテンプレートの編集はできない、と
TemplateInfo.plistファイルをごりごりいじって、と
TemplateInfo.plistが階層構造になって親を継承してるから、それを変更しようと思ったら親の定義を全部持ってきて・・・
AppDelegateクラスにメンバー変数を加えるには・・・
QwartsCore frameworkを加えるには・・・


ぷちっ。

できるかっ!こんな面倒なもんできるかっ!

そんなわけで、XCode3形式のテンプレートをXCode3のときみたいに一切合切文字列置換するrubyスクリプトを作った。プロジェクト新規作成画面で選択できないけど、これを使ってプロジェクト新規作成すればいいんだ。


# XCode3タイプのプロジェクトテンプレートを文字列置換して新しいプロジェクトを作成する
class Replacer
@srcDir
@dstDir
@projectName
@projectNameIdent

# エントリポイント
def main(templateDir, projectDir)
if !templateDir || !projectDir then
p "USAGE: ruby replacetemplate.rb (template dir) (project dir)"
return
end

if File.exist?(projectDir) then
p projectDir + " is already exists."
return
end

@srcDir = templateDir
@dstDir = projectDir
@projectName = File.basename(projectDir)
@projectNameIdent = @projectName.gsub(" ", "_")

p "processing " + @projectNameIdent + " ..."
Dir.mkdir(@dstDir)
processDir(@srcDir, @dstDir)
end

# 文字列置換
def tr(str)
return str.gsub("___PROJECTNAMEASIDENTIFIER___", @projectNameIdent).gsub("___PROJECTNAME___", @projectName)
end

# ディレクトリ処理
def processDir(src, dst)
puts "dir : " + src + "->" + dst
Dir.foreach(src){|item|
if item != "." && item != ".." then
srcPath = src + "/" + item
dstPath = dst + "/" + tr(item)
if File.directory?(srcPath) then
Dir.mkdir(dstPath)
processDir(srcPath, dstPath)
elsif File.file?(srcPath) then
processFile(srcPath, dstPath)
end
puts item
end

}
end

# ファイル処理
def processFile(src, dst)
puts "file : " + src + "->" + dst
of = open(dst, "w")
begin
File.foreach(src) {|line|
of.print(tr(line))
}
ensure
of.close
end
end

end

r = Replacer.new
r.main ARGV[0], ARGV[1]



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。