Cannot set thumbnail image for UIWebView - uiwebview

I want to set thumbnail image in the uiwebview frame on my view.
However when I use the following code, there is no image displayed, although the image value is NOT NULL. Can someone help and and let me knwo where am I going wrong?
Please note that in the code, the VideoView class is derived from UIWebView and works just like it.
video = [[VideoView alloc]
initWithStringAsURL:#"http://www.youtube.com/watch?v=T6X3j7zxUHA"
frame:CGRectMake(11, 7, 298, 311)];
[self addSubview:video];
UIGraphicsBeginImageContext(video.bounds.size);
[video.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *resultImageView = UIGraphicsGetImageFromCurrentImageContext();
thumbnailButton = [UIButton buttonWithType:UIButtonTypeCustom];
[thumbnailButton setFrame:CGRectMake(0,0, 298, 311)];
[thumbnailButton setImage:resultImageView forState:UIControlStateNormal];
[video addSubview:thumbnailButton];
UIGraphicsEndImageContext();

I would not recommend using a UIWebView to just get a thumbnail of a YouTube video, but here is some code that I use to embed youtube videos in my app.
static NSString* EmbedHTML = "<html>\
<head>\
<meta name=\"viewport\" content=\"initial-scale=1.0, user-scalable=no, width=%0.0f\"/>\
</head>\
<iframe width=\"%0.0f\" height=\"%0.0f\" src=\"%#\" frameborder=\"0\" allowfullscreen> </iframe></html>";
Use that to embed the video and change your youtube URL from http://www.youtube.com/watch?v=T6X3j7zxUHA to http://www.youtube.com/embed/T6X3j7zxUHA.
Another way to get this that would not require the webview, would be to just build the thumbnail by hand. (example below)
///////////////////////////////////////////////////////////////////////////////////////////////////
-(NSString*)youtubeThumb:(NSString*)url
{
NSRange end = [url rangeOfString:#"?"];
if(end.location != NSNotFound)
{
NSRange start = [url rangeOfString:#"/" options:NSBackwardsSearch range:NSMakeRange(0, end.location)];
if(start.location != NSNotFound)
{
NSString* video_id = [url substringWithRange:NSMakeRange(start.location+1, (end.location-1)-start.location)];
return [NSString stringWithFormat:#"http://i.ytimg.com/vi/%#/2.jpg",video_id];
}
}
return nil;
}
Now you have the image thumbnail URL, just fetch it (via a simple GET request).

Related

How to use NSCache with CoreData

I have developed a project, where a user draws a image on a canvas, I store it in the file using CoreData, I have one-to-many relationship called folder-to-files. So here all are images. I retrive the images from files , resize according to my table cell height and show it on a table. Once it is shown, I want to cache the images.
I also have some labels on the folder cell, which give me some info regarding my files, which I update on fly.
I also swipe the cells to mark it complete and move it to the bottom the cell.
I also show same file images in different Views depending on how user queries it.
I want to know the best method for this, I read through the web, their are many methods, GCD, NSOperationQueues and many more.
Which method will be best suited for me.
I want to show some code
- (UITableViewCell *)tableView:(FMMoveTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
FolderCell *tableCell = (FolderCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (tableCell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"FolderCell" owner:self options:nil];
tableCell = [nib objectAtIndex:0];
}
NSMutableArray *categoryArray = [[self.controller fetchedObjects]mutableCopy];
Folder *category = [categoryArray objectAtIndex:[indexPath row]];
[tableCell configureCellWithNote:category]; //This function is written in my FolderCell.m function
}
return tableCell;
}
-(void)configureCellWithNote:(Folder *)category
{
self.category = category;
UIImage *image1 = [UIImage imageWithData:category.noteImage];
CGSize newSize;
if(image1.size.width == 620 && image1.size.height == 200)
{
newSize = CGSizeMake(300, 97);
}
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
self.notesImage.image = newImage;
}
So what is happening here is that configureCellWithNote is taking lot of time, because it is resizing images. Please help me out in deciding how can this performance issue be solved.
Regards
Rajit
If you simply want to shuffle the resize operation to a background thread, you could do something like this:
- (void)configureCellWithNote:(Folder *)category
{
self.category = category;
UIImage *image1 = [UIImage imageWithData:category.noteImage];
CGSize newSize;
if(image1.size.width == 620 && image1.size.height == 200)
{
newSize = CGSizeMake(300, 97);
}
dispatch_async(dispatch_get_global_queue(0,0), ^{
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image1 drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
dispatch_async(dispatch_get_main_queue(), ^{
self.notesImage.image = newImage;
});
});
}
If you want to cache the results, then the trick will be to come up with a good cache key. Unfortunately, it's hard to tell from what you've posted what would make a good cache key. Certainly it will need to include the size, but it'll also need to include something that ties it back to the category. I suppose if nothing else you could use the NSManagedObjectID for the category, but I think that'll be specific to each managed object context you have. Assuming there was a property on Folder called uniqueName a caching implementation might look like this:
- (UIImage*)imageForCategory: (Folder*)category atSize: (CGSize)size
{
// A shared (i.e. global, but scoped to this function) cache
static NSCache* imageCache = nil;
// The following initializes the cache once, and only once
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
imageCache = [[NSCache alloc] init];
});
// Generate a cache key sufficient to uniquely identify the image we're looking for
NSString* cacheKey = [NSString stringWithFormat: #"%#|%#", category.uniqueName, NSStringFromSize((NSSize)size)];
// Try fetching any existing image for that key from the cache.
UIImage* img = [imageCache objectForKey: cacheKey];
// If we don't find a pre-existing one, create one
if (!img)
{
// Your original code for creating a resized image...
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
UIImage* image1 = [UIImage imageWithData:category.noteImage];
[image1 drawInRect:CGRectMake(0,0,size.width,size.height)];
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Now add the newly-created image to the cache
[imageCache setObject: img forKey: cacheKey];
}
// Return the image
return img;
}

How can I save a user selected image (Zbar Scanner) inside apps Documents folder

So I have 2 views, one of them is a UITableVew where a user can populate cells by adding them. The second view is the information when they add them (Name, date, company and a place to scan a barcode.). Well when they scan that image, they can see the image of what they scanned (Done with Zbar barcode scanner). So the main question is how can I exactly save different images in each different cell that the user adds?
Code:
Zbar:
- (IBAction)cameraButtonTapped:(id)sender
{
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentModalViewController:imagePicker animated:YES];
}
}
- (void) imagePickerController: (UIImagePickerController*)reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated:YES];
}
-(UIView*)CommomOverlay{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
UIImageView *TopBar = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,58)];
[TopBar setImage:[UIImage imageNamed:#""]];
[view addSubview:TopBar];
UILabel *Toplabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 9, 300, 30)];
[Toplabel setFont:[UIFont fontWithName:#"Heiti TC light" size:22]];
[Toplabel setTextAlignment:UITextAlignmentCenter];
[Toplabel setBackgroundColor:[UIColor clearColor]];
[Toplabel setTextColor:[UIColor lightGrayColor]];
[Toplabel setNumberOfLines:1];
[Toplabel setText:#"Turn your device sideways to scan"];
[TopBar addSubview:Toplabel];
UIImageView *FrameImg = [[UIImageView alloc] initWithFrame:CGRectMake(40,50,240,370)];
[FrameImg setImage:[UIImage imageNamed:#"scanImage.png"]];
[view addSubview:FrameImg];
return view;
}
- (IBAction) scanButtonTapped
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
reader.cameraOverlayView = [self CommomOverlay];
[self presentModalViewController: reader
animated: YES];
}
I did think using core data but i cant find a tutorial anywhere. Then I thought saving it in the apps Documents folder and i think that would be the bes way for me. I am new to this so descriptive code would help :)
Update:
- (IBAction)save:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
UIImage *image = resultImage.image;
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#KYRO Receipts Images/Barcode.png", resultImage]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
if (self.device) {
// Update existing device
[self.device setValue:self.nameOfItem.text forKey:#"name"];
[self.device setValue:self.dateOfPurchase.text forKey:#"date"];
[self.device setValue:self.companyOfItem.text forKey:#"company"];
} else {
//
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Receipt" inManagedObjectContext:context];
[newDevice setValue:self.nameOfItem.text forKey:#"name"];
[newDevice setValue:self.dateOfPurchase.text forKey:#"date"];
[newDevice setValue:self.companyOfItem.text forKey:#"company"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[WTStatusBar setStatusText:#"Saving data..." animated:YES];
[self performSelector:#selector(setTextStatusProgress3) withObject:nil afterDelay:0.1];
[self.navigationController popViewControllerAnimated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
If you're already using Core Data, then depending on the size of the images you could either convert them to NSData and save them directly within Core Data (if they're small) or you can save them within the documents directory and save the file name within Core Data.
Since a full Core Data tutorial is beyond the scope here, I'll just go over saving the image to the documents directory under a unique name. Note that some of the code below was adapted from "iOS Programming: The Big Nerd Ranch Guide".
// Method to save your image file. Returns the file name for you to save in Core Data or elsewhere.
- (NSString *)saveImage:(UIImage *)image {
// Generate a unique key to name the image file
CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);
NSString *imgkey = (__bridge NSString *)newUniqueIDString;
// Get a path for the image file in the documents directory
NSString *imagePath = [self imagePathForKey:imgkey];
// Convert the UIImage into NSData and save it to the documents directory
NSData *imageData = UIImageJPEGRepresentation(img, 0.5);
[imageData writeToFile:imagePath atomically:YES];
// Clean up
CFRelease(newUniqueIDString);
CFRelease(newUniqueID);
return imgkey;
}
// Method to provide the image path for saving/retrieving the image
- (NSString *)imagePathForKey:(NSString *)key {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:key];
}
The following method retrieves the image:
- (UIImage *)imageForKey:(NSString *)imgkey {
result = [UIImage imageWithContentsOfFile:[self imagePathForKey:imgkey thumbnail:FALSE]];
if (!result) {
// File not found - add code here as needed (to return default image or whatever)
}
return result;
}
Note that if you are planning to display multiple images in the table at the same time, you must be careful to ensure they are small, otherwise you may run into memory issues. In this case you would want to convert them into a thumbnail form for the table view, then display the full size image only in the detail view (how to generate a thumbnail would be a separate question).

Unable to Integrate Instagram in iOS App

i am unable to post my photos on instagram using ios App. I got the following code from a post here on stackoverflow but it does not work. When Instagram starts, it displays error unable to open file. kindly help me.
NSURL *instagramURL = [NSURL URLWithString:#"instagram://location?id=1"];
if ([[UIApplication sharedApplication] canOpenURL:instagramURL]) {
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:#"Image.ig"];
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:#"Icon.png"]);
[imageData writeToFile:savedImagePath atomically:YES];
NSURL *imageUrl = [NSURL fileURLWithPath:savedImagePath];
docController = [[UIDocumentInteractionController alloc] init];
docController.delegate = self;
[docController retain];
docController.UTI = #"com.instagram.photo";
[docController setURL:imageUrl];
[docController presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}else{
UIAlertView *errorToShare = [[UIAlertView alloc] initWithTitle:#"Instagram unavailable " message:#"You need to install Instagram in your device in order to share this image" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorToShare show];
[errorToShare release];
}
Minimum resolution for instagram is 612x612. Always JPG.
For the sake of completion, the minimum resolution remains at 612x612 (this is due to displaying images on retina devices), but Instagram now supports both JPEG and PNG images. All non-square images sent to Instagram must be cropped before posting.

displaying Wiki mobile page in UIWebView within UIPopoverController

I try to open wiki mobile version webpage by a UIWebView within a UIPopoverController. the problem is, not matter how I set my contentSizeForViewInPopover, or just UIWebView frame, or simply set UIWebView.scalesPageToFit = YES. the Wiki mobile version page content size seem to larger than my UIWebView. But if I use it on iPhone, there's no such problem. here's my code for popover controller:
//create a UIWebView UIViewController first
WikiViewController *addView = [[WikiViewController alloc] init];
addView.contentSizeForViewInPopover = CGSizeMake(320.0, 480.0f);
//then create my UIPopoverController
popover = [[UIPopoverController alloc] initWithContentViewController:addView];
popover.delegate = self;
[addView release];
//then get the popover rect
CGPoint pointforPop = [self.mapView convertCoordinate:selectAnnotationCord
toPointToView:self.mapView];
CGRect askRect = CGRectMake((int)pointforPop.x, (int)pointforPop.y+10, 1.0, 1.0);
[popover presentPopoverFromRect:askRect
inView:self.mapView
permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
[self.mapView deselectAnnotation:annotation animated:YES];
and this is my code on creating UIWebView:
- (void)viewDidLoad
{
wikiWebView = [[UIWebView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 480.0f)];
wikiWebView.scalesPageToFit = YES;
//or No, doesn't matter, it all get larger than this
wikiWebView.delegate = self;
self.view = wikiWebView;
}
all code seem to be typical...
I wonder if anyone can shed me some light, thank you so much.
This is an enhanced version of auco answer, where if the viewport meta tag is not present it will be added:
- (void)webViewDidFinishLoad:(UIWebView*)webView
{
int webviewWidth = (NSUInteger)webView.frame.size.width;
if (!webView.loading) {
NSString *jsCmd = [NSString stringWithFormat:#"try {var viewport = document.querySelector('meta[name=viewport]');if (viewport != null) {viewport.setAttribute('content','width=%ipx, initial-scale=1.0, user-scalable=1');} else {var viewPortTag=document.createElement('meta');viewPortTag.id='viewport';viewPortTag.name = 'viewport';viewPortTag.content = 'width=%ipx, initial-scale=1.0, user-scalable=1';document.getElementsByTagName('head')[0].appendChild(viewPortTag);}} catch (e) {/*alert(e);*/}", webviewWidth, webviewWidth];
[webView stringByEvaluatingJavaScriptFromString:jsCmd];
}
}
Here is the Javascript pretty formatted code we are injecting in the WebView with a width of 320px
try {
var viewport = document.querySelector('meta[name=viewport]');
if (viewport != null) {
viewport.setAttribute('content',
'width=320px, initial-scale=1.0, user-scalable=1');
} else {
var viewPortTag = document.createElement('meta');
viewPortTag.id = 'viewport';
viewPortTag.name = 'viewport';
viewPortTag.content = 'width=320px,initial-scale=1.0, user-scalable=1';
document.getElementsByTagName('head')[0].appendChild(viewPortTag);
}
} catch (e) {
/*alert(e);*/
}
you can remove the try/catch if you want.
oh, i found in another QA that sometimes if html got a line "width=device-width", and you load a webview from popover controller, this popover controller will automatically send out device-width, not the view width you specified, and make your view ugly and funky. in that post it is a jQuery issue, and it solved with a jQuery way. In my problem, it is just a html issue in wiki mobile version. so I try another way, but similar.
I simple add a code in webViewdidload delegate method, first get URL html into a NSString, then use NSString instance method to search for "device-width" in loaded html, and replace it with my view width to make it a new NSString, then load this page with this new NSString. that's it.
- (void) webViewDidFinishLoad:(UIWebView *)webView
{
if (!alreadyReload)
{
NSString *webHTML = [NSString stringWithContentsOfURL:webView.request.URL encoding:NSUTF8StringEncoding error:NULL];
NSRange range = [webHTML rangeOfString:#"device-width"];
if ((range.location!=NSNotFound)&&(range.length != 0))
{
webHTML = [webHTML stringByReplacingOccurrencesOfString:#"device-width" withString:#"whatever width you need" options:0 range:range];
[webView loadHTMLString:webHTML baseURL:wikiWebView.request.URL];
alreadyReload = YES;
}
}
}
something like this.
by the way, since I only use this on wiki mobile version, the html is simple and this kind of compare and replace is pretty easy. if you wanna use it in a more general case, you might use other way.
It would be much more efficient to manipulate the device-width via JavaScript rather than altering the html after it has fully loaded and then reloading the full page with modified html again.
This should work (and also consider if it's even necessary to change the viewport width):
- (void)webViewDidFinishLoad:(UIWebView *)aWebView {
if(aWebView.frame.size.width < aWebView.window.frame.size.width) {
// width=device-width results in a wrong viewport dimension for webpages displayed in a popover
NSString *jsCmd = #"var viewport = document.querySelector('meta[name=viewport]');";
jsCmd = [jsCmd stringByAppendingFormat:#"viewport.setAttribute('content', 'width=%i, initial-scale=1.0, user-scalable=1');", (NSUInteger)aWebView.frame.size.width];
[aWebView stringByEvaluatingJavaScriptFromString:jsCmd];
}
// stop network indicator
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

MPMoviePlayerController causes flash of black at start of video

The movie plays just fine but there is a quick black flash right before it plays. Is this a quirk resulting from setting the controlstyle to MPMovieControlStyleNone?
NSString *url = [[NSBundle mainBundle] pathForResource:#"00" ofType:#"mov"];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc]
initWithContentURL:[NSURL fileURLWithPath:url]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
//---play video in implicit size---
player.view.frame = CGRectMake(80, 64, 163, 246);
[self.view addSubview:player.view];
// Hide video controls
player.controlStyle = MPMovieControlStyleNone;
//---play movie---
[player play];
I just had this problem and fixed it by adding an observer to the default NSNotificationCenter to find out when the movie was completely ready to play, and THEN adding the view as a subview to my main view.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
...
if(moviePlayer.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK))
{
[pageShown.view addSubview:moviePlayer.view];
[moviePlayer play];
}
In IOS 6 mpmoviewplayer added a new property :readyForDisplay
this is what I'm playing around with and so far so good:
create mpmovieplayer ,add to stage, hide it.
add notification for play state on the movieController
wait for the displayState to Change and once its ready show the video controller:
- (void)moviePlayerPlayState:(NSNotification *)noti {
if (noti.object == self.movieController) {
MPMoviePlaybackState reason = self.movieController.playbackState;
if (reason==MPMoviePlaybackStatePlaying) {
[[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
while (self.movieController.view.hidden)
{
NSLog(#"not ready");
if (self.movieController.readyForDisplay) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSLog(#"show");
self.movieController.view.hidden=NO;
});
}
usleep(50);
}
});
}
}
}
When the play state changes to MPMoviePlaybackStatePlaying we start checking for the readyDisplayState to change.
Evidently there is a flash of black in the movie rect until enough movie loads so it can start playback. Here is my workaround:
Create a UIImageView and put the MPMoviePlayerController in it. That way you can set the alpha to 0.
As soon as you call [player play]; to play the video, set up a .5 second timer.
When the time is done, change the alpha to 1.
This will make the player invisible for 1/2 second (which hides the black flash).
Create video without addSubview and play instructions:
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"video" ofType:#"mp4"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[moviePlayerController.view setFrame:CGRectMake(80, 64, 163, 246)];
moviePlayerController.controlStyle = MPMovieControlStyleNone;
Prepare video to play and add notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
[moviePlayerController prepareToPlay];
Create function checkMovieStatus with addSubview and play instructions:
- (void)checkMovieStatus:(NSNotification *)notification {
if(moviePlayerController.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK)) {
[self.view addSubview:moviePlayerController.view];
[moviePlayerController play];
}
}
Or simply change the color of the view, that is what your actually seeing...
player.view.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0];
I believe the black flash may be related to the movieSourceType property of MPMoviePlayerController.
If you don't set it, it defaults to MPMovieSourceTypeUnknown which causes the UI to be delayed until the file is loaded.
Try adding this line:
player.movieSourceType = MPMovieSourceTypeFile;
Right after initializing player.
To avoid the black flash, use a MPMoviePlayerViewController instead of a MPMoviePlayerController. I think that this class creates the background on view display, rather than on video load (like MPMoviePlayerController does).
Before adding the moviePlayerViewController.moviePlayer.view to your display view, you have to add a white subview (or a subview appropriate for your content) to the backgroundView, like this:
[moviePlayerViewController.moviePlayer.view setFrame:[displayView bounds]];
UIView *movieBackgroundView = [[UIView alloc] initWithFrame:[displayView bounds]];
movieBackgroundView.backgroundColor = [UIColor whiteColor];
[moviePlayerViewController.moviePlayer.backgroundView addSubview:movieBackgroundView];
[movieBackgroundView release];
Fond solution here http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/
from iOS 6
you need to use [self.moviePlayer prepareToPlay]; and catch MPMoviePlayerReadyForDisplayDidChangeNotification to use [self.moviePlayer play];

Resources