TVme Vodcast iOS Template

TVme, your TV station in an app.

Want an app to broadcast video?  We’ve made it easy with TVme, the app template that makes it easy to launch your own digital TV station!  It’s got a full screen video player, with awesome content rich scrolling video views, search, and custom style slide menu. We’ve even gone ahead and hooked it into Youtube’s API so it’s set up to pull in videos directly from youtube already.  Check out the video of it running below, you’ll be impressed.

Like all our templates, it’s got super high quality design and UX, so you really don’t have to change much of the UI to have an awesome looking Video app front end.  And it has top notch modern, native Objective-C code, with example feeds already plugged in from YouTube. It’s ready and waiting to be turned into your own TV station on the App Store.

What’s included in this download

  • App Template Xcode project written in native Objective-C
  • Original layered Adobe Photoshop .psd files you can edit
  • 25+ Sliced .png files
  • Documentation
myapptemplates TVme Vodcast iOS Template

TVme, your TV station in an app. Want an app to broadcast video?  We’ve made it easy with TVme, the app template that makes it easy to launch your own digital TV station!  It’s got a full screen video player, with awesome content rich scrolling video views, search, and custom style slide menu. We’ve even gone ahead […]

  • License Details
  • XCode Sample Project
  • .PSD files
  • Retina support
  • .PNG Artwork
  • iOS 10 optimised
Our iOS and Android app templates are a perfect place to start building awesome apps. Get a functional native code base, eye-catching beautiful artwork with excellent UX, icon artwork and documentation. Make your app so beautiful it can't be ignored

Splash Screen

Categories screen - content rich custom Table views

Slide Menu with expandable lists

Full screen video player

Integrated with YouTube API

Custom Search View

Intricate Video detail view

Elements screen, with cool custom UI elements

Code Snippet

//
//  HomeViewController.m
//  TVMe
//
//  Copyright (c) 2014 MyAppTemplates. All rights reserved.
//

#import "HomeViewController.h"
#import "VideoDetailViewController.h"

@interface HomeViewController ()

@end

@implementation HomeViewController

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

- (void)viewDidLoad
{
  
    [self downloadVideoInformation];
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

-(IBAction)playBtnTapped:(UIButton *)sender
{
    VideoDetailViewController *detailVC = (VideoDetailViewController *) [self viewFromStoryboard:@"VideoDetailViewController"];
    int index = [sender.accessibilityLabel intValue];
    detailVC.dicOfVideo = [arrOfVideos objectAtIndex:index];
    [self.navigationController pushViewController:detailVC animated:YES];

}

#pragma mark - Cells Used to populate tableView

-(UITableViewCell  *)getCellForTopScroller
{
    if (topScrollableCell == nil)
    {
        topScrollableCell = [[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, 320, 170)];
        
        UIScrollView *scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 170)];
        for (int i=0; i<5; i++)
        {
            NSString *thumbnailURL = [[[[[arrOfVideos objectAtIndex:i] objectForKey:@"snippet"] objectForKey:@"thumbnails"] objectForKey:@"high"]objectForKey:@"url"];
            UIView *view = [[UIView alloc]initWithFrame:CGRectMake(i*230, 0, 225, 160)];
            
            UIButton *btnPlay = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, 225, 160)];
            [btnPlay addTarget:self action:@selector(playBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
            [btnPlay setAccessibilityLabel:[NSString stringWithFormat:@"%d",i]];
            
            UIImageView *img = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 225, 160)];
            [img sd_setImageWithURL:[NSURL URLWithString:thumbnailURL]];
            img.contentMode = UIViewContentModeScaleAspectFill;
            img.clipsToBounds = YES;
            [view addSubview:img];
            [view addSubview:btnPlay];
            [scrollView addSubview:view];
        }
        [scrollView setContentSize:CGSizeMake(230*5, 170)];
        [self.view addSubview:scrollView];
        [topScrollableCell addSubview:scrollView];
    }
    return topScrollableCell;
}

-(IBAction)seeAllBtnTapped:(UIButton *)sender
{

    SeeAllViewController *seeVC = (SeeAllViewController *) [self viewFromStoryboard:@"SeeAllViewController"];
    seeVC.strCategoryName = sender.accessibilityLabel;
    [self.navigationController pushViewController:seeVC animated:YES];

}

-(UITableViewCell *)getMiddleThumbnailCell
{
    if (middleThumbnailCell == nil)
    {
        middleThumbnailCell = [[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, 320, 270)];
        UIView *heading = [CustomViews createHeadingLblViewWithTitle:@"Now streaming on TV"];
        heading.frame = CGRectMake(0, 0, 320, 40);
        [middleThumbnailCell.contentView addSubview:heading];
        
        UIButton *btnSeeAll = (UIButton *)[heading viewWithTag:K_TAG_OF_SEE_ALL];
        [btnSeeAll addTarget:self action:@selector(seeAllBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
        [btnSeeAll setAccessibilityLabel:@"Now streaming on TV"];
        
        for (int i=5; i<9; i++)
        {
            NSString *thumbnailURL = [[[[[arrOfVideos objectAtIndex:i] objectForKey:@"snippet"] objectForKey:@"thumbnails"] objectForKey:@"medium"]objectForKey:@"url"];
            UIView *view2 = [CustomViews createThumbnailViewWithData:@{@"title":[[[arrOfVideos objectAtIndex:i] objectForKey:@"snippet"] objectForKey:@"title"],@"category":@"Movie trailor",@"time":@"3:05",@"image":@"video-demo-all-categories.png"}];
            
            UIButton *btnPlay = (UIButton *)[view2 viewWithTag:K_TAG_OF_PLAY_BUTTON];
            [btnPlay addTarget:self action:@selector(playBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
            [btnPlay setAccessibilityLabel:[NSString stringWithFormat:@"%d",i]];
            
            UIImageView *img = (UIImageView *)[view2 viewWithTag:10];
            [img sd_setImageWithURL:[NSURL URLWithString:thumbnailURL]];
            CGRect frame;
            switch (i) {
                case 5:
                    frame =CGRectMake(10, 45, view2.frame.size.width, view2.frame.size.height);
                    break;
                case 6:
                    frame =CGRectMake(165, 45, view2.frame.size.width, view2.frame.size.height);
                    break;
                case 7:
                    frame =CGRectMake(10, 165, view2.frame.size.width, view2.frame.size.height);
                    break;
                case 8:
                    frame =CGRectMake(165, 165, view2.frame.size.width, view2.frame.size.height);
                    break;
                default:
                    break;
            }
            view2.frame = frame;
            [middleThumbnailCell.contentView addSubview:view2];
        }
    
    }
    return middleThumbnailCell;
}

-(UITableViewCell *)getPortraitThumbnailCell
{
    if (portraitThumbnailCell == nil)
    {
        portraitThumbnailCell = [[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, 320, 220)];
        UIView *heading = [CustomViews createHeadingLblViewWithTitle:@"Popular TV Channels"];
        heading.frame = CGRectMake(0, 0, 320, 40);
        [portraitThumbnailCell.contentView addSubview:heading];
        
        UIButton *btnSeeAll = (UIButton *)[heading viewWithTag:K_TAG_OF_SEE_ALL];
        [btnSeeAll addTarget:self action:@selector(seeAllBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
        [btnSeeAll setAccessibilityLabel:@"Popular TV Channels"];
        
        for (int i=10; i<13; i++)
        {
            NSString *thumbnailURL = [[[[[arrOfVideos objectAtIndex:i] objectForKey:@"snippet"] objectForKey:@"thumbnails"] objectForKey:@"medium"]objectForKey:@"url"];
            UIView *view2 = [CustomViews createPortraitThumbnailViewWithData:@{@"title":[[[arrOfVideos objectAtIndex:i] objectForKey:@"snippet"] objectForKey:@"title"],@"category":@"Movie trailor",@"time":@"3:05",@"image":@"video-demo-all-categories.png"}];
            UIButton *btnPlay = (UIButton *)[view2 viewWithTag:K_TAG_OF_PLAY_BUTTON];
            [btnPlay addTarget:self action:@selector(playBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
            [btnPlay setAccessibilityLabel:[NSString stringWithFormat:@"%d",i]];
            
            UIImageView *img = (UIImageView *)[view2 viewWithTag:10];
            [img sd_setImageWithURL:[NSURL URLWithString:thumbnailURL]];
            CGRect frame;
            frame =CGRectMake(8+(105*(i-10)), 40, view2.frame.size.width, view2.frame.size.height);
            
            view2.frame = frame;
            [portraitThumbnailCell.contentView addSubview:view2];
        }
        
    }
    return portraitThumbnailCell;
}

-(UITableViewCell *)getBottomCell
{
    if (bottomCell == nil)
    {
        bottomCell = [[UITableViewCell alloc]initWithFrame:CGRectMake(0, 0, 320, 50)];
        UIView *heading = [CustomViews createHeadingLblViewWithTitle:@"All TV Categories"];
        heading.frame = CGRectMake(0, 10, 320, 40);
        [bottomCell.contentView addSubview:heading];
        
        UIButton *btnSeeAll = (UIButton *)[heading viewWithTag:K_TAG_OF_SEE_ALL];
        [btnSeeAll addTarget:self action:@selector(seeAllBtnTapped:) forControlEvents:UIControlEventTouchUpInside];
        [btnSeeAll setAccessibilityLabel:@"All TV Categories"];
    }
    return bottomCell;
}


#pragma mark UITableView Datasource/Delegate

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // return arrOfOptions.count;
    if (arrOfVideos.count > 0)
        return 5 + 4;
    else
        return 0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == 0)
        return 170;
    if (indexPath.row == 1)
        return 280;
    if (indexPath.row == 2)
        return 220;
    if (indexPath.row == 3)
        return 50;
    return 90;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellMainNibID = @"cellMain";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellMainNibID];
    
    if (cell == nil) {
        cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] objectAtIndex:0];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        //cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellMainNibID];
    }
    if (indexPath.row == 0)
        cell = [self getCellForTopScroller];
    else if (indexPath.row ==1 )
        cell = [self getMiddleThumbnailCell];
    else if (indexPath.row == 2)
        cell = [self getPortraitThumbnailCell];
    else if (indexPath.row == 3)
        cell = [self getBottomCell];
    else
    {
        NSString *thumbnailURL = [[[[[arrOfVideos objectAtIndex:indexPath.row] objectForKey:@"snippet"] objectForKey:@"thumbnails"] objectForKey:@"medium"]objectForKey:@"url"];
        UIImageView *img = (UIImageView *)[cell.contentView viewWithTag:2];
        
        UILabel *lblTitle = (UILabel *)[cell.contentView viewWithTag:3];
        lblTitle.text = [[[arrOfVideos objectAtIndex:indexPath.row] objectForKey:@"snippet"] objectForKey:@"title"];
        lblTitle.font= [UIFont fontWithName:@"Roboto-regular" size:13];
        
        UILabel *lblPostedBy = (UILabel *)[cell.contentView viewWithTag:4];
        lblPostedBy.text = [NSString stringWithFormat:@"Posted by %@",[[[arrOfVideos objectAtIndex:indexPath.row] objectForKey:@"snippet"] objectForKey:@"channelTitle"]];
        lblPostedBy.font = [UIFont fontWithName:@"Roboto-regular" size:11];
        
        UILabel *lblTime = (UILabel *)[cell.contentView viewWithTag:5];
        lblTime.text = [[[arrOfVideos objectAtIndex:indexPath.row] objectForKey:@"snippet"] objectForKey:@"publishedAt"];
        lblTime.font= [UIFont fontWithName:@"Roboto-regular" size:11];
        [img sd_setImageWithURL:[NSURL URLWithString:thumbnailURL]];
    }
    
    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    VideoDetailViewController *detailVC = (VideoDetailViewController *) [self viewFromStoryboard:@"VideoDetailViewController"];
    detailVC.dicOfVideo = [arrOfVideos objectAtIndex:indexPath.row];
    [self.navigationController pushViewController:detailVC animated:YES];
}

-(void)downloadVideoInformation
{
    conn = [[CustomConnection alloc]init];
    conn.delegate = self;
    if (![conn startDownload:@"https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&order=relevance&maxResults=50&videoEmbeddable=true&fields=items(id,snippet)&key=AIzaSyD-0vnOK899x0RDjxT6a3ovbC_gL-41QZ4&q=australia"])
    {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Cannot connect to internet" delegate:self cancelButtonTitle:@"Done" otherButtonTitles:nil];
        [alert show];
        
    }
}


#pragma mark - Connection Delegates

-(void)connectionFinishedSuccessfully:(NSData *)data withTag:(int)tag
{
    NSError *error = nil;

    NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data
                                                                 options:kNilOptions
                                                                   error:&error];
    arrOfVideos = [[NSMutableArray alloc]init];
    arrOfVideos =[jsonResponse objectForKey:@"items"];
    NSLog(@"%@",arrOfVideos);
    [tblView reloadData];

}

-(void)connectionDidFailed:(NSError *)error withTag:(int)tag
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Cannot connect to internet" delegate:self cancelButtonTitle:@"Done" otherButtonTitles:nil];
    [alert show];
}



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



/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

Template Benefits

  • iOS 10 ready
  • iPhone 5/6/7/7+ ready
  • Beautiful, minimal design with excellent UX flow
  • Ready to run right away in xCode
  • Prebuilt functionality saves you hundreds of hours of designing, programming, and testing
  • Customise the template in xCode to build your own app
  • Adheres to Apple’s strict Human Interface Guidelines for easier app approval
  • The easiest way to create your own app!