*

iOSプログラミングのキモ(MainViewController説明)

公開日: : Apple, Computer Language, iOS, iPad, iPhone, Objective-C, XCode

個別の画面のコードについて解説を進めていきます。最初は起動直後の画面であるMainViewControllerの説明です。
IMG_1111

始めにソースコードを掲載してしまいます。正直長いです(^^; どこをどう読んで行けばいいんだ・・って感じですよね。エントリーが長くなってしまうので分けていこうと思いますが 大まかにこのソースでは 以下の点について解説していく予定です。

  • 画面・インスタンス間のデータのやりとり方法(NSNotificationCenter, [[UIApplication sharedApplication] delegate])の使い方
  • Youtubeからのカテゴリ・国別 動画リストの取得方法
  • 外部ライブラリPKRevealControllerの使い方
  • dispatch_asyncとブロック構文を使った 今どきのお手軽マルチスレッドプログラミング

この画面は UITableViewを使った画面構成をしています。UITableViewの解説は 他のブログ・WEBサイトでもたくさん解説があるので、ここではあまりUITableViewについての解説はしません。その代わりに 画面にはあまり出てこない 部分がどのように実装されているかに焦点を当てていこうと思います。

MainViewController.h

//
//  MainViewController.h
//  QTubeTestBrowser
//
//  Created by Matsuda Katsumi on 2013/07/25.
//  Copyright (c) 2013年 LISONAL ltd. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#import "ADSlidingViewController.h"
#import "QTubeVideo.h"

#define kLoadingCellTag 1273
#define kSearchCellTag 12731273

@class QTubeCell;

@interface MainViewController : UIViewController<UITableViewDelegate,UITableViewDataSource,ADBannerViewDelegate>

@property (nonatomic,retain) IBOutlet UITableView *tableView;
@property (assign, nonatomic)int maxResults;
@property (assign, nonatomic)int startIndex;
@property (nonatomic,retain) NSString *region;
@property (nonatomic,retain) NSString *gdataUrlFormat;
@property (nonatomic,retain) NSString *time;

@property (nonatomic,retain) NSArray* videos;

@property (nonatomic,retain) UIRefreshControl *refreshControl;

@property (assign, nonatomic)BOOL nowLoadding;
@property (assign, nonatomic)BOOL allDataLoadding;

@property (assign, nonatomic)BOOL timeEnable;

@property (assign, nonatomic)CGFloat trimY;

@property (nonatomic,retain) NSArray *timeParamsArray;

@property (nonatomic,retain) NSString *searchWords;

@property (assign, nonatomic)BOOL searchMode;
@property (assign, nonatomic)BOOL resetVideoArray;

-(void)gdataLoad;
+(UIImage*)imageResizer30x30:(UIImage*)img_mae;
+(void)cellDownloadStatusSetting:(QTubeCell*)qTubeCell VideoId:(NSString*)videoId;
+(void)cellDownloadStatusSetting:(QTubeCell*)qTubeCell QTubeVideo:(QTubeVideo*)qvideo;
+(void)adSetting:(UIView*)bannerViewFrame UIViewController:(UIViewController*)uIViewController;
@end

MainViewController.m

//
//  MainViewController.m
//  QTubeTestBrowser
//
//  Created by Matsuda Katsumi on 2013/07/25.
//  Copyright (c) 2013年 LISONAL ltd. All rights reserved.
//

#import "MainViewController.h"
#import "WebVideoViewController.h"
#import "JSONModelLib.h"
#import "VideoModel.h"
#import "QTubeCell.h"
#import "YouTubeGdataURL.h"
#import "SearchHistoryViewController.h"
#import "CountrySetting.h"
#import "QTubeVideo.h"
#import "QTubeLoadingCell.h"
#import "LeftDemoViewController.h"
#import "JSONModel.h"
#import "YouTubeURLs.h"
#import "VideoDownloadManager.h"
#import "CountrySettingViewController.h"

@interface MainViewController ()
{
    IBOutlet UITableView *tableView_;
    int maxResults_;
    int startIndex_;
    NSString *region_;
    NSString *gdataUrlFormat_;
    NSString *time_;

    NSArray* videos;

    UIRefreshControl *refreshControl_;

    BOOL nowLoadding_;
    BOOL allDataLoadding_;

    BOOL timeEnable_;

    CGFloat trimY_;

    NSArray *timeParamsArray_;

    NSString *searchWords_;

    YouTubeGdataURL *youTubeGdataURL_;

    IBOutlet SDSegmentedControl *sDSegmentedControl_;

    IBOutlet UIView *bannerViewFrame_;
    //GADBannerView *bannerView_;

    IBOutlet ADBannerView *_bannerView;
}

@end

@implementation MainViewController

@synthesize tableView = tableView_;
@synthesize maxResults = maxResults_;
@synthesize startIndex = startIndex_;
@synthesize region = region_;
@synthesize gdataUrlFormat = gdataUrlFormat_;
@synthesize time = time_;
@synthesize videos = videos_;
@synthesize refreshControl = refreshControl_;
@synthesize nowLoadding = nowLoadding_;
@synthesize allDataLoadding = allDataLoadding_;
@synthesize timeEnable = timeEnable_;
@synthesize trimY = trimY_;
@synthesize timeParamsArray = timeParamsArray_;
@synthesize searchWords = searchWords_;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    }
    return self;
}

+(UIImage*)imageResizer30x30:(UIImage*)img_mae
{
    // リサイズ例文(割合を指定する方法)
    UIImage *img_ato;  // リサイズ後UIImage

    CGSize sz = CGSizeMake(30, 30);
    UIGraphicsBeginImageContext(sz);
    [img_mae drawInRect:CGRectMake(0, 0, sz.width, sz.height)];
    img_ato = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img_ato;
}

-(void)localize
{
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"TodayString", nil) forSegmentAtIndex:0];
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"ThisWeekString", nil) forSegmentAtIndex:1];
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"ThisMonthString", nil) forSegmentAtIndex:2];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    trimY_ = -1.0f;

    refreshControl_ = [[UIRefreshControl alloc] init];
    [tableView_ addSubview:refreshControl_];
    [refreshControl_ addTarget:self action:@selector(refreshOccured:) forControlEvents:UIControlEventValueChanged];

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(gDataURLChanged:) name:YOUTUBE_GDATA_URL_CHANGED object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(regionChanged:) name:NOTIFICATION_COUNTRY_SELECTED object:nil];

    AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];

    searchWords_ = nil;
    self.searchMode = NO;
    self.resetVideoArray = YES;

    maxResults_ = MAX_RESULT;
    startIndex_ = 1;
    region_ = [appDelegate getLocaleCountryCode];
    /*
     time パラメータは、指定された期間内にアップロードされた動画に検索を制限します。このパラメータの有効な値は today(1 日)、this_week(7 日)、this_month(1 か月)、all_time(すべての期間)です。このパラメータのデフォルト値は all_time です。

     このパラメータは、検索フィードと、top_rated、top_favorites、most_viewed、most_popular、most_discussed、most_responded の
     各標準フィードに対してサポートされています。
     */
    timeParamsArray_ = [NSArray arrayWithObjects:@"today", @"this_week", @"this_month", nil];
    time_ = [timeParamsArray_ objectAtIndex:0];

    // 起動初期のフィード・カテゴリを取り出してセット
    NSUInteger a = 0;
    NSArray *jsonArray = [LeftDemoViewController getYouTubeURLsJsonData];
    YouTubeURLs *youTubeURLs = (YouTubeURLs*)[jsonArray objectAtIndex:a];
    youTubeGdataURL_ = (YouTubeGdataURL*)[youTubeURLs.youTubeGdataURLs objectAtIndex:a];
    gdataUrlFormat_ = youTubeGdataURL_.url;
    self.navigationItem.title = youTubeGdataURL_.title;

    switch (youTubeGdataURL_.timeEnable) {
        case 1:
            timeEnable_ = YES;
            break;

        default:
            timeEnable_ = NO;
            break;
    }

    nowLoadding_ = NO;
    allDataLoadding_ = NO;

    //self.navigationItem.rightBarButtonItem.
    self.navigationItem.rightBarButtonItem = [self getRightBarButtonItem];// .image = [MainViewController imageResizer30x30:[UIImage imageNamed:region_]];

    _bannerView.delegate = self;

    [self localize];

    [MainViewController adSetting:bannerViewFrame_ UIViewController:self ];

    [self gdataLoad];
}

-(UIBarButtonItem*)getRightBarButtonItem
{
    UIButton *customView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
    [customView setBackgroundImage:[MainViewController imageResizer30x30:[UIImage imageNamed:region_]]
                          forState:UIControlStateNormal];
    [customView addTarget:self action:@selector(rightNavBarButtonTouched:) forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem* buttonItem = [[UIBarButtonItem alloc] initWithCustomView:customView];
    //self.navigationItem.rightBarButtonItem = buttonItem;

    return buttonItem;
}

-(void)viewWillAppear:(BOOL)animated
{
    //[[UIApplication sharedApplication] setStatusBarHidden:NO];
    //[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
    //[self.navigationController.navigationBar setBarStyle:UIBarStyleBlackOpaque];
    //[self.navigationController.navigationBar setTranslucent:NO];

}

-(void)viewDidAppear:(BOOL)animated
{
    if(trimY_ == -1.0f){
        // 最初の一度だけ 実行すれば良い箇所
        trimY_ = tableView_.frame.origin.y;
        [self.view bringSubviewToFront:tableView_];
        //LOG(@"----------- trimY_=%f tableView_.frame=%@",trimY_, NSStringFromCGRect(tableView_.frame));
        //return;
    }
    [self trimTableView];
    LOG(@"self.navigationController.navigationBar.frame=%@", NSStringFromCGRect(self.navigationController.navigationBar.frame));
    LOG(@"trimY_=%f self.view.frame=%@",trimY_, NSStringFromCGRect(self.view.frame));
    //[tableView_ setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
    [tableView_ reloadData];

    //[self.view bringSubviewToFront:bannerViewFrame_];
    [self layoutAnimated:NO];
    [self.view bringSubviewToFront:_bannerView];

}

-(void)trimTableView
{
    //LOG(@"timeEnable_=%@",timeEnable_ ? @"YES" : @"NO");
    CGFloat x = tableView_.frame.origin.x;
    CGFloat y = tableView_.frame.origin.y;
    CGFloat width = tableView_.frame.size.width;
    CGFloat height = tableView_.frame.size.height;
    //LOG(@"trimY_=%f tableView_.frame=%@", trimY_, NSStringFromCGRect(tableView_.frame));

    if(timeEnable_){
        if(y==0){
            [UIView animateWithDuration:0.5 animations:^(void){
                tableView_.frame = CGRectMake(x, trimY_, width, height-trimY_);
                //LOG(@"- trimY_=%f tableView_.frame=%@", trimY_, NSStringFromCGRect(tableView_.frame));
            }];
            //[self.view layoutSubviews];
            return;
        }
        //LOG(@"-- trimY_=%f tableView_.frame=%@", trimY_, NSStringFromCGRect(tableView_.frame));
        return;
    }
    if(y==trimY_){
        [UIView animateWithDuration:0.5 animations:^(void){
            tableView_.frame = CGRectMake(x, 0, width, height+trimY_);
            //LOG(@"--- trimY_=%f tableView_.frame=%@", trimY_, NSStringFromCGRect(tableView_.frame));
        }];
        //[self.view layoutSubviews];
    }
    //LOG(@"---- trimY_=%f tableView_.frame=%@", trimY_, NSStringFromCGRect(tableView_.frame));

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

#pragma mark - IBAction receiver methods

-(IBAction)regionChanged:(id)sender
{
    NSNotification *notification = (NSNotification*)sender;
    CountrySetting *countrySetting = (CountrySetting*)notification.object;
    region_ = countrySetting.countryCode;
    self.navigationItem.rightBarButtonItem = [self getRightBarButtonItem];//.image = [MainViewController imageResizer30x30:[UIImage imageNamed:region_]];
    [self refreshOccured:sender];
    //self.navigationItem.rightBarButtonItem.image = [UIImage imageNamed:region_];
    //LOG(@"sender=%@ region_=%@", sender, region_);
}

-(IBAction)gDataURLChanged:(id)sender
{
    //LOG(@"%@#gDataURLChanged sender=%@", [self class], sender);
    if(nowLoadding_)
        return;

    self.searchMode = NO;

    NSNotification *notification = (NSNotification*)sender;
    youTubeGdataURL_ = (YouTubeGdataURL*)notification.object;
    gdataUrlFormat_ = youTubeGdataURL_.url;
    self.navigationItem.title = youTubeGdataURL_.title;

    //LOG(@"%@#gDataURLChanged youTubeGdataURL.timeEnable=%d", [self class], youTubeGdataURL_.timeEnable);
    switch (youTubeGdataURL_.timeEnable) {
        case 1:
            timeEnable_ = YES;
            break;

        default:
            timeEnable_ = NO;
            break;
    }

    [self trimTableView];

    [refreshControl_ beginRefreshing];

    self.resetVideoArray = YES;
    startIndex_ = 1;
    //videos = nil;
    allDataLoadding_ = NO;
    [self gdataLoad];

}

-(IBAction)segmentedControlActionReceiver:(id)sender
{
    UISegmentedControl *seg = (UISegmentedControl*)sender;
    //LOG(@"%@#segmentedControlActionReceiver seg.selectedSegmentIndex=%d", [self class], seg.selectedSegmentIndex);
    time_ = [timeParamsArray_ objectAtIndex:seg.selectedSegmentIndex];

    //[seg setSelectedSegmentIndex:seg.selectedSegmentIndex];
    //[[[seg subviews]objectAtIndex:seg.selectedSegmentIndex] setTintColor:[UIColor darkGrayColor]];

    if(nowLoadding_)
        return;

    [refreshControl_ beginRefreshing];

    startIndex_ = 1;
    //videos = nil;
    allDataLoadding_ = NO;
    [self gdataLoad];

}

-(IBAction)leftNavBarButtonTouched:(id)sender
{
    //[[self slidingViewController] anchorTopViewTo:ADAnchorSideRight];

    //LOG(@"%@#leftNavBarButtonTouched sender=%@", [self class], sender);
    if (self.navigationController.revealController.focusedController == self.navigationController.revealController.leftViewController)
    {
        [self.navigationController.revealController showViewController:self.navigationController.revealController.frontViewController];
    }
    else
    {
        [self.navigationController.revealController showViewController:self.navigationController.revealController.leftViewController];
    }

}

-(IBAction)rightNavBarButtonTouched:(id)sender
{
    //[[self slidingViewController] anchorTopViewTo:ADAnchorSideLeft];
    //LOG(@"%@#rightNavBarButtonTouched sender=%@", [self class], sender);
    if (self.navigationController.revealController.focusedController == self.navigationController.revealController.rightViewController)
    {
        [self.navigationController.revealController showViewController:self.navigationController.revealController.frontViewController];
    }
    else
    {
        [self.navigationController.revealController showViewController:self.navigationController.revealController.rightViewController];
    }
}

#pragma mark - refreshOccured

- (void)refreshOccured:(id)sender {
    //LOG(@"%@#refreshOccured sender=%@", [self class], sender);
    if(nowLoadding_)
        return;

    if(self.searchMode && !searchWords_){
        [refreshControl_ endRefreshing];
        return;
    }

    startIndex_ = 1;
    //videos = nil;
    allDataLoadding_ = NO;
    self.resetVideoArray = YES;
    [self gdataLoad];
}

#pragma mark - Download from gdata methods

-(void)gdataLoad
{

    NSString *urlStr; // = [NSString stringWithFormat:gdataUrlFormat_, region_, startIndex_, maxResults_, time_];
    if(self.searchMode){
        urlStr = [NSString stringWithFormat:gdataUrlFormat_, searchWords_, startIndex_, maxResults_];
    }else{
        if(timeEnable_){
            urlStr = [NSString stringWithFormat:gdataUrlFormat_, region_, startIndex_, maxResults_, time_];
        }else{
            urlStr = [NSString stringWithFormat:gdataUrlFormat_, region_, startIndex_, maxResults_];
        }
    }

    LOG(@"urlStr=%@", urlStr);

    @synchronized(self)
    {

        nowLoadding_ = YES;

        [JSONHTTPClient getJSONFromURLWithString: urlStr
                                      completion:^(NSDictionary *json, JSONModelError *err) {

                                          @synchronized(self)
                                          {
                                              nowLoadding_ = NO;
                                          }

                                          if (err) {
                                              if(refreshControl_.refreshing){
                                                  [refreshControl_ endRefreshing];
                                              }
                                              [[[UIAlertView alloc] initWithTitle:@"Error"
                                                                          message:[err localizedDescription]
                                                                         delegate:nil
                                                                cancelButtonTitle:@"Close"
                                                                otherButtonTitles: nil] show];
                                              return;
                                          }

                                          if(refreshControl_.refreshing){
                                              videos = nil;
                                              [refreshControl_ endRefreshing];
                                          }

                                          //LOG(@"json=%@",json);

                                          //initialize the models
                                          NSArray *array = [VideoModel arrayOfModelsFromDictionaries:
                                                            json[@"feed"][@"entry"]
                                                            ];
                                          // LOG(@"%@#gdataLoad json=%@", [self class], json);

                                          if(array && [array count]>0){
                                              if(!videos || self.resetVideoArray){
                                                  videos = array;
                                                  self.resetVideoArray = NO;
                                              }else{
                                                  videos = [videos arrayByAddingObjectsFromArray:array];
                                              }

                                              [tableView_ reloadData];
                                          }else{
                                              allDataLoadding_ = YES;
                                              [tableView_ reloadData];
                                          }

                                      }];
    }
}

#pragma mark - tableview delegate methods

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    if(videos){
        if(allDataLoadding_){
            return [videos count];
        }else{
            return [videos count]+1;
        }
    }

    return 1;
    //[countrySettingList_ count];//[activityTypeArray_ count];
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 100.0;
}

- (UITableViewCell *)loadingCell {

    QTubeLoadingCell *cell = [QTubeLoadingCell getQTubeLoadingCell];
    cell.tag = kLoadingCellTag;
    return cell;
}

- (UITableViewCell *)loadingCell2 {

    QTubeLoadingCell *cell = [QTubeLoadingCell getQTubeLoadingCell];
    cell.tag = kLoadingCellTag;
    return cell;
}

-(UIImage*)imageFromLocal:(NSString*)videoId
{
    if(!videoId)
        return nil;

    NSArray *filePaths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES);
    NSString *recordingDirectory = [filePaths objectAtIndex: 0];
    // Pick a file name
    NSString *filePath = [NSString stringWithFormat: @"%@/%@.jpg", recordingDirectory, videoId];
    NSData *data = nil;

    NSFileManager *manager = [NSFileManager defaultManager];
    if([manager fileExistsAtPath:filePath]){
        //LOG(@"%@#loadPhotoFromURL read file filePath=%@", [self class], filePath);
        NSFileHandle *fhandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
        if(!fhandle){
            return nil;
        }else{
            //LOG(@"%@#loadPhotoFromURL read file ----- filePath=%@", [self class], filePath);
            data = [fhandle readDataToEndOfFile];
            //LOG(@"%@#loadPhotoFromURL read file ----- videoId=%@, [data length]=%d", [self class], videoId, [data length]);

            if(data){
                UIImage *image = [UIImage imageWithData:data];
                return image;
            }
            return nil;
        }
    }
    return nil;

}

+(void)cellDownloadStatusSetting:(QTubeCell*)qTubeCell VideoId:(NSString*)videoId
{
    dispatch_queue_t q_global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t q_main = dispatch_get_main_queue();

    //qTubeCell.downloadButton.hidden = NO;
    dispatch_async(q_global, ^{
        QTubeVideo *qvideo = [VideoDownloadManager getQTubeVideoByVideoId:videoId];

        if(qvideo) {
            NSString *message = nil;
            BOOL isDisplayDownloadButton = YES;
            switch (qvideo.stateValue) {
                case QTubeVideoStatusDownloadSuccess:
                    isDisplayDownloadButton = NO;
                    double size = (double)qvideo.sizeValue;
                    size = size / 1000000.0f;
                    message = [NSString stringWithFormat:@"%4.1fMB", size];//@"Cached";
                    break;
                case QTubeVideoStatusDownloadNow:
                    isDisplayDownloadButton = NO;
                    message = @"";
                    break;
                case QTubeVideoStatusDownloadQueue:
                    isDisplayDownloadButton = NO;
                    message = @"Waiting";
                    break;
                case QTubeVideoStatusDownloadFailure:
                    isDisplayDownloadButton = YES;
                    message = @"Failure";
                    break;
                case QTubeVideoStatusDownloadSuspend:
                    isDisplayDownloadButton = YES;
                    message = @"Suspend";
                    break;
                case QTubeVideoStatusFileDeleted:
                    isDisplayDownloadButton = YES;
                    message = @"Viewing end";
                    break;

                default:
                    break;
            }
            dispatch_async(q_main, ^{
                qTubeCell.downloadButton.hidden = !isDisplayDownloadButton;
                if(message){
                    qTubeCell.downloadStatusLabel.hidden = NO;
                    qTubeCell.downloadStatusLabel.text = message;
                }
            });
        }
    });

}

+(void)cellDownloadStatusSetting:(QTubeCell*)qTubeCell QTubeVideo:(QTubeVideo*)qvideo
{
    dispatch_queue_t q_global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t q_main = dispatch_get_main_queue();

    //qTubeCell.downloadButton.hidden = NO;
    dispatch_async(q_global, ^{
        //QTubeVideo *qvideo = [VideoDownloadManager getQTubeVideoByVideoId:videoId];

        if(qvideo) {
            NSString *message = nil;
            BOOL isDisplayDownloadButton = YES;
            switch (qvideo.stateValue) {
                case QTubeVideoStatusDownloadSuccess:
                    isDisplayDownloadButton = NO;
                    double size = (double)qvideo.sizeValue;
                    size = size / 1000000.0f;
                    message = [NSString stringWithFormat:@"%4.1fMB", size];//@"Cached";
                    break;
                case QTubeVideoStatusDownloadNow:
                    isDisplayDownloadButton = NO;
                    message = @"";
                    break;
                case QTubeVideoStatusDownloadQueue:
                    isDisplayDownloadButton = NO;
                    message = @"Waiting";
                    break;
                case QTubeVideoStatusDownloadFailure:
                    isDisplayDownloadButton = YES;
                    message = @"Failure";
                    break;
                case QTubeVideoStatusDownloadSuspend:
                    isDisplayDownloadButton = YES;
                    message = @"Suspend";
                    break;
                case QTubeVideoStatusFileDeleted:
                    isDisplayDownloadButton = YES;
                    message = @"Viewing end";
                    break;

                default:
                    break;
            }
            dispatch_async(q_main, ^{
                qTubeCell.downloadButton.hidden = !isDisplayDownloadButton;
                if(message){
                    qTubeCell.downloadStatusLabel.hidden = NO;
                    qTubeCell.downloadStatusLabel.text = message;
                }
                [qTubeCell setNeedsDisplay];
                [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.05]];
            });
        }
    });

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(!videos){
        return [self loadingCell2];
    }
    if (indexPath.row < videos.count) {                  QTubeCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ACell"];         if(!cell){             cell = [QTubeCell getQTubeCellWithVideoModel:(VideoModel*)videos[indexPath.row]];         }                  VideoModel* video = videos[indexPath.row];         MediaThumbnail* thumb = video.thumbnail[0];         cell.videoModel = video;                  cell.titleLabel.text = video.title;         cell.autherNameLabel.text = video.authorName;         cell.playCountLabel.text = [AppDelegate createStringAddedCommaFromInt:];         cell.ratingAverageLabel.text = [NSString stringWithFormat:@"%.0f%%", *20.0f];         //LOG(@"%@#cellForRowAtIndexPath video.videoId=%@ thumb.url=%@",[self class], video.videoId, thumb.url);                  NSDateFormatter *df = [[NSDateFormatter alloc] init];         [df setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"US"]]; // Localeの指定         [df setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];         if(video.duration >= 3600) [df setDateFormat:@"HH:mm:ss"];
        else [df setDateFormat:@"m:ss"];

        //LOG(@"video.duration=%d", video.duration);
        NSDate *now = [NSDate dateWithTimeIntervalSince1970:(NSTimeInterval)video.duration];
        NSString *strNow = [df stringFromDate:now];
        cell.dulationLabel.text = strNow;

        [MainViewController cellDownloadStatusSetting:cell VideoId:];

        UIImage *image = [self imageFromLocal:video.videoId];
        if(image)
            cell.imageView.image = image;
        else{
            //cell.imageView.image = [UIImage imageNamed:@"Icon.png"];
            // add a loading spinner
            cell.spinner = [[UIActivityIndicatorView alloc]
                            initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
            cell.spinner.center = CGPointMake(cell.frame.size.width / 4, cell.frame.size.height / 2);
            cell.spinner.autoresizingMask = UIViewAutoresizingFlexibleTopMargin
            | UIViewAutoresizingFlexibleRightMargin
            | UIViewAutoresizingFlexibleBottomMargin
            | UIViewAutoresizingFlexibleLeftMargin;
            cell.spinner.color = UIColor.lightGrayColor;

            [cell addSubview:cell.spinner];
            [cell.spinner startAnimating];
        }
        if(!image){
            dispatch_queue_t q_global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
            dispatch_queue_t q_main = dispatch_get_main_queue();

            dispatch_async(q_global, ^{
                //LOG(@"%@#cellForRowAtIndexPath dispatch_async q_global video.videoId=%@ thumb.url=%@",[self class], video.videoId, thumb.url);
                NSData *data = [NSData dataWithContentsOfURL:thumb.url];
                UIImage *image = [UIImage imageWithData:data];

                dispatch_async(q_main, ^{
                    if(cell.spinner){
                        [cell.spinner stopAnimating];
                        [cell.spinner removeFromSuperview];
                    }
                    if(image){
                        if ([tableView_.visibleCells containsObject:cell]) {
                            //LOG(@"%@#cellForRowAtIndexPath dispatch_async q_main video.videoId=%@ thumb.url=%@",[self class], video.videoId, thumb.url);
                            [cell.imageView setImage:image];
                            [cell bringSubviewToFront:cell.imageView];
                            [cell bringSubviewToFront:cell.dulationLabel];
                            //[cell layoutSubviews];
                        }
                        //cell.imageView.image = image;
                    }
                });

                if(video.videoId){
                    NSArray *filePaths = NSSearchPathForDirectoriesInDomains (NSCachesDirectory, NSUserDomainMask, YES);
                    NSString *recordingDirectory = [filePaths objectAtIndex: 0];
                    // Pick a file name
                    NSString *filePath = [NSString stringWithFormat: @"%@/%@.jpg", recordingDirectory, video.videoId];

                    NSFileHandle *fileHandle_ = [NSFileHandle fileHandleForWritingAtPath:filePath];
                    if(!fileHandle_)
                    {
                        [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
                        fileHandle_ = [NSFileHandle fileHandleForWritingAtPath:filePath];
                    }
                    // 既存のファイルがあったら サイズをゼロにする
                    [fileHandle_ truncateFileAtOffset:0];

                    [fileHandle_ writeData:data];

                    [fileHandle_ synchronizeFile];
                    [fileHandle_ closeFile];
                }

            });
        }

        //cell.indentationWidth = 0.0f;
        //LOG(@"cell.indentationWidth=%f", cell.indentationWidth);
        //LOG(@"cell.indentationLevel=%d", cell.indentationLevel);
        //cell.separatorInset = UIEdgeInsetsZero;
        return cell;

    }else{
        return [self loadingCell];
    }

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(videos){
        VideoModel *video = [videos objectAtIndex:indexPath.row];

        //[self performSegueWithIdentifier:@"videoViewSegue" sender:video];

        AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
        WebVideoViewController *webVideoViewController = nil;
        if(appDelegate.isRetina4){
            webVideoViewController = [[WebVideoViewController alloc]initWithNibName:@"WebVideoViewController" bundle:[NSBundle mainBundle]];
        }else{
            webVideoViewController = [[WebVideoViewController alloc]initWithNibName:@"WebVideoViewController_retina3" bundle:[NSBundle mainBundle]];
        }
        webVideoViewController.video = video;
        [self.navigationController pushViewController:webVideoViewController animated:YES];
    }
}

-(NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 0;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    // LOG(@"cell.frame=%@",NSStringFromCGRect(cell.frame));
    // LOG(@"cell.contentView.frame=%@",NSStringFromCGRect(cell.contentView.frame));
    // LOG(@"cell.imageView.frame=%@",NSStringFromCGRect(cell.imageView.frame));

    if (cell.tag == kLoadingCellTag) {
        if(nowLoadding_)
            return;

        startIndex_+= maxResults_;
        [self gdataLoad];
    }
}

#pragma mark - storyboard prepareForSegue

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    WebVideoViewController* controller = segue.destinationViewController;
    controller.video = sender;
}

#pragma mark - iAd methods

- (void)layoutAnimated:(BOOL)animated
{
    // As of iOS 6.0, the banner will automatically resize itself based on its width.
    // To support iOS 5.0 however, we continue to set the currentContentSizeIdentifier appropriately.
}

- (void)viewDidLayoutSubviews
{
    [self layoutAnimated:[UIView areAnimationsEnabled]];
}

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    [self layoutAnimated:YES];
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    [self layoutAnimated:YES];
}

- (void)bannerViewActionDidFinish:(ADBannerView *)banner
{
}

@end

関連記事

FileQ iOS版 公開しました。

5/2にFileQ iOS版を無事、公開しました。Appleの審査もスンナリ通り ホットしています(

記事を読む

iOSプログラミングのキモ(複雑な画面を複数のViewControllerで制御する その2)

先週は、複数のViewControllerで1つの画面を構成する話のうち、親ViewControll

記事を読む

iOSプログラミングのキモ

このブログでは、実際に弊社が公開しているアプリのソースコードを使って、iOSプログラミングのキモを解

記事を読む

iPhoneが7GBの転送制限に引っかかりそうになって Nexus7(2013)LTE版のテザリング機能が大活躍

皆さんは スマホを使ってて、転送制限に引っかかったことはありますか?私はあります(笑) 最

記事を読む

iOSプログラミングのキモ(行き当たりばったりなプログラミングでも、何とか形にするために守っていること その1)

FileQ iOS版がリリースされて、のんびりしたい気持ちもありますが、FileQ Android版

記事を読む

iOSプログラミングのキモ(デバッグをやりやすくするための工夫:Debug.hのインクルード )

前回 紹介した Debug.h は、使う際 以下のようにソースファイル(ここでは拡張子が m のもの

記事を読む

iOSプログラミングのキモ(AppDelegate説明 NSUserDefaultsに設定情報を格納する )

QTubeは、YouTubeを閲覧するときに 国別コードを設定しています。国別コードは iOSに設定

記事を読む

iOSプログラミングのキモ(MainViewController説明 : dispatch_asyncとブロック構文を使った 今どきのお手軽マルチスレッドプログラミング)

TwitterやYouTubeといったサービスでは、コンテンツの見出しにサムネイルが付加されることが

記事を読む

iOSプログラミングのキモ(複雑な画面を複数のViewControllerで制御する その1)

久々に、プログラミングの話です(^^; 今日は 機能が複雑な画面を 複数のViewContro

記事を読む

iOSプログラミングのキモ(Delegate iOSプログラミングで避けて通れないしくみ)

Delegate(委任)の考え方を説明します。iOSのプログラミングでは このDelegateが頻繁

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

FileQ Hosting 月額99円 容量1GB


サイト管理 Mezzanine
Django上で動くCMS Mezzanine 用のモジュールを作ってみる その1

Django上で動くCMS Mezzanine上で動く、モジュールを作

ホーム Mezzanine
Django上で動くCMS Mezzanine を インストールする MacOSX Yesemite 編

Mezzanineは Django WEBフレームワーク上で動くCMS

EclipseにGWT(Google Web Toolkit) Plugin for Eclipseを入れようとしてハマった

最近PHPでちょっとした業務システムを作りました。業務システムの特徴と

ブログを半年やった成果を Google Analytics から眺める

今年の1月からブログを書き始め、そろそろ半年が経とうとしています。

母校で特別 講義をやってきました。

少し 間が空いてしまいました(^_^;) ちょっと前になりますが

→もっと見る

mautic is open source marketing automation
PAGE TOP ↑