引っ越しました。

このブログは引っ越しました。
今後は引越し先で更新を続けます。
新しいブログではソースコードにシンタックスカラーを付けているので見やすくなっていると思います。

こちらは数ヶ月後に削除しますのでよろしくお願いします。

2010年7月12日月曜日

UIviewはUIViewControllerを知らない

ブログ移行しました。
新しいブログでのこの記事はUIviewはUIViewControllerを知らないこちらです。
シンタックスカラーなど導入しているのでソースコードが見やすくなっているはずなので是非っ。


UIView上でモーダルビューを実装しようとして必死にpresentModalViewController呼んでた。
先日ようやくViewDidLoadとInitWithFrameの違い覚えたばかりだというのに。

UIViewはUIViewControllerの存在を知らない。
ちぃ覚えた。

参考サイト
viewDidAppear/viewDidDisappearが呼ばれない

モーダルビューを表示した時に前のビューのツールバー、ナビゲーションバーが残る時の対処法

タイトル通りの症状。
この症状が出た人は恐らく下のソースと似たようなソースになってるんじゃないかと。
自分はTestViewClassでモーダルを呼び出したときにこの症状が出ました。

AppliNameAppDelegate.h
@interface AppliNameAppDelegate : NSObject  {
 UIWindow* window_;
 TestViewClass *testClass;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;

@end
AppliNameAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

 // windowを自分で作成
 CGRect bounds = [[UIScreen mainScreen] bounds];
 window_ = [[UIWindow alloc] initWithFrame:bounds];

 testClass = [[[TestViewClass alloc]init]autorelease];
 
 UINavigationController *NavigationController =
  [[UINavigationController alloc] initWithRootViewController:testClass] ;
 
 [window_ addSubview:NavigationController.view];
 [window_ makeKeyAndVisible];
 
 return YES;
}

対処としてはAppliNameAppDelegate.mの下記の部分で
UINavigationController *NavigationController =
[[[UINavigationController alloc] initWithRootViewController:paging] autorelease];
NavigationControllerをautoreleaseしていたらこれを消してやる。
んでUINavigationControllerは.mじゃなく.hの方で宣言しておく。
deallocでreleaseするの忘れずにね。
これで新しくモーダルビューを表示した時にもちゃんとツールバーやナビゲーションバーが表示されるみたい。

TestViewClass上(呼び出した先)でモーダルを表示するとNavigationControllerのautoreleaseが動いて上手く処理されないのかも。

※追記
他の場所で同じような現象が起きたので例のごとく総当りでautorelease, release関係消してみたけど駄目でした。
今回の現象が起きたところは元々処理のさせ方が無理矢理だったからそれが原因なのかもしれないのですが。
とりあえずこの問題解決の糸口はrelease関係じゃないのかもしれません。
…という投げっぱなしな記事。

warning: class 'ClassName' does not implement the 'UI***Delegate' protocol の警告を消す

warning: class 'ClassName' does not implement the 'UI***Delegate' protocol
の警告を消す方法。

クラスの宣言を
@interface ClassName : UIViewController
から
@interface ClassName : UIViewController<UI***Delegate>
に変えるだけ。
<>は半角の<>に直してね。

参考サイト
・『UIActionSheet』を使う時にチョットはまった…。
・warning、error → 検索・翻訳で余計意味不明

2010年7月1日木曜日

UIButtonをクラス化

初級程度の知識しかないと意外と手こずったのでメモメモ。
自分の場合はScrollView上に貼り付けて使うことを想定しているので他の処理をするときは上手くいかないかもしれません。

大体こんな感じ。

@interface CButton : UIViewController {
 UIButton* button;
}
- (UIButton*)getButton;
@end
#import "CButton.h"

@implementation CButton

- (void)viewDidLoad : (NSString*)imageName : (CGPoint)center
{
 button = [UIButton buttonWithType:UIButtonTypeCustom];
 UIImage* img = [UIImage imageNamed: imageName];
 button.frame = CGRectMake( 0, 0, 128, 128 );
 [button setImage:img forState:UIControlStateNormal];
 [button setImage:img forState:UIControlStateHighlighted];
 [button addTarget:super.view.superview
  action:@selector(DidPushButton:)
  forControlEvents:UIControlEventTouchUpInside];
 button.center = center;
}

- (UIButton*)getButton
{
 return btn;
}
@end

以上です。
引数のimageNameはファイル名(UIButtonTypeRoundRectなど自分で用意した画像を表示しないなら省略)、centerはボタンの中心位置。
基本的に普通のUIButtonと変わらないです。
違うのはaddTarget。
addTargetはいつも通りのselfだとタップした時点でエラーで落ちます。
ScrollView上に描画するこの場合は自分より1個上のビュー(要するにScrollViewこと)のsuper.view.superviewを指定してやります。
よくよく考えると「ですよねー」な感じだけど気づくのに時間かかりました…。

あとはボタンのサイズや透過度など別途引数で渡してあげれば汎用性も上がるんじゃないじゃないかと。

※追記
この状態だとScrollView上で用意されてるDidPushButtonの処理になります。
…全然クラス化出来てなくね?
CButtonで宣言したDidPushButtonを処理させるにはどうすればいいだろう。

※追記
複数の違う処理をするボタンはTagを使うといいみたいです。
button.tagでそれぞれの処理に振り分ける、みたいなやり方。