1

みんな地獄:)

iOSでのUITablewViewControllerの使用経験は、残念ながら非常に限られています。アプリケーションで必要なのは、現在Webサーバーにアップロードされているアクティブなアップロード(ビデオ、オーディオなど)ごとに1つのカスタムセルを含むUIテーブルビューです。

これらの各アップロードはバックグラウンドで非同期に実行され、更新の進行状況をパーセンテージで示す、それぞれのセルのUILabelなどをすべて更新できる必要があります。

今、私はうまくいく解決策を見つけました。問題は、それが実際に安全かどうかわからないことです。私自身の結論に基づいて、私は実際にはそうではないと思います。私がしているのは、作成中のセルからUIViewの参照を取得し、それらの参照をアップロードオブジェクトに保存して、ラベルテキストなどを自分で変更できるようにすることです。

私自身の解決策

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *CustomCellIdentifier = @"CustomCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];

if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"UploadCellView" owner:self options:nil];

    if ([nib count] > 0)
    {
        cell = customCell;
    }
    else
    {
        NSLog(@"Failed to load CustomCell nib file!");
    }
}

NSUInteger row = [indexPath row];
UploadActivity *tempActivity = [[[ApplicationActivities getSharedActivities] getActiveUploads] objectAtIndex:row];

UILabel *cellTitleLabel = (UILabel*)[cell viewWithTag:titleTag];
cellTitleLabel.text = tempActivity.title;

UIProgressView *progressbar = (UIProgressView*)[cell viewWithTag:progressBarTag];
[progressbar setProgress:(tempActivity.percentageDone / 100) animated:YES];

UILabel *cellStatusLabel = (UILabel*)[cell viewWithTag:percentageTag];

[cellStatusLabel setText:[NSString stringWithFormat:@"Uploader - %.f%% (%.01fMB ud af %.01fMB)", tempActivity.percentageDone, tempActivity.totalMBUploaded, tempActivity.totalMBToUpload]];

tempActivity.referencingProgressBar = progressbar;
tempActivity.referencingStatusTextLabel = cellStatusLabel;

return cell;
}

ご覧のとおり、これは私が十分ではないことをしていると思うところです。tempActivity.referencingProgressBar = progressbar; tempActivity.referencingStatusTextLabel = cellStatusLabel;

アップロードアクティビティは、このセルに保存されているコントロールへの参照を取得し、それらを自分で更新できます。問題は、これが安全かどうかわからないことです。参照しているセルが再利用されたり、メモリから削除されたりした場合はどうなりますか?

基になるモデル(アップロードアクティビティ)を単純に更新してから、UIテーブルビューに変更されたセルを再描画させる別の方法はありますか?最終的にUITableViewCellをサブクラス化し、アップロードを継続的にチェックしてから、自分でアップロードさせることができますか?

編集

これは、アップロードアクティビティオブジェクトが参照UIコントロールを呼び出す方法です。

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
if (referencingProgressBar != nil)
{
    [referencingProgressBar setProgress:(percentageDone / 100) animated:YES];
}

if (referencingStatusTextLabel != nil)
{
    [referencingStatusTextLabel setText:[NSString stringWithFormat:@"Uploader - %.f%% (%.01fMB ud af %.01fMB)", percentageDone, totalMBUploaded, totalMBToUpload]];
}
}

私の唯一の懸念は、これらのオブジェクトが非同期で実行されるため、ある時点でUIテーブルビューがこれらのアップロードオブジェクトが指しているセルを削除または再利用することを決定した場合はどうなるでしょうか。あまり安全ではないようです。

4

1 に答える 1

2

アップロードしているバックグラウンドプロセスがあると仮定すると、2つの可能性があります。

  1. テーブルビューはデリゲートであり、uploadProgress関数を実装します
  2. テーブルビューはuploadProgressNSNotificationsをリッスンします

2つ目は実装が簡単で、リスナーをviewdidappear/viewdiddissappearに開始/停止するだけです。次に、アップロードで進行状況を追跡し、進行状況に整数値を与えるuserinfoを添付した通知を発行できます。テーブルには、受信中のこの通知を処理し、セルを再描画する機能があります。NSNotificationのuserinfo部分にデータを追加する方法は次のとおりです。

もっと凝ったものにしたい場合は、アップロードIDを設定し、これをセルインデックスにマップして、その特定のセルのみを再描画することができます。これを行う方法を説明する質問と回答があります。


現在、IOS dev envにアクセスできないため、嫌な擬似コード

アップロード機能:

uploadedStuff{
  upload_id = ... // unique i, maps to row in table somehow
  byteswritten = ...
  bytestotal = ....
  userinfo = new dict
  userinfo["rowid] = upload_id
  userinfo["progress"] = (int)byteswritten/bytestotal
  sendNotification("uploadprogress",userinfo)
}

tableview.m:

viewdidappear{
  listenForNotification name:"uploadprogress" handledBy:HandleUploadProgress
}

viewdiddisappear{
  stoplisteningForNotification name:"uploadprogess"
}

HandleUploadProgess:NSNotification notification {
 userinfo = [notification userinfo]
 rowId = [userinfo getkey:"rowId"]
 progress = [userinfo getkey:"rowId"]
 // update row per the link above
}
于 2012-02-16T18:24:32.687 に答える