*

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

公開日: : iOS, iPhone, XCode

久々に、プログラミングの話です(^^;

今日は 機能が複雑な画面を 複数のViewControllerで制御する方法です。

QTubeの動画閲覧画面のスクリーンショット3つです。

IMG_1353

IMG_1352

IMG_1351

動画を再生しつつ、「情報」「投稿者の動画」「関連動画」という3つのタブを切り替えることで 1つの画面にまとめています。

基本的にiOSプログラミングでは 1つの画面に1つのViewControllerクラスを用意して、その中にイベント処理(ボタンが押された等)に対応するメソッドを書いていく手法を取ります。しかし機能が増えていくと ViewControllerがとても複雑になってしまい、メンテナンス性が落ちます。

さらに、UITableView を使う場合、delegate を使うため制御メソッドが決まっています。複数の UITableView を 制御することも出来なくはないですが
実装が複雑になり、やはりオススメ出来ません。

こういった場合、複数のViewControllerを作成し 機能を分散することで 実装を簡単にしていくことが出来るようになります。

上記のスクリーンショットは 以下の様な 4つのViewControllerで出来ています。

1,WebVideoViewController (親 ViewController)
2,InfoViewController (「情報」画面担当)
3,OtherVideosOfAuthorViewController (「投稿者の動画」画面担当)
4,RelatedVideosViewController (「関連動画」画面担当)

2−4の画面の切り替えには SDSegmentedControl を使っています。

1つのエントリーで 4つのViewControllerを説明するのは大変なので 複数回に分けて ソースを交え 説明していこうと思います。

WebVideoViewController.h

#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#import "VideoModel.h"
#import "LBYouTubePlayerViewController.h"

@class VideoDownloader;

@interface WebVideoViewController : UIViewController <ADBannerViewDelegate>
{
}

@property (nonatomic, retain) VideoModel* video;
@property (weak, nonatomic) IBOutlet UIView* segmentedView;
@property (weak, nonatomic) IBOutlet UIBarButtonItem* downloadButton;
@property (nonatomic,retain) IBOutlet UIProgressView *downloadProgressView;

-(IBAction)segmentedControlValueChanged:(id)sender;
-(IBAction)newVideoIdSelected:(id)sender;
-(void)displayUIActivityView;
@end

WebVideoViewController.m

#import "WebVideoViewController.h"
#import "LBYouTube.h"
#import "Debug.h"
#import <MediaPlayer/MediaPlayer.h>

#import "VideoDownloader.h"
#import "YoutubeGetVideoInfo.h"

#import "InfoViewController.h"
#import "OtherVideosOfAuthorViewController.h"
#import "RelatedVideosViewController.h"
#import "VideoModel.h"
#import "VideoDownloadManager.h"
#import "VideoDownloader.h"
#import "QTubeVideo.h"
#import "MainViewController.h"
#import "LINEActivity.h"
#import "Util.h"
#import "MainViewController.h"

@interface WebVideoViewController ()
{
    MPMoviePlayerController *moviePlayerController_;
    LBYouTubePlayerViewController *lbYoutubePlayerVC_;
    
    IBOutlet UIView* movieView_;
    
    InfoViewController *infoViewController_;
    OtherVideosOfAuthorViewController *otherVideosOfAuthorViewController_;
    RelatedVideosViewController *relatedVideosViewController_;
    
    IBOutlet SDSegmentedControl *sDSegmentedControl_;
    
    BOOL sDSegmentedControlNormalPosition_;
    CGFloat sDSegmentedControl_frame_origin_NormalPosition_y;
    CGFloat sDSegmentedControl_frame_origin_UpPosition_y;
    CGFloat trimY_;
    
    BOOL isPlaybackFinished_;
    BOOL newVideoIdSelected_;
    
    IBOutlet UIView *bannerViewFrame_;
    IBOutlet ADBannerView *_bannerView;
    
    IBOutlet UILabel *videoMessageLabel_;
}

@end

@implementation WebVideoViewController

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

-(void)localize
{
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"InfoString", nil) forSegmentAtIndex:0];
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"OtherVideosString", nil) forSegmentAtIndex:1];
    [sDSegmentedControl_ setTitle:NSLocalizedString(@"RelatedVideosString", nil) forSegmentAtIndex:2];
    
    [videoMessageLabel_ setText:NSLocalizedString(@"VideoPlaybackInPreparationString", nil)];
}

-(void)viewDidLoad
{
    LOG(@"webVideoViewController.video.videoId=%@ webVideoViewController.video=%@", self.video.videoId, self.video);
    
    // 子供ViewControllerをインスタンス化する
    infoViewController_ = [[InfoViewController alloc]initWithNibName:@"InfoViewController" bundle:[NSBundle mainBundle]];
    otherVideosOfAuthorViewController_ = [[OtherVideosOfAuthorViewController alloc]initWithNibName:@"OtherVideosOfAuthorViewController" bundle:[NSBundle mainBundle]];
    relatedVideosViewController_ = [[RelatedVideosViewController alloc]initWithNibName:@"RelatedVideosViewController" bundle:[NSBundle mainBundle]];
    
    // YouTubeビデオ情報を 子供ViewController にセット
    infoViewController_.video = self.video;
    otherVideosOfAuthorViewController_.video = self.video;
    relatedVideosViewController_.video = self.video;
    
    // 子供ViewController に 自分をセット
    infoViewController_.webVideoViewController = self;
    otherVideosOfAuthorViewController_.webVideoViewController = self;
    relatedVideosViewController_.webVideoViewController = self;
    
    // segmentedView に 子供ViewController のViewを登録
    [self.segmentedView addSubview:infoViewController_.view];
    [self.segmentedView addSubview:otherVideosOfAuthorViewController_.view];
    [self.segmentedView addSubview:relatedVideosViewController_.view];
    
    // 画面のサイズを調整してセットする
    infoViewController_.view.frame = self.segmentedView.bounds;
    otherVideosOfAuthorViewController_.view.frame = self.segmentedView.bounds;
    relatedVideosViewController_.view.frame = self.segmentedView.bounds;
    
    [self.segmentedView bringSubviewToFront:infoViewController_.view];
    
    
    sDSegmentedControlNormalPosition_ = YES;
    isPlaybackFinished_ = NO;
    newVideoIdSelected_ = NO;
        
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(startQtubeVideoPlayNotificationReceiver:) name:START_QTUBE_VIDEO_PLAY_NOTIFICATON object:nil];
    
    _bannerView.delegate = self;
    
    [self localize];
 
    [self layoutAnimated:NO];
    [self.view bringSubviewToFront:_bannerView];

    NSString* videoId = [self.video videoId];
    LOG(@"videoId=%@ self.video=%@", videoId, self.video);

}


-(void)viewWillAppear:(BOOL)animated
{    
    LOG(@"newVideoIdSelected_=%@", newVideoIdSelected_?@"YES":@"NO");
    if(!moviePlayerController_ || newVideoIdSelected_){
        NSString *notificationKeyString = [sDSegmentedControl_ getUpDownSwipeGestureNotificationKeyString];
        LOG(@"%@", notificationKeyString);
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(sdSegmentedControlSwipeGestureReceiver:) name:notificationKeyString object:nil];
        
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(startVideoDownload:) name:VIDEO_DOWNLOAD_START object:nil];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(progressVideoDownload:) name:VIDEO_DOWNLOAD_PROGRESS object:nil];
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(endVideoDownload:) name:VIDEO_DOWNLOAD_END object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willExitFullscreen:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(enteredFullscreen:) name:MPMoviePlayerDidEnterFullscreenNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayerPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
        
        //newVideoIdSelected_ = NO;
    }

    [infoViewController_ viewWillAppear:animated];
    [otherVideosOfAuthorViewController_ viewWillAppear:animated];
    [relatedVideosViewController_ viewWillAppear:animated];
        
    LOG(@"self.view.frame=%@",NSStringFromCGRect(self.view.frame));
    LOG(@"movieView_.frame=%@",NSStringFromCGRect(movieView_.frame));
    LOG(@"sDSegmentedControl_.frame=%@",NSStringFromCGRect(sDSegmentedControl_.frame));
    LOG(@"self.segmentedView.frame=%@",NSStringFromCGRect(self.segmentedView.frame));
    LOG(@"self.segmentedView.bounds=%@",NSStringFromCGRect(self.segmentedView.bounds));
}

-(void)viewDidAppear:(BOOL)animated
{
    [[NSNotificationCenter defaultCenter]postNotificationName:START_VIDEO_PLAY_NOTIFICATON object:self];

    if(moviePlayerController_){
        if(newVideoIdSelected_){
            [moviePlayerController_.view removeFromSuperview];
            moviePlayerController_ = nil;
            [self _viewDidAppear:animated];
            newVideoIdSelected_ = NO;
        }
        return;
    }
    
    [self _viewDidAppear:animated];
    
    [self layoutAnimated:NO];
    [self.view bringSubviewToFront:_bannerView];

}

-(void)_viewDidAppear:(BOOL)animated
{
    NSString* videoId = [self.video videoId];
    LOG(@"videoId=%@ self.video=%@", videoId, self.video);
    if (!videoId) {
        [[[UIAlertView alloc] initWithTitle:@"Error" message:@"Video ID not found in video URL" delegate:nil cancelButtonTitle:@"Close" otherButtonTitles: nil]show];
        return;
    }
    
    dispatch_queue_t q_global = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t q_main = dispatch_get_main_queue();
    
    // Get YouTube movie data URL and play start in background.
    dispatch_async(q_global, ^{
        NSURL *url = nil; //[YoutubeGetVideoInfo urldecodedVideoInfo:videoId Quarity:LBYouTubeVideoQualityLarge];
        url = [YoutubeGetVideoInfo urldecodedVideoInfo:videoId Quarity:LBYouTubeVideoQualityLarge];
        
        //LOG(@"--- Embed video id: %@  Stream URL = %@", videoId, [url absoluteString]);
        dispatch_async(q_main, ^{
            if(url){
                [self moviePlay:url];
            }
        });
    });
    
    // If not download this movie, Set download butotn at self.navigationItem.rightBarButtonItem
    dispatch_async(q_global, ^{
        QTubeVideo *qvideo = [VideoDownloadManager getQTubeVideoByVideoId:videoId];
        if(!qvideo) {
            dispatch_async(q_main, ^{
                //UIImage *image = [MainViewController imageResizer30x30:[UIImage imageNamed:@"QTubeIcon40x40"]];
                UIBarButtonItem * btn1 = [ [ UIBarButtonItem alloc ] initWithImage:[UIImage imageNamed:@"plus_alt_white"] style:UIBarButtonItemStyleBordered target:self action:@selector(downloadButtonPushed:)];
                self.navigationItem.rightBarButtonItem = btn1;
            });
        }
        
    });
    
    
    [infoViewController_ viewDidAppear:animated];
    [otherVideosOfAuthorViewController_ viewDidAppear:animated];
    [relatedVideosViewController_ viewDidAppear:animated];
    
    if(sDSegmentedControlNormalPosition_){
        sDSegmentedControl_frame_origin_NormalPosition_y = sDSegmentedControl_.frame.origin.y;
        sDSegmentedControl_frame_origin_UpPosition_y = sDSegmentedControl_frame_origin_NormalPosition_y / 2.0;
        
        trimY_ = sDSegmentedControl_frame_origin_NormalPosition_y - sDSegmentedControl_frame_origin_UpPosition_y;
    }
}

-(void)viewWillDisappear:(BOOL)animated
{
    LOG(@"newVideoIdSelected_=%@", newVideoIdSelected_?@"YES":@"NO");
    if(newVideoIdSelected_)
        [[NSNotificationCenter defaultCenter]removeObserver:self];
}

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

- (BOOL)shouldAutorotate
{
    return NO;
}

- (NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;
}

#pragma mark - Download button pushed method

-(IBAction)downloadButtonPushed:(id)sender
{
    if(self.video){
        LOG(@"video.title = %@",self.video.title);
        
        AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
        [appDelegate.videoDownloadManager queue:self.video];
        
        self.navigationItem.rightBarButtonItem = nil;
        
    }else{
        LOG(@"called");
    }
    
}


#pragma mark - MPMoviePlayerController methods

-(void)moviePlay:(NSURL *)videoURL
{
    LOG(@"%@#moviePlay videoURL#absoluteString = %@", [self class], [videoURL absoluteString]);
    
    if(!moviePlayerController_){
        moviePlayerController_ = [[MPMoviePlayerController alloc]initWithContentURL:videoURL];
        //moviePlayerController.controlStyle = MPMovieControlStyleNone;
        [moviePlayerController_.view setFrame:movieView_.bounds];
        [movieView_ addSubview:moviePlayerController_.view];
    }else{
        [moviePlayerController_ setContentURL:videoURL];
    }
    [moviePlayerController_ prepareToPlay];
    [moviePlayerController_ play];
    isPlaybackFinished_ = NO;
}

- (void)willEnterFullscreen:(NSNotification*)notification {
    LOG(@"willEnterFullscreen");
}

- (void)enteredFullscreen:(NSNotification*)notification {
}

- (void)willExitFullscreen:(NSNotification*)notification {
}

- (void)exitedFullscreen:(NSNotification*)notification {
    LOG(@"moviePlayerController_.playbackState = %d", moviePlayerController_.playbackState);
    if (moviePlayerController_.playbackState == MPMoviePlaybackStatePaused && !isPlaybackFinished_) {
        [moviePlayerController_ play];
    }
}

- (void) moviePlayerPlaybackStateDidChange: (NSNotification *) notification {
    LOG(@"moviePlayerController_.playbackState = %d", moviePlayerController_.playbackState);
}

- (void)playbackFinished:(NSNotification*)notification {
    NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
    switch ([reason intValue]) {
        case MPMovieFinishReasonPlaybackEnded:
            LOG(@"playbackFinished. Reason: Playback Ended");
            break;
        case MPMovieFinishReasonPlaybackError:
            LOG(@"playbackFinished. Reason: Playback Error");
            break;
        case MPMovieFinishReasonUserExited:
            LOG(@"playbackFinished. Reason: User Exited");
            break;
        default:
            break;
    }
    isPlaybackFinished_ = YES;
    [moviePlayerController_ setFullscreen:NO animated:YES];
    
    [AppDelegate iRateDisplay];
}

#pragma mark - SDSegmentedControl methods

-(IBAction)segmentedControlValueChanged:(id)sender
{
    SDSegmentedControl *segmentedControl = (SDSegmentedControl*)sender;
    LOG(@"segmentedControl.selectedSegmentIndex=%d",segmentedControl.selectedSegmentIndex);
    
    switch (segmentedControl.selectedSegmentIndex) {
        case 0:
            [self.segmentedView bringSubviewToFront:infoViewController_.view];
            break;
        case 1:
            [self.segmentedView bringSubviewToFront:otherVideosOfAuthorViewController_.view];
            break;
        case 2:
            [self.segmentedView bringSubviewToFront:relatedVideosViewController_.view];
            break;
            
        default:
            [self.segmentedView bringSubviewToFront:infoViewController_.view];
            break;
    }
}

-(IBAction)newVideoIdSelected:(id)sender
{
    LOG(@"sender = %@", sender);
    VideoModel *video = nil;
    if([sender isKindOfClass:[NSNotification class]]){
        NSNotification *notification = (NSNotification*)sender;
        video = (VideoModel*)notification.object;
    }else if ([sender isKindOfClass:[VideoModel class]]){
        video = (VideoModel*)sender;
    }else{
        LOG(@"Sender is neither VideoModel nor NSNotification.");
    }
    
    [moviePlayerController_ pause];
    
    newVideoIdSelected_ = YES;
    
    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];
    
}

#pragma mark - storyboard prepareForSegue

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

#pragma mark - sdSegmentedControlSwipeGestureReceiver

-(IBAction)sdSegmentedControlSwipeGestureReceiver:(id)sender
{
    NSNotification *notification = sender;
    UISwipeGestureRecognizer *recognizer = notification.object;
    
    NSString *directionString = nil;
    switch ([recognizer direction]) {
        case UISwipeGestureRecognizerDirectionRight:
            directionString = @"UISwipeGestureRecognizerDirectionRight";
            break;
        case UISwipeGestureRecognizerDirectionLeft:
            directionString = @"UISwipeGestureRecognizerDirectionLeft";
            break;
        case UISwipeGestureRecognizerDirectionUp:
            directionString = @"UISwipeGestureRecognizerDirectionUp";
            [self sdSegmentedControlSwipeGestureUP];
            break;
        case UISwipeGestureRecognizerDirectionDown:
            directionString = @"UISwipeGestureRecognizerDirectionDown";
            [self sdSegmentedControlSwipeGestureDown];
            break;
    }
}


-(void)_sdSegmentedControlSwipeGestureUP
{
    CGFloat x = sDSegmentedControl_.frame.origin.x;
    CGFloat width = sDSegmentedControl_.frame.size.width;
    CGFloat height = sDSegmentedControl_.frame.size.height;
    sDSegmentedControl_.frame = CGRectMake(x, sDSegmentedControl_frame_origin_UpPosition_y, width, height);
}

-(void)_sdSegmentedViewSwipeGestureUP
{
    CGFloat x = self.segmentedView.frame.origin.x;
    CGFloat y = self.segmentedView.frame.origin.y;
    CGFloat width = self.segmentedView.frame.size.width;
    CGFloat height = self.segmentedView.frame.size.height;
    
    self.segmentedView.frame = CGRectMake(x, y-trimY_, width, height+trimY_);
    [infoViewController_ setFrame:self.segmentedView.bounds];
    [otherVideosOfAuthorViewController_ setFrame:self.segmentedView.bounds];
    [relatedVideosViewController_ setFrame:self.segmentedView.bounds];
}


-(void)sdSegmentedControlSwipeGestureUP
{
    if(sDSegmentedControlNormalPosition_){
        [UIView animateWithDuration:0.25 animations:^(void){
            [self _sdSegmentedControlSwipeGestureUP];
            [self _sdSegmentedViewSwipeGestureUP];
            LOG(@"sDSegmentedControl_.frame = %@", NSStringFromCGRect(sDSegmentedControl_.frame));
            LOG(@"self.segmentedView.frame = %@", NSStringFromCGRect(self.segmentedView.frame));
            
            sDSegmentedControlNormalPosition_ = NO;
        }];
    }
}

-(void)_sdSegmentedControlSwipeGestureDown
{
    CGFloat x = sDSegmentedControl_.frame.origin.x;
    CGFloat width = sDSegmentedControl_.frame.size.width;
    CGFloat height = sDSegmentedControl_.frame.size.height;
    sDSegmentedControl_.frame = CGRectMake(x, sDSegmentedControl_frame_origin_NormalPosition_y, width, height);
}

-(void)_sdSegmentedViewSwipeGestureDown
{
    CGFloat x = self.segmentedView.frame.origin.x;
    CGFloat y = self.segmentedView.frame.origin.y;
    CGFloat width = self.segmentedView.frame.size.width;
    CGFloat height = self.segmentedView.frame.size.height;
    
    self.segmentedView.frame = CGRectMake(x, y+trimY_, width, height-trimY_);
    [infoViewController_ setFrame:self.segmentedView.bounds];
    [otherVideosOfAuthorViewController_ setFrame:self.segmentedView.bounds];
    [relatedVideosViewController_ setFrame:self.segmentedView.bounds];
}

-(void)sdSegmentedControlSwipeGestureDown
{
    if(!sDSegmentedControlNormalPosition_){
        [UIView animateWithDuration:0.25 animations:^(void){
            [self _sdSegmentedControlSwipeGestureDown];
            [self _sdSegmentedViewSwipeGestureDown];
            sDSegmentedControlNormalPosition_ = YES;
        }];
    }
}

#pragma mark - video download pregress notifications receivers

-(IBAction)startVideoDownload:(id)sender
{
    NSNotification *notification = (NSNotification*)sender;
    VideoDownloader *videoDownloader = (VideoDownloader*)notification.object;
    NSString *videoID = videoDownloader.qTubeVideo.videoID;
    NSString *videoID2 = self.video.videoId;
    if([videoID isEqualToString:videoID2]){
        self.downloadProgressView.hidden = NO;
        [movieView_ bringSubviewToFront:self.downloadProgressView];
        self.downloadProgressView.progress = videoDownloader.loadedbytes/videoDownloader.totalbytes;
    }
}

-(IBAction)progressVideoDownload:(id)sender
{
    NSNotification *notification = (NSNotification*)sender;
    VideoDownloader *videoDownloader = (VideoDownloader*)notification.object;
    NSString *videoID = videoDownloader.qTubeVideo.videoID;
    NSString *videoID2 = self.video.videoId;
    if(!videoID2){
        videoID2 = self.video.videoId;
    }
    if([videoID isEqualToString:videoID2]){
        self.downloadProgressView.hidden = NO;
        [movieView_ bringSubviewToFront:self.downloadProgressView];
        self.downloadProgressView.progress = videoDownloader.loadratio;//edbytes/videoDownloader.totalbytes;
    }
}

-(IBAction)endVideoDownload:(id)sender
{
    self.downloadProgressView.hidden = YES;
}

#pragma mark - startQtubeVideoPlayNotificationReceiver

-(IBAction)startQtubeVideoPlayNotificationReceiver:(id)sender
{
    if(moviePlayerController_){
        [moviePlayerController_ pause];
    }
}

#pragma mark - UIActivityViewController

-(void)displayUIActivityView
{
    
    NSString *urlStr = [NSString stringWithFormat:@"http://www.youtube.com/watch?v=%@",[self.video videoId]];
    NSString *text  = [NSString stringWithFormat:@"%@ %@",[self.video title], urlStr];
    NSArray *activityItems = @;
    NSArray *applicationActivities = @[[[LINEActivity alloc] init]];

    UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems
                                                                               applicationActivities:applicationActivities];
    [self presentViewController:activityView animated:YES completion:nil];
}

#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.
    CGRect contentFrame = self.view.bounds;
    if (contentFrame.size.width < contentFrame.size.height) {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    } else {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
    }
    
    CGRect bannerFrame = _bannerView.frame;
    if (_bannerView.bannerLoaded) {
        contentFrame.size.height -= _bannerView.frame.size.height;
        bannerFrame.origin.y = contentFrame.size.height;
    } else {
        bannerFrame.origin.y = contentFrame.size.height;
    }
}

- (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

キモは ViewDidLoadメソッド内で 子供ViewControllerと結びつける作業を部分です。
オブジェクト指向プログラミング的には 抽象度を上げるべきなのかもしれませんが、今回は1つの画面を複数のViewControllerで制御するという
発想なので、ViewController同士は密な結びつきでも 良いという考えで 実装を進めています。

WebVideoViewController自体のソース量は550行程度で収まっていて まあクラスの全体を見通せるサイズとしては ちょうどいい位かなと感じています。
1つのクラスが1000行を超えてる場合は 別々のクラスに分けることを検討した方がいいでしょう。

子供ViewControllerについては別のエントリで説明していきます。

関連記事

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

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

記事を読む

iOSプログラミングのキモ(2:ソースコード概説 )主要なObjective-Cソース・ファイル一覧

QTubeの主要Objective-Cのソース一覧です。 iOSでは アプリを作る場合 Objec

記事を読む

iOSプログラミングのキモ(デバッグをやりやすくするための工夫:コンソール・ログの出し方 )

iOS上でプログラミングをする時、ログ出力用の関数としてNSLogという関数をよく使います。NSLo

記事を読む

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

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

記事を読む

iOSプログラミングのキモ(iOS7から使えるようになったマルチタスク機能、NSURLSessionはこう使え!)

今日はQTubeのソースに関する話題ではなく、現在開発中のアプリで使っているNSURLSession

記事を読む

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

先週に引き続き、今週も文字中心のエントリーです、今回は 下記3つのことを書いていきます。 M

記事を読む

FileQ iOS版を開発しようと思った理由

私の会社では FileQというファイル転送サービスを 2008年3月末から始めています、かれこれ6年

記事を読む

iOSプログラミングのキモ(MainViewController説明 NSNotification/NSNotificationCenter これ大事)

前回のエントリの続きで 今回はNSNotification/NSNotificationCenter

記事を読む

iOSプログラミングのキモ(サードパーティ製ライブラリをサクッと入れるcocoapods)

iOSプログラミングでは 便利なライブラリがたくさんあります。特にUI系のライブラリは豊富で自分で作

記事を読む

iOSプログラミングのキモ

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

記事を読む

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 ↑