忍者ブログ
[1] [2] [3] [4] [5] [6] [7] [8] [9
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。


UTableViewを使っているとちょくちょく登場してくるNSIndexPath。

今までは、この詳細まで意識する必要がなかったのであまり気にしていなくて、どこをさしているかが入っているものくらいにしか考えていなかった。
確かに、それで間違っている訳ではないのだが、その詳細についてはよくわからなかった。

今回、テーブル内容の削除や変更と連動していろいろと操作が必要となったので、調べる必要がでたので、ここに残す。

単純に参照する時には、下記のように指定する事で取り出せていた。

    NSInteger row = indexPath.row;

これがあるのだから、中身の設定(変更)も、単純に設定できると思っていたが、そうではなかった。

結果的には下記のようにする事で設定が出来た。

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:1];

参照と設定の方法が、別々のやり方が必要なのは少し分かりにくいと思う。

拍手[0回]

PR

昨日に続いて、coredataの使い方で躓いてしまったので、また残す事にする。

coredataのデータ更新自体は、サンプルのソースがたくさん出ていて、特に悩む事はないと思う。
しかし、今回は、うまく更新が出来ない現象に当たってしまった。
しかも、シミュレータでは、特に問題なく動作したのだが、実機を使うと失敗してしまった。
この手の現象が最も困ってしまう。

今回は、データベースのデータ構造として、少し複雑な構造を設計していた。
昨日の記事にも書いている事から分かるように、独自のクラスを追加して、データに使用した。
それだけであれば、おそらく問題は出なかったと思う。

データの構造を簡単に書くと、メインの配列があり、そのメンバに、さらに配列を作り、メンバが独自クラスという構造。
簡単に書くとい可能なイメージ。

メインのcoredataから管理するデータ(xcdatamodeldに書いてあるメンバ)

@interface DataGroup : NSManagedObject

NSString *sampleName;
NSMutableArray *arrayObject;
(このNSMutableArrayは、実際には、Transformable)

NSMutableArray *sampleObject;に設定する内容として、下記のクラスを作成

@interface DataObject : NSObject

NSString *itemName;
UIImage *itemObject;
double itemDouble;

こんな感じ。

データの更新タイミングで、単純に変更したパラメータのみ設定して書き込みを行う。
その上で、再読み込みをすると、設定した内容を取り出す事が出来た。
これで問題ないと思って、次の作業を行っていたのだが、しばらくして実機で確認した。

すると、更新して保存、再読み込みと特に問題なく出来たのだが、アプリを再起動して読み込むと、データが消えている。
「arrayObject」に新規の「DataObject」のメンバを追加して保存するのだが、アプリ再起動後は、メンバがいなくなる。
シミュレータで同じ事を行うと、アプリ再起動後も正しく再設定した内容が取り出せる。
この中途半端さ加減に参ってしまった。

いろいろ考えた結果、失敗するパターンの事のみ考えて、下記のような対策を行った。
「arrayObject」に入っているクラスそのものは、使い回していたのをやめて、新規に作成する事にした。

下記が、対応後のソース
    DataGroup *selectedObject = [[self fetchedResultsController] objectAtIndexPath:editGroupNo];
    NSMutableArray *editArray = selectedObject.arrayObject;
    DataObject *editData = [[DataObject alloc]init];

     [editArray addObject:editData];
    
    NSMutableArray *saveArray = [NSMutableArray array];
    NSInteger cnt,loopMax;

    loopMax = editArray.count;
    
    for (cnt=0; cnt<loopMax; cnt++) {
        [saveArray addObject:[editArray objectAtIndex:cnt]];
    }
    
    selectedObject.pinArrayObject = saveArray;
    
    // saveメソッドで更新状態を確定
    error = nil;
    if (![context save:&error]) {
        NSLog(@"error = %@", error);
        abort();
    }


これで、メンバの追加がうまくいくようになった。

しかし、独自クラス内のメンバの内容を更新しても変更されない現象が続けて発生した。
たとえば、上記の構想の「itemName」のみを変更してアプリを起動したままし読み込みをすると、変更されていた。
しかし、アプリを再起動すると、変更前のデータが出てきた。
これも、シミュレータで同じ事を行うと、アプリ再起動後も正しく再設定した内容が取り出せる。

このような現象が起きてしまったら、あまり行いたくない事であったが、一度、削除してから再設定を行う事で、対策する事が出来た。
    DataGroup *selectedObject = [[self fetchedResultsController] objectAtIndexPath:editGroupNo];
    NSMutableArray *editArray = selectedObject.arrayObject;
    DataObject *editData = [editArray objectAtIndex:editItemNo];

    selectedObject.pinArrayObject = nil;
    
    // saveメソッドで更新状態を確定
    error = nil;
    if (![context save:&error]) {
        NSLog(@"error = %@", error);
        abort();
    }

    editData.itemName = @"変更後の文字列";

    NSMutableArray *saveArray = [NSMutableArray array];
    NSInteger cnt,loopMax;

    loopMax = editArray.count;
    
    for (cnt=0; cnt<loopMax; cnt++) {
        [saveArray addObject:[editArray objectAtIndex:cnt]];
    }
    
    selectedObject.pinArrayObject = saveArray;
    
    // saveメソッドで更新状態を確定
    error = nil;
    if (![context save:&error]) {
        NSLog(@"error = %@", error);
        abort();
    }


これで、メンバ内のデータ更新がうまくいくようになった。
coredataは使いやすいような使いにくいような、なかなか謎が多いのかもしれない。

拍手[0回]


久々にここの開発関連の記事を追加したが、やはり、気になった事は、出来るだけ書き残していこうと思い、さらに更新。

今度は、タイトルにあるように比較的単純なお話。

UITabaleViewの背景色が、なぜか思い通りにならない現象が発生した。

現象としては、iPhone用の画面では、特に問題なく表示されていた。
(今回は、scroll view textured background colorに設定したUIImageの上にUITableViewを背景色として白を指定)

ある程度の作成を行った所で、iPad用のレイアウトをストーリーボードで作成。
すると、UITableViewの背景色が、その下にあるUIImageの色と同じとなった。

iPhoneとiPadのパラメータを比較しても特に差分はない。
いろいろなパラメータを変更したが一向に変化なし。

最終的に、ある意味、一番単純な方法のソース上で色指定すると、表示された。

self.tableView.backgroundColor = [UIColor whiteColor];

こんな単純な事なのに、ストーリボードのバックグランドの色指定をどんなに変更しても変わらなかった。
何とも不思議な現象だった。

拍手[0回]


久々に、開発関連の記事を書く事にする。

最近は、今までに使った事のある内容の組み合わせで開発を行っていた。
そのため、ちょっとした事で引っかかった事は会ったのだが、その都度、検索して解決させて、記事にするのを失念してしまっていた。
今回は、結構試行錯誤しながら進めたので、きちんと書いておく事にした。

タイトルにあるように、現在、coredataを使用したアプリを作成中。

coredata自体は、以前も使った事があったが、今回は、独自クラスをデータベースに保存するようにした。

coredataの使い方は、省略させていただく。

データベースに保存するデータのクラス(型)は、選択肢から選ぶ事になるのだが、種類はさほど多くない。
さらに、タイトルにあるように、独自のものを保存したい場合も多いので、単純にはうまくいかない。

そこで用意されているものが「Transformable」だ。
名前の通り、変更可能となる。

ここで、変更可能と言っても、そのまま設定しようとしてもエラーが出るだけ。
-[Sample initWithCoder:]: unrecognized selector sent to instance 0xXXXXXXX'
こんな感じのエラーが発生する。
これは、指定されているもの(Sample initWithCoder:この部分)が、存在しないとおこられてしまう。
実装上、こんなものをコールする事は無いのだが、「Transformable」に設定しようとする時に、自動的に変換する為にコールされるようだ。
「Transformable」と指定されたものは、NSDataに自力で変更する必要があるらしい。
標準のクラスには、変換の為のものが、入っているものもあるが、独自であれば、当然ない。

こういわれてしまうのであれば、単純にそれを追加すればよいという事。
ただし、上記で指摘されてたものとペアとなる「encodeWithCoder」

その結果追加したものが、下記の内容。
- (void)encodeWithCoder:(NSCoder*)coder
{
    [coder encodeInteger:_itemNo forKey:@"itemNo"];
    [coder encodeObject:_itemName forKey:@"itemName"];
    [coder encodeDouble:_itemDouble forKey:@"itemDouble"];
}
- (id)initWithCoder:(NSCoder*)decoder
{
    self = [super init];
    _itemNo = [decoder decodeIntegerForKey:@"workOfArt"];
    _itemName = [decoder decodeObjectForKey:@"itemName"];
    _itemDouble = [decoder decodeDoubleForKey:@"itemDouble"];
    
    return self;
}



サンプルとして、3種類をいれて、それぞれ、NSInteger、NSString、doubleとしてみた。
他のクラスや型を使用したいと思った場合も上記と変わらない。
「encodeInteger」等の部分を、encodeのあたりまで入力すると、xcodeの補完機能で一覧が出るため使用しているものにあうと思われる名前のものを選択するとよいようだ。

ここまでは、まだ、比較的簡単に進める事が出来たのだが、標準のクラスだが、NSDataへの変換に対応していない場合にはまってしまった。

いろいろと調べてみたり試したりしたのだがうまくいかない。
きっと、うまく対応させる方法があるのだと思うのだが、そこまでは分からなかった。
結果的に、変換不可のクラスの、自分の使用したパラメータを、複数の変更可能なクラスに分て保存する事にした。
こうすれば、深く考える事無く対応する事が可能。
当然、その事は始めから分かっている事だったのだが、管理するには、そのまま保存した方がよい事は明らかなので、がんばってみたが、結局断念。

これも、継続して調査して、うまい方法を見つけた時には、置き換えて、ここにも残すつもり。

拍手[0回]


このところ、開発スピードが落ちてしまい、さらに、Xcode的に使った事の無い処理を使う事が無い作業が続いてしまったため、処理無いように関する記事を書く事が出来なかった。

次のアプリ開発で、今までと少し違った事を始めたので、久々に開発に関する記事を書いてみる。

今回は、アニメーション処理。

Xcodeでアニメーション表示を行う場合、いくつかの方法があるのだが、初めなので最も簡単な方法で実装を進めている。
UIViewに対して「animateWithDuration」を使う事で、かなり簡単に画像を動かす事が出来た。


-(void)sample
{
   self.view.frame = CGRectMake(start_positionX,start_positionY,start_sizeX,start_sizeY);
    [UIView animateWithDuration:1.0f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{
                         // アニメーションをする処理
                         self.view.frame = CGRectMake(positionX, positionY, sizeX, sizeY);
                     }
                     completion:^(BOOL finished){
                         // アニメーションが終わった後実行する処理
[self smile2]; }]; }

たったこれだけで、画像の移動、拡大縮小、さらに、その連続ができる。
(上記の例では、アニメション完了後「sample2」が処理される。)
同様に、「view.transform = CGAffineTransformMakeRotation(M_PI);」を指定する事で回転も簡単にできる。

パラメータも比較的単純で、始めから、「アニメーション時間」、「動作開始までの時間」、「動作のパターン」のみの指定となる。
この中の、「options」が、パターンがあまり多くなく、思い通りに動かすには少し苦労する。
パターンとしては、「一定速度」、「だんだん早く」、「だんだん遅く」、「早くなってから遅くなる」の4種類。
これだけしかないので、この中で組み合わせて使うしか無い。
自分は、タイマを併用し、タイミングを計って、別々のアニメーションしているViewを入れ替える事である程度思い通りに動かす事が出来た。
ただ、タイミング的に、なかなかシビアなので、実際にリリースできるものにするまでまだまだ検証が必要。

ここで、さらに思ったのが、何らかの操作を行った場合、その時点でアニメーション動作を止める、又は、動きをかえる事が出来るのか?だった。

いろいろ考えたが結局、止める為の処理を別に組み込む必要があるようだ。

具体的には、以下のように実装した。


BOOL stop_flg;

-(void)sample
{
   stop_flg = NO;
    self.view.frame = CGRectMake(positionX, positionY, sizeX, sizeY);
    [self move];
}
-(void)move
{
    if(stop_flg == YES)return;
    [UIView animateWithDuration:1.0f
                          delay:0.0f
                        options:UIViewAnimationOptionCurveEaseIn
                     animations:^{
                         // アニメーションをする処理
                         self.view.frame = CGRectMake(positionX+X, positionY+Y, sizeX, sizeY);
                     }
                     completion:^(BOOL finished){
                         // アニメーションが終わった後実行する処理
[self move]; }]; } -(void)stop { stop_flg = YES; }
見て分かるとは思うが、細かい動きの連続で、それぞれの動作の開始前(後でもよい)に停止すべきかの判断を行う。
上記の場合、ボタン等から「stop」をコールするだけとなる。

これらの処理の組み合わせだけで、意外と思い通りに動かす事が出来る。

拍手[0回]


リリース済みアプリ

Silmuvide


PseudoRPT


うつすと!


ChronologyMaker


LASI


3行日記


単位計算機


Marking Map Plus


交通費管理


交通費計算リスト


Markin Map


SheepSleepSheep


RootCalculator


元号変換


PieChart


MeasureShooting


SimpleMapCreator



Applivのレビュー記事
http://app-liv.jp/713163900/

ゆびてんじ


PR



Copyright ©   marble seijin の開発日記   All Rights Reserved
Design by MMIT simple_plain Powered by NINJA TOOLS
忍者ブログ [PR]