I want to create a quick picture/movie viewer - for a birthday celebration.
First I want to show some pictures - then a movie - and then some pictures again. The first picture animation shows up fine, movie starts fine and catching AVPlayerItemDidPlayToEndTimeNotification just fine to launch pictures again, - but second animation never starts - I cannot work this out ?? - DoShow1 is not working - please advice anybody out there ??
- (void)DoShow
{
NSArray *imageNames = #[#"1.jpg", #"2.jpg", #"3.png", #"4.png",
#"5.png", #"6.png",#"7.png", #"8.png",
#"9.png", #"10.png", #"11.png",#"12.png",
#"13.png"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
_imageview.animationImages = images;
_imageview.animationDuration = 10;
_imageview.animationRepeatCount = 1;
[_imageview startAnimating];
[self performSelector:#selector(playmovie) withObject:nil afterDelay: 10];
}
- (void)DoShow1
{
NSArray *imageNames = #[#"14.jpg", #"16.jpg", #"18.jpg", #"19.jpg",
#"20.jpg", #"22.jpg",#"23.jpg", #"24.jpg"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
_imageview2.animationImages = images;
_imageview2.animationDuration = 2;
_imageview2.animationRepeatCount = 100;
[_imageview2 startAnimating];
}
- (void) playmovie
{
MyMusicPlayerManager *sharedManager = [MyMusicPlayerManager sharedManager];
[sharedManager ChkPaused];
NSBundle *Bundle = [NSBundle mainBundle];
NSString *moviePath = [Bundle pathForResource:#"stine_ane" ofType:#"mp4"];
NSLog(#"String is %#", moviePath);
NSURL *url = [NSURL fileURLWithPath:moviePath];
AVPlayerItem *video = [[AVPlayerItem alloc] initWithURL:url];
AVQueuePlayer *queue = [[AVQueuePlayer alloc] initWithItems:#[video]];
video = [[AVPlayerItem alloc] initWithURL:url];
[queue insertItem:video afterItem:nil];
self.avmovieplayer = [[AVPlayerViewController alloc] init];
self.avmovieplayer.player = queue;
[self presentViewController:self.avmovieplayer animated:YES completion:nil];
self.avmovieplayer.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[avmovieplayer.player currentItem]];
[self.avmovieplayer setShowsPlaybackControls:YES];
[self.avmovieplayer.player play];
}
- (void)myMovieFinishedCallback:(NSNotification *)notification {
[self dismissViewControllerAnimated:YES completion:Nil];
[self DoShow1];
}
- (IBAction)DoStart:(id)sender {
[self DoShow];
}
[self dismissViewControllerAnimated:YES completion:Nil];
[self DoShow1];
this is probably calling in succession and animation doesnt start at the same time the view is being dismissed.
try it in the completion handler which is called after the view is
dismissed
[self dismissViewControllerAnimated:YES completion:^{
[self DoShow1];
}];
Related
How can I use activity indicator in second view controller to let data to be complete load
first VC
- (IBAction)btnOpenHTML:(id)sender {
RecievVC *obj = [self.storyboard instantiateViewControllerWithIdentifier:#"RecievVC"];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:lblName.text forKey:#"lblname"];
//........Lots of Data........(then in the end of 1st VC)........//
obj.dicData = dict;
[self.navigationController pushViewController:obj animated:true];
}
#end
the 2nd VC Code after viewdidload
- (void)viewDidLoad {
[super viewDidLoad];
[self->webView.scrollView setScrollEnabled:true];
[self->webView loadHTMLString:[self getHTMLStirng] baseURL:[NSURL URLWithString:#""]];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(NSString *)getHTMLStirng {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"resumeT" ofType:#"html"];
NSString *strHTML = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
if (self.dicData) {
strHTML = [strHTML stringByReplacingOccurrencesOfString:#"#NAME" withString:[_dicData valueForKey:#"lblname"]];
//...............Lots of Data......Then at the end of 2nd VC............//
}return strHTML;
}
what I main by lots of data, it's around 150 of keys and value have to be send from 1st VC to 2nd VC.
any idea?
You could try GCD:
// instantiate the activity indicator
UIActivityIndicatorView *activity = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle: UIActivityIndicatorViewStyleGray];
activity.center = self.view.center;
// start your activity indicator
[activity startAnimating]
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// load data on background thread
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:lblName.text forKey:#"lblname"];
//........Lots of Data........(then in the end of 1st VC)........//
// update UI on main thread
dispatch_async(dispatch_get_main_queue(), ^{
// stop your activity indicator
[activity stopAnimating]
RecievVC *obj = [self.storyboard instantiateViewControllerWithIdentifier:#"RecievVC"];
obj.dicData = dict;
[self.navigationController pushViewController:obj animated:true];
});
});
I used ELCImagePicker with my APP I faced two problems the first one when gallery appear view not equal to the width of iPhone or iPad like image blow, the second one images that appear in gallery are pixeled not on the normal resolution.
//----------------------------------------------------
//imagePicker Zone
- (IBAction)uploadImageActionButton:(id)sender {
ELCImagePickerController *elcPicker = [[ELCImagePickerController alloc] initImagePicker];
elcPicker.maximumImagesCount = 5; //Set the maximum number of images to select to 100
elcPicker.returnsOriginalImage = YES; //Only return the fullScreenImage, not the fullResolutionImage
elcPicker.returnsImage = YES; //Return UIimage if YES. If NO, only return asset location information
elcPicker.onOrder = YES; //For multiple image selection, display and return order of selected images
elcPicker.mediaTypes = #[(NSString *)kUTTypeImage, (NSString *)kUTTypeMovie]; //Supports image and movie types
elcPicker.imagePickerDelegate = self;
[self presentViewController:elcPicker animated:YES completion:nil];
}
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{//yes
[self dismissViewControllerAnimated:YES completion:nil];
//
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[info count]];
NSMutableArray *name = [NSMutableArray arrayWithCapacity:[info count]];
NSMutableArray *path = [NSMutableArray arrayWithCapacity:[info count]];
NSString *aDocumentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSInteger anIndex = 0;
for(NSDictionary *dict in info) {
UIImage *image = [dict objectForKey:UIImagePickerControllerOriginalImage];
[images addObject:image];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
// Save Image
NSString *anImageName = [NSString stringWithFormat:#"%ld.jpg", 1+(long)anIndex++];
NSString *anImagePath = [NSString stringWithFormat:#"%#/%#", aDocumentsDirectory, anImageName];
NSData *anImageData = UIImageJPEGRepresentation(image, 0.5);
[anImageData writeToFile:anImagePath atomically:YES];
[path addObject:anImagePath];
[images addObject:anImageData];
}
_chosenImages=images;
_chosenImagesName=name;
_chosenImagesPath=path;
NSLog(#"name %#",_chosenImagesName);
}
- (void)elcImagePickerControllerDidCancel:(ELCImagePickerController *)picker
{//yes
[self dismissViewControllerAnimated:YES completion:nil];
}
Right now I'm allocating and initializing three UIImageViews that take up the entire screen and are stacked in the viewDidLoad method. Its actually taking some time to do this. Is there a way to do this automatically so the view just has them before its even loaded? like an init method that would speed this up?
- (void)viewDidLoad {
[super viewDidLoad];
self.mySubviews = [[NSMutableArray alloc] init];
self.videoCounterTags = [[NSMutableArray alloc] init];
int c = (int)[self.scenes count];
c--;
NSLog(#"int c = %d", c);
self.myCounter = [NSNumber numberWithInt:c];
for (int i=0; i<=c; i++) {
//create imageView
UIImageView *imageView =[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height)];
[imageView setUserInteractionEnabled:YES]; // <--- This is very important
imageView.tag = i; // <--- Add tag to track this subview in the view stack
[self.view addSubview:imageView];
NSLog(#"added image view %d", i);
//get scene object
PFObject *sceneObject = self.scenes[i];
//get the PFFile and filetype
PFFile *file = [sceneObject objectForKey:#"file"];
NSString *fileType = [sceneObject objectForKey:#"fileType"];
//check the filetype
if ([fileType isEqual: #"image"])
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//get image
NSURL *imageFileUrl = [[NSURL alloc] initWithString:file.url];
NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl];
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageWithData:imageData];
});
});
}
//its a video
else
{
// the video player
NSURL *fileUrl = [NSURL URLWithString:file.url];
self.avPlayer = [AVPlayer playerWithURL:fileUrl];
self.avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
//self.avPlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[self.avPlayer currentItem]];
CGRect screenRect = [[UIScreen mainScreen] bounds];
self.avPlayerLayer.frame = CGRectMake(0, 0, screenRect.size.width, screenRect.size.height);
[imageView.layer addSublayer:self.avPlayerLayer];
NSNumber *tag = [NSNumber numberWithInt:i+1];
NSLog(#"tag = %#", tag);
[self.videoCounterTags addObject:tag];
}
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(viewTapped:)];
// dummyScreen is just a see through view that sits on top of my image stack and holds my tap gesture recognizer
[self.view bringSubviewToFront:self.dummyScreen];
[self.dummyScreen addGestureRecognizer:tapGesture];
}
The problem is this line:
dispatch_async(dispatch_get_global_queue...
That moves you onto a background thread, and thus there is no telling when the code will be executed. Hence the delay.
If these are local files (i.e., the URL is the file URL of an image file in your app bundle), there is no need for any dispatch_async in your code. Remove all of that and do everything on the main thread. That way, it will happen as fast as possible.
If these are remote files (i.e., you have to do networking to get hold of them), then there's probably nothing you can do to speed things up; networking takes time, and viewDidLoad is just about as early as you can possibly be notified that it's time to get hold of the images.
My code is:
-(void)playMoviesForItems:(NSArray *)shopItems{
_moviePlayer = [self.storyboard instantiateViewControllerWithIdentifier:#"videoPlayerController"];
[_moviePlayer playMoviesForItems:shopItems];
[self presentViewController:_moviePlayer animated:NO completion:^{
[self.scrollView scrollRectToVisible:CGRectZero animated:YES];
}];
}
In the line that includes presentViewController, I am getting
EXC_BAD_ACCESS (code=1, address=.....)
I cannot find why I am getting this. Where am I wrong? How can I debug that?
UPDATE:
Movie Player is declared like:
#property(nonatomic,retain) VideoPlayerViewController* moviePlayer;
And the code in VideoPlayerController is:
-(VideoPlayerViewController*)playMoviesForItems:(NSArray*)items{
playerItems = [[NSMutableArray alloc] init];
for (ShopItem* item in items) {
NSURL *url = [NSURL fileURLWithPath:item.localUrl];
AVPlayerItem *videoItem = [AVPlayerItem playerItemWithURL:url];
[playerItems addObject:videoItem];
}
self.mPlayer = [[AVQueuePlayer alloc] init];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:mPlayer];
self.playerLayer.bounds = self.view.bounds;
self.view.backgroundColor = [UIColor blackColor];
[mPlaybackView setPlayer:self.mPlayer];
currentIndex = 0;
[self initScrubberTimer];
[self playAtIndex:currentIndex];
mScrubber.maximumValue = CMTimeGetSeconds(self.mPlayer.currentItem.duration);
mScrubber.value = 0.0;
[self syncScrubber];
[self showOverlays];
return self;
}
Sometimes it works clearly. But sometimes it breaks.
[EDIT]
Ok I found the problem, I was just calling the bad connection request of my web service. So downloading a blog would erase the articles list content. Time for a break :p
#
I'm upgrading an old app which is a simple RSS reader with a list of articles and a list of blogs. Each of these is a UITableView with its own UITableViewController.
Both of them retrieve data from a JSON file on my server.
At the end of the JSON parsing I update the dataSources and then call the reloadData method on both tableviews. The problem is that the articles list is filled with the blogs and the blog list isn't filled at all.
If I don't call reloadData on the blog tableview, the article one is filled correctly and works well. As seen on an other post I've tried with the tableview.tag identifier but it doesn't work.
Note: I'm not using IB.
Here is the code for the BlogTableViewController:
#implementation BlogsTVC
#synthesize dataSourceForBlogs;
#synthesize blogRec;
- (id)initWithStyle:(UITableViewStyle)style
{
if ((self = [super initWithStyle:style])) {
self.title = #"Blogs";
self.tableView.tag = 2;
self.tableView.delegate = self;
dataSourceForBlogs = [[NSMutableArray alloc] init];
// Register to notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callback_blogs:) name:#"blogs" object:nil ];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(connection_error:) name:#"connection_error" object:nil];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self refreshBlogs];
}
-(void)callback_blogs:(NSNotification *)notification
{
if([self.dataSourceForBlogs count] > 0)
{
NSInteger i, count = [self.dataSourceForBlogs count];
for(i=0; i < count; i++)
{
[[self.dataSourceForBlogs objectAtIndex:i] release];
}
[self.dataSourceForBlogs removeAllObjects];
}
//remplissage
NSArray *receivedDatas = [[notification userInfo] objectForKey:#"data"];
NSUInteger i, count = [receivedDatas count];
for(i=0; i<count; i++)
{
self.blogRec = [[BlogRecord alloc] init];
self.blogRec.blog_id_auteur = [[receivedDatas objectAtIndex:i] objectForKey:#"id"];
self.blogRec.blog_auteur = [[receivedDatas objectAtIndex:i]objectForKey:#"auteur"];
self.blogRec.blog_url = [[receivedDatas objectAtIndex:i]objectForKey:#"url"];
self.blogRec.blog_date = [[receivedDatas objectAtIndex:i] objectForKey:#"date"];
self.blogRec.blog_nb_pub = [[receivedDatas objectAtIndex:i] objectForKey:#"nb_publication"];
self.blogRec.blog_url_image = [[receivedDatas objectAtIndex:i] objectForKey:#"theme"];
[self.dataSourceForBlogs addObject:self.blogRec];
self.blogRec = nil;
}
[self.tableView reloadData];
}
Here is the code for the Articles:
#implementation ActualiteTVC
#synthesize dataSource;
#synthesize artRec;
#pragma mark -
#pragma mark Initialization
- (id)initWithStyle:(UITableViewStyle)style {
// Override initWithStyle: if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
if ((self = [super initWithStyle:style])) {
// Titles
self.title = #"Actualités";
self.tableView.tag = 1;
// Register to notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(callback_general:) name:#"general" object:nil ];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(connection_error:) name:#"connection_error" object:nil];
self.dataSource = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark -
#pragma mark View lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self refreshNews];
}
-(void)callback_general: (NSNotification *) notification
{
if ([self.dataSource count] > 0) {
NSUInteger i, count = [self.dataSource count];
for (i = 0; i < count; i++) {
[[self.dataSource objectAtIndex:i] release];
}
[self.dataSource removeAllObjects];
}
NSArray *receivedDatas = [[notification userInfo] objectForKey:#"data"];
NSUInteger i, count = [receivedDatas count];
for (i = 0; i < count; i++) {
self.artRec = [[ArticleRecord alloc] init];
self.artRec.art_id = [[receivedDatas objectAtIndex:i] objectForKey:#"id"];
self.artRec.art_auteur = [[receivedDatas objectAtIndex:i] objectForKey:#"auteur"];
self.artRec.art_categorie = [[receivedDatas objectAtIndex:i] objectForKey:#"categorie"];
self.artRec.art_date = [[receivedDatas objectAtIndex:i] objectForKey:#"date"];
//self.artRec.art_texte = [[receivedDatas objectAtIndex:i] objectForKey:#"texte"];
self.artRec.art_titre = [[receivedDatas objectAtIndex:i] objectForKey:#"titre"];
self.artRec.art_url_auteur = [[receivedDatas objectAtIndex:i] objectForKey:#"url_auteur"];
self.artRec.art_url = [[receivedDatas objectAtIndex:i] objectForKey:#"url"];
self.artRec.art_url_img = [[receivedDatas objectAtIndex:i] objectForKey:#"image"];
[self.dataSource addObject:self.artRec];
self.artRec = nil;
}
[self.tableView reloadData];
}
Finally here is how I add these TableViews in the TabBar:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 0
//articles
ActualiteTVC *actualiteTVC = [[ActualiteTVC alloc] init];
UINavigationController *actualiteNC = [[UINavigationController alloc] initWithRootViewController:actualiteTVC];
[actualiteTVC release];
actualiteNC.tabBarItem.title = #"Actualités";
actualiteNC.tabBarItem.image = [UIImage imageNamed:#"08-chat.png"];
[actualiteNC.navigationBar setBarStyle:UIBarStyleBlack];
//1
//blogs
BlogsTVC *blogsTVC = [[BlogsTVC alloc] init];
UINavigationController *blogsNC = [[UINavigationController alloc] initWithRootViewController:blogsTVC];
[blogsTVC release];
blogsNC.tabBarItem.title = #"Blogs";
blogsNC.tabBarItem.image = [UIImage imageNamed:#"balance.png"];
[blogsNC.navigationBar setBarStyle:UIBarStyleBlack];
// myTabBarController
myTabBarController = [[UITabBarController alloc] init];
[myTabBarController setViewControllers:[NSArray arrayWithObjects:actualiteNC, blogsNC, nil]];
[actualiteNC release];
[blogsNC release];
/*
//fullscreen
CGRect frame = [[UIScreen mainScreen] applicationFrame];
frame.origin.x = 0;
frame.origin.y = 25;
//[baseViewCtrl.view setFrame:frame];
[myTabBarController.view setFrame:frame];
*/
/*
// window
//[window addSubview:myTabBarController.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleRemoveLoading:) name:#"removeLoading" object:nil];
loading = [[LoadingVC alloc] init];
[window addSubview:loading.view];
*/
[window addSubview:baseViewCtrl.view];
[window makeKeyAndVisible];
return YES;
}