I'm trying to access an UIImage instance variable and display it in UIImageView. When I try to NSLog the path I get null. I can manually display a pic through the IB, but I want to do this strictly through code
#import "Deck.h"
#import "Card.h"
#implementation Deck
#synthesize cards;
- (id) init
{
if(self = [super init])
{
cards = [[NSMutableArray alloc] init];
NSInteger aCount, picNum = 0;
for(int suit = 0; suit < 4; suit++)
{
for(int face = 1; face < 14; face++, picNum++)
{
NSString *fileName = [NSString stringWithFormat:#"card_%d", picNum];
NSString *path = [[NSBundle mainBundle] pathForResource:fileName
ofType:#"png"inDirectory:#"/cards"];
NSLog(#"%#", path); //outputs correctly
UIImage *output = [UIImage imageNamed:path];
NSLog(#"%#", output); //outputs null
Card *card = [[Card alloc] initWithFaceValue:(NSInteger)face
countValue:(NSInteger)aCount
suit:(Suit)suit
cardImage:(UIImage *)output];
[cards addObject:card];
}
}
}
return self;
}
I've added a link to show where the pics are found
Link
You don't have to include all the path to the image, if you just put the name, Xcode will automatically look for it.
Related
I would like to call a method that rotates a sprite when a particular frame in displayed. I got a few ideas from this post but I am having issues as to how I should implement it. How would I define my dictionary for accessing 3rd frame and link it to the selector? Below is what I've done. Please note that it's work-in-progress.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
CCSpriteBatchNode* batchNode;
CCSpriteFrameCache* frameCache;
frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
[frameCache addSpriteFramesWithFile:#"cat-hd.plist"];
batchNode = [CCSpriteBatchNode batchNodeWithFile:#"cat-hd.pvr.ccz"];
[self addChild:batchNode];
CCSprite* wallbg = [CCSprite spriteWithSpriteFrameName:#"firstBg.png"];
wallbg.position= ccp(240.0, 160.0);
//wallbg.anchorPoint = ccp(0.5, 0.5);
[batchNode addChild:wallbg];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(rotateAnimationFrame:) name:CCAnimationFrameDisplayedNotification object:nil];
NSMutableArray* catAnimationArray = [[NSMutableArray alloc]init];
for(int i = 1; i < 7; i++) // i< number of frames in the plist File Name
{
CCLOG(#"item %d added", i);
[catAnimationArray addObject:
[frameCache spriteFrameByName:
[NSString stringWithFormat:#"blackCat%d.png", i]]]; }
CCSprite* catSprite = [CCSprite spriteWithSpriteFrameName: #"blackCat1.png"];
CGSize screenSize = [[CCDirector sharedDirector] winSize];
catSprite.position = ccp(screenSize.width/2, screenSize.height/2);
CCAnimation *animation = [CCAnimation animationWithSpriteFrames:catAnimationArray delay:0.3];
CCAnimationFrame* thirdFrame = [animation.frames objectAtIndex:2];
NSDictionary* uInfo = //how should I define my dictionary?
id action =[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation :animation]];
[catSprite runAction:action];
[batchNode addChild:catSprite];
}
return self;
}
// on "dealloc" you need to release all your retained objects
-(void)rotateAnimationFrame:(NSNotification*)notification {
NSDictionary *userInfoDictionary = [notification userInfo];
if ([[notification name] isEqualToString:#"CCAnimationFrameDisplayedNotification"]) {
CCSprite* thirdAnim = [CCSprite spriteWithSpriteFrame:#"blackCat3.png"];
CCRotateTo *rotateRight = [CCRotateBy actionWithDuration:0.2 angle:40.0];
[thirdAnim runAction:rotateRight];
}
I have a problem with the PIn color mapView when a refresh is done.
In my I app i display some point with two color in order to identify if a service is available.
On the first start, no problems appear. The code is the follower:
- (void)viewDidLoad
{
[super viewDidLoad];
[self dowloadPoint]; // here I exucte the first start
}
- (void)dowloadPoint{
NSURL *url1 =[NSURL URLWithString:#"http:MYUSRL"];
NSData *datos1 =[[NSData alloc] initWithContentsOfURL:url1];
[self plotBarPosition:datos_string1]; //Here I call the plotBarPosition method
}
- (void)plotBarPosition:(NSString *)datos_string1 {
for (id<MKAnnotation> annotation in _mapView.annotations) {
[_mapView removeAnnotation:annotation];
}
// Parse the string into JSON
NSDictionary *json = [(NSDictionary*)[datos_string1 JSONValue]objectForKey:#"features"];
// Get the objects you want, e.g. output the second item's client id
NSArray *items_properties = [json valueForKeyPath:#"properties"];
NSArray *items_geo = [json valueForKeyPath:#"geometry"];
for (int i = 0; i < [json count]; i++){
NSString *nomprePunto =[[items_properties objectAtIndex:i] objectForKey:#"title"];
NSNumber *lat =[[[items_geo objectAtIndex:i] objectForKey:#"coordinates"] objectAtIndex:0];
NSNumber *lon =[[[items_geo objectAtIndex:i] objectForKey:#"coordinates"] objectAtIndex:1];
CLLocationCoordinate2D coordinate;
coordinate.latitude = lat.doubleValue;
coordinate.longitude = lon.doubleValue;
//ESTADO
NSString *description = [[items_properties objectAtIndex:i] objectForKey:#"description"];
NSString *estado_punto = [[NSString alloc]init];
if ([description rangeOfString:#"Averiado"].location == NSNotFound) {
estado_punto = #"Available";
} else {
estado_punto = #"NOt Available";
averiados ++;
}
NSString *averiadosStr = [NSString stringWithFormat:#"%d",averiados];
averiadosLabel.text = averiadosStr;
MyLocation *location =[[MyLocation alloc] initWithName:nomprePunto coordinate:coordinate estado:estado_punto];
[_mapView addAnnotation:location];
}
}
- (MKPinAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(MyLocation *)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
if([[annotation estado] isEqualToString:#"En Servicio"])
annotationView.pinColor = MKPinAnnotationColorGreen;
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
But whe I add a refres button that is function is simply a refreshcalling the dowloadPoint once again,
- (IBAction)refresh{
[self dowloadPoint];
}
the color of pins change in a "random manner", not corrisponding with the real state of point.
Any ideas about what is happening? Thanks in advance.
EDIT: It seemps pproblems is due to:
for (id<MKAnnotation> annotation in _mapView.annotations) {
[_mapView removeAnnotation:annotation];
}
erasing it, the app work properly but pins area drown abow the previous ones...:S
The default color of the pin is red. You set it to green if the estado property of your MyLocation object is equal to #"En Servicio". I understand that sometimes the color is red, when your estado property is equal to #"En Servicio", or sometimes green when it is not.
One reason could be that your MyLocation object simply does no longer exist when you press the refresh button. In this case, you might still have a pointer to the memory location where it once existed, but this location may have been overwritten by anything, causing a random color.
This can happen e.g. if your MyLocation object has been created as an autorelease object that has been released when you returned to the main event loop, i.e. to handle user interactions.
This should not be the case if you are using ARC.
I have a folder of png's called "cards" in Supporting Files. I'm trying to set a pic as a UIImage instance variable for a object. When i try to NSLog the UIImage i get null.
I don't think I'm accessing the path to the pics correctly, but not sure ????
#import "Deck.h"
#import "Card.h"
#implementation Deck
#synthesize cards;
- (id) init
{
if(self = [super init])
{
cards = [[NSMutableArray alloc] init];
NSInteger aCount, picNum = 0;
for(int suit = 0; suit < 4; suit++)
{
for(int face = 1; face < 14; face++, picNum++)
{
//NSString *path = [[NSBundle mainBundle] bundlePath];
//NSString *imagePath = [path stringByAppendingPathComponent: [NSString stringWithFormat:#"/cards/card_%d.png",picNum]];
NSString *fileName = [NSString stringWithFormat:#"card_%d", picNum];
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:#"png"inDirectory:#"/cards"];
NSLog(#"%#", path);
UIImage *output = [UIImage imageNamed:path];
//NSLog(#"%#", output);
Card *card = [[Card alloc] initWithFaceValue:(NSInteger)face
countValue:(NSInteger)aCount
suit:(Suit)suit
cardImage:(UIImage *)output];
[cards addObject:card];
}
}
}
return self;
}
}
#end
The conceptually better approach would be to use the method of NSBundle which was specifically designed for working with subdirectories:
NSString *fileName = [NSString stringWithFormat:#"card_%d", picNum];
NSString *path = [[NSBundle mainBundle] pathForResource:fileName
ofType:#"png"
inDirectory:#"cards"];
This one has been doing my head in for months - So time to swallow my pride and reach out for a little help. At the moment this is being done in UIWebView as HTML5/JS controlled system. But UIWebview frankly sux and looking to make this last component native too.
I have a collection of videos and at specific timed points during the video, I am calling a page of instructions that relate to the timed period in the video. The video controls also act as a controller for the instructions pages. So whatever timed point is reached, the corresponding page is animated into place.
I've looked in many, many options, with the closest coming in with http video streaming and using timed metadata to initiate a view, but I am containing the videos locally on the device. And, as yet cannot find anything that looks like it will work. Seems simple enough in principle, but I'll be damned if I can find a decent solution...
Any ideas / pointers?
Here's the last attempt at going native with this before the remainder of my hair fell out - I think I may be seeing where I was heading in the wrong direction, but if you can spare a few moments, I'd really appreciate it!
OBJECTIVE is to have a shoutOut that lives below the video that contains a page of instructions. At x seconds, the content will be refreshed to correspond to that portion of the video and persist until the next shoutOut for fresh content. This I have managed to achieve successfully. Where I have been falling down (a lot) is when I scrub the video back to a previous section, the shoutOut content remains at the position from which I scrubbed and remains there permanently. Or as the code is below, simply doesn't re-apear as it is set to a timed visible duration.
Anyway, here's the code...
Header:
// START:import
#import <UIKit/UIKit.h>
// START_HIGHLIGHT
#import <MediaPlayer/MPMoviePlayerController.h>
#import "CommentView.h"
// END_HIGHLIGHT
// START:def
// START:wiring
#interface MoviePlayerViewController : UIViewController {
UIView *viewForMovie;
// END:wiring
// START_HIGHLIGHT
MPMoviePlayerController *player;
// END_HIGHLIGHT
// START:wiring
UILabel *onScreenDisplayLabel;
UIScrollView *myScrollView;
NSMutableArray *keyframeTimes;
NSArray *shoutOutTexts;
NSArray *shoutOutTimes;
}
#property (nonatomic, retain) IBOutlet UIView *viewForMovie;
// END:wiring
// START_HIGHLIGHT
#property (nonatomic, retain) MPMoviePlayerController *player;
// END_HIGHLIGHT
#property (nonatomic, retain) IBOutlet UILabel *onScreenDisplayLabel;
#property (nonatomic, retain) IBOutlet UIScrollView *myScrollView;
#property (nonatomic, retain) NSMutableArray *keyframeTimes;
// START_HIGHLIGHT
-(NSURL *)movieURL;
- (void)timerAction:(NSTimer*)theTimer;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification;
- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer;
- (IBAction) getInfo:(id)sender;
- (void)removeView:(NSTimer*)theTimer;
// END_HIGHLIGHT
// START:wiring
#end
// END:def
// END:wiring
// END:import
Main:
#implementation MoviePlayerViewController
// START:synth
#synthesize player;
#synthesize viewForMovie;
#synthesize onScreenDisplayLabel;
#synthesize myScrollView;
#synthesize keyframeTimes;
// END:synth
// Implement loadView to create a view hierarchy programmatically, without using a nib.
// START:viewDidLoad
// START:viewDidLoad1
- (void)viewDidLoad {
[super viewDidLoad];
keyframeTimes = [[NSMutableArray alloc] init];
shoutOutTexts = [[NSArray
arrayWithObjects:#"This is a test\nLabel at 2 secs ",
#"This is a test\nLabel at 325 secs",
nil] retain];
shoutOutTimes = [[NSArray
arrayWithObjects:[[NSNumber alloc] initWithInt: 2],
[[NSNumber alloc] initWithInt: 325],
nil] retain];
self.player = [[MPMoviePlayerController alloc] init];
self.player.contentURL = [self movieURL];
// END:viewDidLoad1
self.player.view.frame = self.viewForMovie.bounds;
self.player.view.autoresizingMask =
UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight;
[self.viewForMovie addSubview:player.view];
[self.player play];
// START_HIGHLIGHT
[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(timerAction:) userInfo:nil repeats:YES];
// END_HIGHLIGHT
// START:viewDidLoad1
[self.view addSubview:self.myScrollView];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieDurationAvailable:)
name:MPMovieDurationAvailableNotification
object:nil];
}
// END:viewDidLoad
// END:viewDidLoad1
// START:movieURL
-(NSURL *)movieURL
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *moviePath =
[bundle
pathForResource:#"BigBuckBunny_640x360"
ofType:#"m4v"];
if (moviePath) {
return [NSURL fileURLWithPath:moviePath];
} else {
return nil;
}
}
// END:movieURL
int position = 0;
- (void)timerAction:(NSTimer*)theTimer {
NSLog(#"hi");
int count = [shoutOutTimes count];
NSLog(#"count is at %d", count);
if (position < count) {
NSNumber *timeObj = [shoutOutTimes objectAtIndex:position];
int time = [timeObj intValue];
NSLog(#"time is at %d", time);
if (self.player.currentPlaybackTime >= time) {
CommentView *cview = [[CommentView alloc]
initWithText:[shoutOutTexts objectAtIndex:position]];
[self.player.view addSubview:cview];
position++;
[NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:#selector(removeView:) userInfo:cview repeats:NO];
}
}
}
- (void)removeView:(NSTimer*)theTimer {
UIView *view = [theTimer userInfo];
[view removeFromSuperview];
}
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
- (void) movieDurationAvailable:(NSNotification*)notification {
MPMoviePlayerController *moviePlayer = [notification object];
int duration = [moviePlayer duration];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(playerThumbnailImageRequestDidFinish:)
name:MPMoviePlayerThumbnailImageRequestDidFinishNotification
object:nil];
NSMutableArray *times = [[NSMutableArray alloc] init];
for(int i = 0; i < 20; i++) {
[times addObject:[NSNumber numberWithInt:5+i*((duration)/20)]];
}
[self.player requestThumbnailImagesAtTimes:times timeOption: MPMovieTimeOptionNearestKeyFrame];
}
int p = 0;
int ll=0;
- (void) playerThumbnailImageRequestDidFinish:(NSNotification*)notification {
NSDictionary *userInfo;
userInfo = [notification userInfo];
NSNumber *timecode;
timecode = [userInfo objectForKey: #"MPMoviePlayerThumbnailTimeKey"];
[keyframeTimes addObject: timecode];
UIImage *image;
image = [userInfo objectForKey: #"MPMoviePlayerThumbnailImageKey"];
int width = image.size.width;
int height = image.size.height;
float newwidth = 75 * ((float)width / (float)height);
self.myScrollView.contentSize = CGSizeMake((newwidth + 2) * 20, 75);
UIImageView *imgv = [[UIImageView alloc] initWithImage:image];
[imgv setUserInteractionEnabled:YES];
[imgv setFrame:CGRectMake(ll, 0, newwidth, 75.0f)];
ll+=newwidth + 2;
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:#selector(handleTapFrom:)];
[tapRecognizer setNumberOfTapsRequired:1];
[imgv addGestureRecognizer:tapRecognizer];
[tapRecognizer release];
[myScrollView addSubview:imgv];
}
- (void) getInfo:(id)sender
{
MPMovieMediaTypeMask mask = self.player.movieMediaTypes;
NSMutableString *mediaTypes = [[NSMutableString alloc] init];
if (mask == MPMovieMediaTypeMaskNone) {
[mediaTypes appendString:#"Unknown Media Type"];
} else {
if (mask & MPMovieMediaTypeMaskAudio) {
[mediaTypes appendString:#"Audio"];
}
if (mask & MPMovieMediaTypeMaskVideo) {
[mediaTypes appendString:#"Video"];
}
}
MPMovieSourceType type = self.player.movieSourceType;
NSMutableString *sourceType = [[NSMutableString alloc] initWithString:#""];
if (type == MPMovieSourceTypeUnknown) {
[sourceType appendString:#"Source Unknown"];
} else if (type == MPMovieSourceTypeFile) {
[sourceType appendString:#"File"];
} else if (type == MPMovieSourceTypeStreaming) {
[sourceType appendString:#"Streaming"];
}
CGSize size = self.player.naturalSize;
onScreenDisplayLabel.text = [NSString stringWithFormat:#"[Type: %#] [Source: %#] [Time: %.1f of %.f secs] [Playback: %.0fx] [Size: %.0fx%.0f]",
mediaTypes,
sourceType,
self.player.currentPlaybackTime,
self.player.duration,
self.player.currentPlaybackRate,
size.width,
size.height];
}
- (void)handleTapFrom:(UITapGestureRecognizer *)recognizer {
NSArray *subviews = [myScrollView subviews];
for (int i = 0; i < 20; i++) {
if (recognizer.view == [subviews objectAtIndex:i]) {
NSNumber *num = [keyframeTimes objectAtIndex:i];
self.player.currentPlaybackTime = [num intValue];
return;
}
}
}
#end
The Comment View Header:
#import <UIKit/UIKit.h>
#interface CommentView : UIView {
}
- (id)initWithFrame:(CGRect)frame andText:(NSString *) text;
- (id)initWithText:(NSString *) text;
#end
The Comment View Main:
#import "CommentView.h"
#implementation CommentView
- (id)initWithFrame:(CGRect)frame andText:(NSString *) text {
if ((self = [super initWithFrame:frame])) {
UIImage *image = [UIImage imageNamed:#"comment.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self addSubview:imageView];
CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.text = text;
label.numberOfLines = 3;
label.adjustsFontSizeToFitWidth = YES;
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
[self addSubview:label];
}
return self;
}
- (id)initWithText:(NSString *) text {
if ((self = [super init])) {
UIImage *image = [UIImage imageNamed:#"comment.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[self addSubview:imageView];
CGRect rect = CGRectMake(20, 20, 200.0f, 90.0f);
UILabel *label = [[UILabel alloc] initWithFrame:rect];
label.text = text;
label.numberOfLines = 3;
label.adjustsFontSizeToFitWidth = YES;
label.textAlignment = UITextAlignmentCenter;
label.backgroundColor = [UIColor clearColor];
[self addSubview:label];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#end
Thoughts anyone?
Cheers!
What's wrong with monitoring currentPlaybackTime at regular intervals (assuming you are using an instance that implements MPMediaPlayback for playback).
do you think is it possible add a code in an application (xcode) that allows print the screen of ipad, or send it to the mac
#import "AirPrintingViewController.h"
#implementation AirPrintingViewController
-(void)printItem {
NSString *path = [[NSBundle mainBundle] pathForResource:#"demo" ofType:#"png"];
NSData *dataFromPath = [NSData dataWithContentsOfFile:path];
UIPrintInteractionController *printController = [UIPrintInteractionController sharedPrintController];
if(printController && [UIPrintInteractionController canPrintData:dataFromPath]) {
printController.delegate = self;
UIPrintInfo *printInfo = [UIPrintInfo printInfo];
printInfo.outputType = UIPrintInfoOutputGeneral;
printInfo.jobName = [path lastPathComponent];
printInfo.duplex = UIPrintInfoDuplexLongEdge;
printController.printInfo = printInfo;
printController.showsPageRange = YES;
printController.printingItem = dataFromPath;
void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) = ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
if (!completed && error) {
NSLog(#"FAILED! due to error in domain %# with error code %u", error.domain, error.code);
}
};
[printController presentAnimated:YES completionHandler:completionHandler];
}
}
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn addTarget:self action:#selector(printItem) forControlEvents:UIControlEventTouchDown];
[btn setTitle:#"PRINT" forState:UIControlStateNormal];
btn.frame = CGRectMake(0, 100, 320, 50);
[self.view addSubview:btn];
}
#end
,
with this code I can print a file in the path, how can I print my screen instead the file already in the path?
Sure, but only from your own apps. You cannot send screenshots of other apps.