UITableViewCellの高さを内容に合わせて変化させる

平成22年3月10日(水) 15時29分42秒
区分
objective-c
報告者:
masuda

こんにちは。

今回はUITableViewにおいてcellの高さをcellの内容に合わせて変化させるということをやってみます。

Natsuliphoneのソースを参考にさせていただきました。

UITableViewでcellの高さを設定するには、UITableViewDelegateのtableView:heightForRowAtIndexPath:メソッドを実装して高さを返してあげます。
ただ、ここに問題があってこのメソッドが呼び出される時点ではcellができていないのです。
ですので、cellForRowAtIndexPath:メソッドなどでcellを取得してそのcellの高さを返すというような方法をとることができません。

そこで対象となるcellに高さを計算するためのクラスメソッドを実装し、そこで得られた値をtableView:heightForRowAtIndexPath:に返します。

+ (CGFloat)heightWithContents:(NSString *)contents
{
    CGFloat result;
    CGSize  labelSize;

    result = 0.0;
    labelSize = [contents sizeWithFont:[UIFont systemFontOfSize:16.0]
                     constrainedToSize:CGSizeMake(300.0, 10000)
                         lineBreakMode:UILineBreakModeWordWrap];
    result += labelSize.height;

    return result;
}

複数行にわたるtextの高さを求めるにはsizeWithFont:constrainedToSize:lineBreakMode:メソッドを使用します。
sizeWithFont:forWidth:lineBreakMode:メソッドは1行だけのサイズを返しますので、名前にだまされないようにしてください。

参考: Natsuliphoneのソース

>View Comments          このページの上へ戻る

衝突判定でウロウロする

平成22年3月9日(火) 04時44分40秒
区分
canvas
報告者:
komagata

身に覚えの無い商品がAmazonから送られてくる。komagataです。

canvasでウロウロするものに衝突判定を追加してみました。

(今回はAndroidエミュレーターで機種はNexus Oneで動作させてみましたが、webkitなのでiPhone用から何の変更も無しに動いたのは楽でした。)

5554:nexus_one

http://komagata.org/canvas-prowler/3/

(iPhoneやAndroidでアクセスしてみて下さい)

自分で作る前に、文系プログラマー的にはゲームプログラムはどういう実装をすればいいのかを言葉で知りたかったので実装のイメージ的なところを以前のモノと合わせて言葉で説明したいと思います。

移動方法の実装イメージ:

まず、キャラクターの描画はフレーム毎に定期的に(30fpsとかで)描画します。描画はキャラクタの現在持っている座標に単に描画するだけです。

それとは別にクリックイベントをトリガーとしてプレイヤーキャラクターとクリック地点をプレゼンハムアルゴリズムで直線を引き(実際には描画しない)、その直線の座標を配列としてプレイヤーキャラクターの移動のためのバッファ(キュー)に格納します。

キャラクターはクリックイベントには感知せず、1フレーム毎に自分の移動バッファに座標があれば一つづつ消費しながら自分の座標を変更していき、バッファに無ければ何もしません。

クリックイベント時には移動バッファが残っていても空にした上で新しい経路を設定するのでクリックした瞬間に進路を変更します。

衝突判定:

何かが有る度に、それぞれのオブジェクト(プレイヤー、背景、障害物など)を全て走査、それぞれのオブジェクトが持つプレイヤーフラグ、障害物フラグを見て処理します。(これは関係無いオブジェクトも毎回走査することになるのでとてもヘボイやり方でした。イベント毎にイベントリスナーを登録するように次は変更したいです。)

プレイヤーキャラクターの移動バッファの次の移動場所が障害物フラグを持つオブジェクトと衝突している場合に移動を中止して以降の移動バッファもクリアします。

シンプルなドット絵を対象にしているので四角形と四角形の衝突を判定するのはとても楽です。

少しハマったのは、衝突した時点で移動バッファをクリアするのではなく、衝突する一歩前で次の移動地点を見てバッファをクリアしなければならないというところです。

衝突した時点でバッファをクリアすると、見た目上は分かり辛いですが、一歩分障害物にめり込んでいるので障害物に接触した瞬間動けなくなります。

この変な動きも面白かったですが、プログラムを見直して、なるほどなあと思いました。

次回もこれに新しい要素を付け加えたいと思います。

>View Comments          このページの上へ戻る

多段 ssh で vnc

平成22年3月5日(金) 14時30分10秒
区分
ssh
報告者:
tahara

こんにちは!! tahara です。

例えば host1 を経由して host2 に vnc したい場合どうすればいいか調べてみました。 結果 ↓ のページに書かれてあるとおりすれば可能でした。ありがとうございます。

ssh を多段に使ってずっと遠くにあるマシンに port forward する|裏表(Phinloda のもう裏だか表だか分からないページ)

蛇足になりますが、次の手順で host2 に vnc できました。

>View Comments          このページの上へ戻る

MacOSX上でMacPortsを使わずにRails開発環境を作る

平成22年3月4日(木) 23時49分51秒
区分
MacPortsよりfink
報告者:
chiba

こんにちは、chibaです。
MacOSX上などにRails開発環境を複数作らなくてはいけなくて色々試行錯誤しています。
環境は、

  • デザイナーさん制作ツール: Coda
  • Ruby on Rails
  • Apache2
  • MacOSXだったり
  • Linuxだったり
  • 貧乏
という感じで、OS環境を2〜3種跨ぎ、かつ、MacOSXとWindowsは主にデザイナーさんが利用するプラットフォームです。
  1. Linuxなら直にRoR環境を構築してしまえば良いし、デザイナーさん達がLinuxは使うことはない
  2. MacOSXも直にMacPortsなどを利用してRoR環境を構築すれば良いけれど、デザイナーさん達はMacOSXをメインに使うらしいので、勝手に各自RoR環境を構築してみて下さいとも言いがたい
  3. 何か問題が起きた場合に、各自で環境を構築してもらうと、何がどうなってエラーになっているのか探るのが面倒臭い
という状況でした。
適当に考えた末、VirturlBox上にRoRの環境を構築し、そのVMイメージを皆で共有すれば楽チンで良いに違いない!ということで試しに、MacOSXの上にVirturlBoxを導入してみました。
ホスト<=>VM間のファイル共有はNFS。
本当は、VirturlBoxの共有ファイル機能を利用したかったのですが、なんだか上手く動かせなかったのでNFSに。
ローカルのファイルをCodaで編集して、Apache/VirturlBoxがホストするページをローカルのブラウザで眺める、という感じで作業してもらうことになりました。
MacOSXは、NFSなどの上で作業すると、._unkoや、.DS〜というファイルを大量にばらまきますが、この構成の場合、作業ディレクトリはホスト側なのでそういうこともありません。
とりあえず、LinuxとMacOSXをホストにして実際に使ってみていますが、可もなく不可もないような、微妙な環境ができあがりました。
もっと他にナイスな組み合わせを教えてください…。■

>View Comments          このページの上へ戻る

canvasでウロウロする(2)

平成22年3月3日(水) 18時31分08秒
区分
canvas
報告者:
komagata

火曜日担当なのに間に合わずに水曜日にアップしている2010生まれてこなかった方が良かった男オブザイヤー候補、komagataです。

canvasでウロウロするのをiPhoneにフィットするように修正しました。

canvas prowler2

http://komagata.org/canvas-prowler/2/

解像度がファミコンは224x256に対してiphoneは320x480なので細かいですね。

ソース:2 at master from komagata's canvas-prowler - GitHub

>View Comments          このページの上へ戻る

UITextFieldに入力されている文字数を動的に、非同期に数える。

平成22年3月3日(水) 11時06分22秒
区分
objective-c
報告者:
masuda

2週間連続で原稿を落としたmasudaです。
こんにちは。

あまりググればわかるということは書きたくはないなと思っているので、なかなかネタを見つけるのは難しいです。

今回はiPhoneアプリを書いているときにはまったところで、ググってもなかなか答えが見つからないことを書きたいと思います。

2つあるので2週間はこれで持つ!

とあるUITextFieldによる入力フォームと、UIBarButtonItemによる「完了」ボタンがある画面を考えます。

今回のエントリの目的はUITextFieldに文字が入力されていない、つまり空であるときは、「完了」ボタンを表示しない画面を作成するということです。

ポイントはUIControlEventEditingChangedイベントを使うこと。
最初はUITextFieldDelegateのtextField:shouldChangeCharactersInRange:replacementString:とかを使用することを考えましたが、文字を消去したときにボタンが消えない等々うまくいきませんでした。

サンプルコードを書いてみます。

- (void)setupUserInterface
{
    UIView      *contentView;
    UITextField *textField;

    contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    [self setView:contentView];
    [contentView release];

    doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                               target:self
                                                               action:@selector(respondsToDoneButtonTouchDown:)];

    textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
    [contentView addSubview:textField];
    [textField release];
    [textField addTarget:self
                  action:@selector(respondsToEditingChanged:)
        forControlEvents:UIControlEventEditingChanged];
}


- (void)respondsToEditingChanged:(id)sender
{
    if ([sender isKindOfClass:[UITextField class]])
    {
        // 本当はsenderを用いずにメンバ変数とかにしておけばいいのだけれど、今回はあえて型変換をしてみる。
        if ([[(UITextField *)sender text] length])
        {
            [[self navigationItem] setRightBarButtonItem:doneButton animated:YES];
        }
        else
        {
            [[self navigationItem] setRightBarButtonItem:nil animated:YES];
        }
    }
}

参考
Disable button if textField is empty - iPhone SDK Development

>View Comments          このページの上へ戻る

iPhone アプリケーションの開発

平成22年2月26日(金) 16時42分10秒
区分
iPhone
報告者:
tahara

こんにちは!! tahara です。

突然ではありますが、とりあえず読むべきは iPhone Dev Center にある以下のドキュメントでしょうか。

まずは iPhone ヒューマンイン ターフェイス ガイドライン を読んでみました。

iPhone が他と違うところ

  • 小さい画面サイズ。 480x320
  • メモリ少ない。OS が警告をくれたらすぐにメモリ開放すべすし。didReceiveMemoryWarning
  • 1画面。ある意味 Stumpwm!
  • さらに、同時に1アプリケーション。
  • 標準に準拠してヘルプコンテンツを最小限にすべし。

3つのアプリケーションの形態

  • iPhone アプリケーション
  • Web 専用contents
  • ハイブリッドアプリケーション(上の2つの組み合わせ)

3つのアプリケーションスタイル

  • 生産性型アプリケーション(例 Mail)
  • ユーティリティ型アプリケーション(例 Weather)
  • 没入型アプリケーション(例 ゲームアプリ)

デスクトップアプリを移植する場合はよく使われる 20% の機能のみに絞る。

ヒューマンインターフェイスの原則

  • 自然なメタファで
  • 具体的なものを直接いじる感覚
  • テキスト入力を最小限に、選択肢を提示
  • ユーザの操作に対するフィードバック、効果的なやりとり
  • ユーザが開始でき、それを停止できる動きであること
  • インターフェイスの一貫性

製品定義ステートメントを作りましょう。

  • 対象ユーザを明確化
  • 実装機能の限定

簡潔さと使いやすさ

  • 使い方を明白に
  • 頻繁に使用される情報を画面上部に集中
  • テキスト入力を最小限
  • 重要な情報を簡潔に
  • タップ可能な要素の領域は指先サイズに

製品ステートメントにふさわしい主たる機能に焦点を当て、 簡潔かつ入力を最小限にする。

ジェスチャを適切にサポートする。

  • 単純かつ簡単な方法は必須
  • 新しいジェスチャを定義しない

ブランドはささやかで控え目に。 ただしアプリケーションアイコンにはブランドももりこむ。

一般的なタスク

  • 開始
    • ステータスバーに適切なスタイルを設定する
    • 最初の画面に似た起動画面を用意して感覚的起動時間を短縮する
    • 余計なスプラッシュ画面は不要
    • 基本縦で起動
    • 最後に実行したときの状態を復元する
  • 停止
    • いつでも停止できるように
    • 停止時は次の起動のために可能なかぎり詳細の情報を保存しておく
  • 設定(Settings)と設定オプション
    • 設定は一度設定したら変更しないもの
    • 設定オプションは頻繁に変更する可能性があるもの
    • 理想はユーザに設定を要求しないこと
  • その他いろいろ ... ちょっと省略してしまいました。

ユーザインターフェイスの設計

  • ステータスバーはあまりいじらない
  • ToolBar は 44x44 で5つ以下が妥当
  • Tab Bar はモードの切り替え。 5つまでは横に並んで、それをこえたものは More に。 バッジを表示できる。
  • モーダルビューは煩わしいので乱用しない。
  • Action Sheet はユーザの選択肢でり複数のボタンを備える。 害のあるものは赤で一番上に。
  • モーダルビューは主たる機能が関連する自己簡潔型のタスクで(例 Mail のメッセージ作成)
  • アクティビティインジケータ
    • ステータスバーのは1〜2秒ネットワークにアクセスする場合
    • もっと時間がかかる場合はツールバーに表示
  • 進捗がわかるものは Progress View
  • Text Field は左端に使用目的、右端に追加機能
  • システムが用意しているボタン、アイコンを意図されたとおり使う
    • ユーザにやさしい
    • 工数削減

アイコン、画像の作り方の説明でおしまい。

このようなドキュメントがしっかり用意されているのは素晴しいですね。

>View Comments          このページの上へ戻る

C-s/C-rを使おう

平成22年2月26日(金) 00時19分21秒
区分
Emacs
報告者:
chiba

chibaです。依然としてネタ切れです。
WordPressのことを調べようと思って前フリしてましたが、これまた全然進んでません。

ということなので、最近知ったEmacsの知ってる人には、当たり前な機能を紹介したいと思います。
Emacs使いの方は、C-sはもちろん良く利用すると思いますが、C-sで検索モードに入ってからの、C-w、M-yが便利であることを最近知りました。
C-wで単語単位で検索ワードを漸増しつつ検索できたりしますし、M-yは最新のキルリングの内容で検索できます。

また、C-sの応用として、カーソル移動に積極的にC-s/C-rを利用するのも非常に便利であることを再認識しています。
viだとf〜などが便利なのでfを良く使うのですが、EmacsでもC-sで似たようなことはできるんだなあと。
10年位使っていますが、この10年間だいぶ損をしていたなあと思った次第です。

>View Comments          このページの上へ戻る

プレゼンハムでウロウロする

平成22年2月23日(火) 20時44分15秒
区分
canvas
報告者:
komagata

komagataです。

前回は矢印キーでウロウロしたのでマウスクリックでウロウロするものを作りました。

canvas

http://komagata.org/canvas-prowler/1/

直線や曲線を整数で高速に描画するプレゼンハムアルゴリズムでクリック地点までの経路を計算して近付きます。

グラフィックのプログラミングは間違えても変な動きをしたりして面白いですね!

>View Comments          このページの上へ戻る

Lisp on Rails 第4回 〜 has-many

平成22年2月19日(金) 23時09分06秒
区分
Lisp on Rails
報告者:
tahara

こんにちは!! tahara です。 Lisp on Rails 第4回です!

今回は ActiveRecord の has_many アソシエーションもどきを実装したいと思います。 前回の belongs_to とほとんど同じです。 ar-has-many-direct-slot-definition と ar-has-many-effective-slot-definition を定義します。

(defclass ar-has-many-slot-mixin ()
  ((has-many :initarg :has-many
             :initform nil
             :accessor has-many)
   (class-symbol :initarg :class-symbol
                 :initform nil
                 :accessor class-symbol)))

(defmethod initialize-instance :after ((self ar-has-many-slot-mixin) &rest args)
  (declare (ignore args))
  (unless (class-symbol self)
    (setf (class-symbol self)
          (sym (singularize (has-many self))))))

(defclass ar-has-many-direct-slot-definition (ar-direct-slot-definition
                                              ar-has-many-slot-mixin)
  ())

(defclass ar-has-many-effective-slot-definition (ar-effective-slot-definition
                                                 ar-has-many-slot-mixin)
  ())

direct-slot-definition-class と effective-slot-definition-class と compute-effective-slot-definition でゴニョゴニョすると上記の slot-definition が使えるようになります。

slot-value-using-class と (setf slot-value-using-class) で関連テーブルの 取得と設定を行います。

(defmethod c2mop:slot-value-using-class
  ((class active-record-class)
   instance
   (slot-def ar-has-many-effective-slot-definition))
  (aif (call-next-method)
       it
       (setf (slot-value instance (has-many slot-def))
             (all (find-class (class-symbol slot-def))
                  :conditons (list (key-sym (class-name class) '-id)
                                   (%value-of instance :id))))))

(defmethod (setf c2mop:slot-value-using-class) :after
           (new-value
            (class active-record-class)
            instance
            (slot-def ar-has-many-effective-slot-definition))
  (loop with id = (%value-of instance :id)
        with column = (str (class-name class) "-id")
        for x in new-value
        do (setf (%value-of x column) id)))

で、だいたいこんな感じで使えるようになります。

(def-record comment
    (:belongs-to post))
(def-record post
    (:has-many comments))
(let* ((post (car (all post)))
       (comments (comments-of post)))
  (mapc #'describe comments))

以上、なんとなく has-many できました。 ソースはこちらから http://github.com/quek/lisp-on-rails

第5回につづきます

>View Comments          このページの上へ戻る

技師部隊からの
お知らせ

インフルエンザに気をつけて頑張っています

本頁の来客数
一万七千五百五十三名

メンバー一覧

アクトインディ技師部隊員名簿

アクトインディへ

投稿する

カテゴリー

アクトインディ

aaaa