I'm making a Card game and trying to call UIImages from an object's instance variable to update a UIImageView
I have a Deck object, which has an NSArray instance variable of Card objects.
Each Card object has a few instance variables, one of which is an UIImage that I'm trying to display in a UIImageView....and this is where I'm having a problem
The storyboard isn't displaying the UIImageView and i'm not getting any compile errors
The UIImageView that I'm trying to update is cardDisplay (ViewController.h)
Here's some snippets from my code
ViewController.h
#import "Deck.h"
#import "Card.h"
#interface ViewController : UIViewController
{
UIImageView *cardDisplay;
}
#property (nonatomic, retain) IBOutlet UIImageView *cardDisplay;
#end
ViewController.m
#import "ViewController.h"
#import "Deck.h"
#import "Card.h"
#implementation ViewController
#synthesize cardDisplay;
- (void)viewDidLoad
{
[super viewDidLoad];
Deck *deck = [[Deck alloc]init];
NSLog(#"%#", deck);
for (id cards in deck.cards) {
NSLog(#"%#", cards);
}
self.cardDisplay = [[UIImageView alloc] initWithImage:
[[deck.cards objectAtIndex:0 ] cardImage]];
}
#end
Card.h
#interface Card : NSObject
{
NSString *valueAsString, *suitAsString;
NSInteger faceValue, countValue;
Suit suit;
UIImage *cardImage;
}
#property (nonatomic, retain) NSString *valueAsString;
#property (nonatomic, retain) NSString *suitAsString;
#property (nonatomic) NSInteger faceValue;
#property (nonatomic) NSInteger countValue;
#property (nonatomic) Suit suit;
#property (nonatomic) UIImage *cardImage;
- (id) initWithFaceValue:(NSInteger)aFaceValue countValue:(NSInteger)aCountValue
suit:(Suit)aSuit cardImage:(UIImage*)aCardImage;
#end
Deck.h
#import "Card.h"
#interface Deck : NSObject
{
NSMutableArray *cards;
}
#property(nonatomic, retain)NSMutableArray *cards;
#end
Deck.m
#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++)
{
if (face > 1 && face < 7)
aCount = 1;
else if (face > 6 && face < 10)
aCount = 0;
else
aCount = -1;
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *imagePath = [path stringByAppendingPathComponent:
[NSString stringWithFormat:#"/cards/card_%d.png",picNum]];
UIImage *output = [UIImage imageNamed:imagePath];
Card *card = [[Card alloc] initWithFaceValue:(NSInteger)face
countValue:(NSInteger)aCount
suit:(Suit)suit
cardImage:(UIImage *)output];
[cards addObject:card];
}
}
}
return self;
}
#end
This line:
self.cardDisplay = [[UIImageView alloc] initWithImage:
[[deck.cards objectAtIndex:0 ] cardImage]];
should be:
self.cardDisplay.image = [[deck.cards objectAtIndex:0 ] cardImage];
You need to set the image on the image view you created in IB, not create a new one. Doing it this way doesn't keep you from doing what you want with the timer later.
Related
[__NSArrayM insertObject:atIndex:]: object cannot be nil
The problem is when trying to execute [_eventsArray addObject:eventModel]; error is occurred.
eventModel is nil.
How can I solve this problem ?
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *eventsArray;
#end
#interface EventsModel : NSObject
#property(nonatomic, assign) NSString *title;
#property(nonatomic, strong) NSString *details;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
EventsModel *eventModel ;
eventModel.title = #"Meeting";
eventModel.details = #"some description";
[_eventsArray addObject:eventModel];
}
#end
#pragma mark - Model Class
#implementation EventsModel
-(instancetype)init{
self = [super init];
if (self) {
self.title = nil;
self.details =nil;
}
return self;
}
#end
EventsModel *model = [EventsModel new];
model.title = #"test";
model.details = #"Detail test";
EventsModel *model2 = [EventsModel new];
model2.title = #"test2";
model2.details = #"Detail test2";
[_eventsArray addObject:model];
[_eventsArray addObject:model2];
NSLog(#"%lu elements in array",(unsigned long)_eventsArray.count);
you use EventsModel *model = [EvenntsModel new]; and create object
try this code
I am trying to share images via UIActivityViewController similar to this. However if I share several images, Twitter and Facebook will disappear in the UIActivityViewController.
Is there a way to share one image for both Twitter and Facebook, several images for mail as attachment?
EDIT:
// return different string depends on the type
CustomActivityItemProvider *textProvider = [[CustomActivityItemProvider alloc] initWithText:textContent url:url title:textTitle];
NSMutableArray *applicationActivities = [NSMutableArray array];
NSMutableArray *activityItems = [#[
textProvider,
image,
url
] mutableCopy];
// custom applicationActivities
...
// If add multiple images, facebook and twitter will not show up
for(int i = 0; i < [images count]; ++i)
{
if(images[i] != image) [activityItems addObject:images[i]];
}
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:activityItems
applicationActivities:applicationActivities];
[activityController setValue:textTitle forKey:#"subject"];
activityController.excludedActivityTypes = excludeActivities;
[self presentViewController:activityController animated:YES completion:nil];
Is there a way similar to the UIActivityItemProvider?
A similar way to textActivityItemProvider I've end up using:
ImageActivityItemProvider.h
#import <UIKit/UIKit.h>
#interface ImageActivityItemProvider : UIActivityItemProvider
#property (nonatomic, strong, readonly) UIImage *image;
#property (nonatomic, readonly) NSInteger index;
#property (nonatomic, readonly) NSInteger shouldShowIndex;
- (instancetype)initWithImage:(UIImage*)image index:(NSInteger)index shouldShowIndex:(NSInteger)shouldShowIndex;
#end
ImageActivityItemProvider.m
#import "ImageActivityItemProvider.h"
#interface ImageActivityItemProvider ()
#property (nonatomic, strong) UIImage *image;
#property (nonatomic) NSInteger index;
#property (nonatomic) NSInteger shouldShowIndex;
#end
#implementation ImageActivityItemProvider
- (instancetype)initWithImage:(UIImage*)image index:(NSInteger)index shouldShowIndex:(NSInteger)shouldShowIndex
{
// make sure the placeholder is nil instead of the image
self = [super initWithPlaceholderItem:nil];
if (self)
{
self.image = image;
self.index = index;
self.shouldShowIndex = shouldShowIndex;
}
return self;
}
- (id)item
{
if (
[self.activityType isEqualToString:UIActivityTypeMail] ||
self.index == self.shouldShowIndex
)
{
return self.image;
}
return self.placeholderItem;
}
#end
Please help....I'm losing my mind trying to figure out this problem.
I'm fairly new to iOS so don't go too hard on me if it's something obvious! ;)
I'm using xcode 4.6 and targeting iPhone6.1 Simulator.
I get the following error when starting up my app:
EXC_BAD_ACCESS code = 2
There are hundres of threads appearing in Debug Navigator which leads to to believe there is some sort of infinite loop somewhere (I just cannot see where).
The error occurs beside (id)init in PlayingCardDeck.m after entering it from ViewController.m at line:
Card *card = [self.deck drawRandonCard];
ViewConrtoller:
#import "ViewController.h"
#import "PlayingCardDeck.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *flipsLabel;
#property (nonatomic) int flipCount;
#property (strong, nonatomic) Deck *deck;
#property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;
#end
#implementation ViewController
#synthesize deck = _deck;
- (IBAction)flipCard:(UIButton *)sender {
sender.selected = !sender.isSelected;
self.flipCount++;
}
- (void)setFlipCount:(int)flipCount
{
_flipCount = flipCount;
self.flipsLabel.text = [NSString stringWithFormat:#"Flips: %d", self.flipCount];
}
- (Deck *)deck
{
if (!_deck) _deck = [[PlayingCardDeck alloc] init];
return _deck;
}
- (void)setCardButtons:(NSArray *)cardButtons
{
_cardButtons = cardButtons;
for (UIButton *cardButton in cardButtons)
{
Card *card = [self.deck drawRandonCard];
[cardButton setTitle:card.contents forState:UIControlStateSelected];
}
}
#end
Deck.m
#import "Deck.h"
#interface Deck()
#property (strong, nonatomic) NSMutableArray *cards;
#end
#implementation Deck
- (NSMutableArray *)cards
{
if (!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}
- (void)addCard:(Card *)card atTop:(BOOL)atTop
{
if (atTop)
{
[self.cards insertObject:card atIndex:0];
}
else
{
[self.cards addObject:card];
}
}
- (Card *)drawRandonCard
{
Card *randomCard = nil;
if (self.cards.count)
{
unsigned index = arc4random() % self.cards.count;
randomCard = self.cards[index];
[self.cards removeObjectAtIndex:index];
}
return randomCard;
}
#end
PlayingCardDeck.m
#import "PlayingCardDeck.h"
#import "PlayingCard.h"
#implementation PlayingCardDeck
- (id)init
{
self = [self init];
if (self)
{
for (NSString *suit in [PlayingCard validSuits])
{
for (NSUInteger rank=1; rank <= [PlayingCard maxRank]; rank++)
{
PlayingCard *card = [[PlayingCard alloc] init];
card.suit = suit;
card.rank = rank;
[self addCard:card atTop:YES];
}
}
}
return self;
}
#end
In PlayerCardDeck.m self = [self init] should be self = [super init]. That's causing the infinite loop.
I'm trying to write a calculator program, but I'm running into this error when pressing a particular key that is linked to the function expressionEvaluation. My calculator works fine, but I am trying to add in the ability to use/store variables. For this, I use the expressionEvaluation button. However, as soon as I press the button linked to that method, the whole app crashes, and xcode gives me the error EXC_BAD_ACCESS code=2. I'm new to objective-c, so I'm not sure how to debug this error. As far as I can tell, though, the issue is with the line
double result = [CalculatorBrain evaluateExpression:self.brain.expression usingVariableValues:testValues];
...in my view controller. I set a break point before this line and it didn't crash, but setting it at this line resulted in the crash I'm experiencing.
I tried to cut the code down below, and have included only the things directly linked to the expressionEvaluation button. Thank you for your help!
Here's the .h for my brain method:
// CalculatorBrain.h
#import <Foundation/Foundation.h>
#interface CalculatorBrain : NSObject
- (void) pushOperand:(double)operand;
- (void) setVariableAsOperand:(NSString *)variableName;
- (void) performWaitingOperation;
- (double) performOperation:(NSString *)operation;
#property (readonly) id expression;
+ (double)evaluateExpression: (id)anExpression
usingVariableValues: (NSDictionary *)variables;
+ (NSSet *)variablesInExpression:(id)anExpression;
+ (NSString *)descriptionOfExpression:(id)anExpression;
+ (id)propertyListForExpression:(id)anExpression;
+ (id)expressionForPropertyList:(id)propertyList;
#end
Here's the .m:
// CalculatorBrain.m
#import "CalculatorBrain.h"
#define VARIABLE_PREFIX #"^"
#interface CalculatorBrain()
#property (nonatomic) double operand;
#property (nonatomic, strong) NSString *waitingOperation;
#property (nonatomic) double waitingOperand;
#property (nonatomic) double storedOperand;
#property (nonatomic) NSMutableArray *internalExpression;
#end
#implementation CalculatorBrain
#synthesize operand = _operand; //operand in use
#synthesize waitingOperation = _waitingOperation; //waiting to be computed
#synthesize waitingOperand = _waitingOperand; //waiting to be used
#synthesize storedOperand = _storedOperand; //stored in memory
#synthesize internalExpression = _internalExpression; //private expression stored
#synthesize expression = _expression;
- (id) expression {;
return [NSMutableArray arrayWithArray:self.internalExpression];
}
//here I have instance methods that add objects to the array internalExpression
//these work fine as far as I can tell
+ (double) evaluateExpression:(id)anExpression usingVariableValues:(NSDictionary *)variables {
double result = 0;
int count = [anExpression count];
CalculatorBrain *brain;
for (int i = 0; i < count; i++) {
if([[anExpression objectAtIndex:i] isKindOfClass:[NSNumber class]]) {
double operand = [[anExpression objectAtIndex:i] doubleValue];
[brain pushOperand:operand];
}
if([[anExpression objectAtIndex:i] isKindOfClass:[NSString class]]) {
NSString *string = [anExpression objectAtIndex:i];
if([string characterAtIndex:0] == '^') {
NSString* variable = [NSString stringWithFormat:#"%c",[string characterAtIndex:1]];
double valueOfVariable = [[variables objectForKey:variable] doubleValue];
[brain pushOperand:valueOfVariable];
}
else {
NSString* operator = [anExpression objectAtIndex:i];
result = [brain performOperation:operator];
}
}
}
return result;
}
#end
Here's the .h for my view controller:
// CalcViewController.h
#import <UIKit/UIKit.h>
//view controller for calculator
#interface CalcViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *display; //real-time display
#property (strong, nonatomic) IBOutlet UILabel *miniDisplay; //past display
#property (strong, nonatomic) IBOutlet UILabel *memDisplay; //display stored digits
- (IBAction)digitPressed:(UIButton *)sender; //pressed number
- (IBAction)operandPressed:(UIButton *)sender; //pressed operation
- (IBAction)variablePressed:(UIButton *)sender; //pressed variable
- (IBAction)expressionEvaluation:(UIButton *)sender; //evaluate expression with variables
#end
Here's the .m:
// CalcViewController.m
#import "CalcViewController.h"
#import "CalculatorBrain.h"
#interface CalcViewController ()
#property (nonatomic, strong) CalculatorBrain *brain;
#property (nonatomic) BOOL userIsInTheMiddleOfTypingANumber;
#end
#implementation CalcViewController
- (CalculatorBrain *) brain {
if (!_brain) _brain = [[CalculatorBrain alloc] init];
return _brain;
}
- (IBAction)expressionEvaluation:(UIButton *)sender {
NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:#"x", 2, #"y", 3, #"z", 4, nil];
double result = [CalculatorBrain evaluateExpression:self.brain.expression usingVariableValues:testValues];
NSString *resultString = [NSString stringWithFormat:#"%g", result];
self.display.text = resultString;
}
#end
EDIT: Just as a side note, I am not getting any errors, only one warning: incomplete implementation. This is because I haven't finished a couple class methods yet, but I don't think it is causing the crash.
NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:#"x", 2, #"y", 3, #"z", 4, nil];
turned out to be the erroneous line. It should have been:
NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:#"x", [NSNumber numberWithInt:2], #"y", [NSNumber numberWithInt:3], #"z", [NSNumber numberWithInt:4], nil];
Thanks to everyone who helped!
You will get more information on the code line raising the exception by adding an exception breakpoint in xCode.
I have gone through a few tutorials including the sample app included
with Three20 and cannot figure out why photos aren't showing up in my
TTPhotoViewController. I actually find it pretty hard to debug.
Below is the code I have. Any thoughts on why images will not load
and how to debug it would be great. I get a completely black view in
between my bottom tabbar and upper nav bar. I also see left and right
arrows overlayed on the black view which seems to be for navigating
photos although I thought it was supposed to display a thumbnail
gallery.
// A TTPhoto class
// Photo.h
#import <Foundation/Foundation.h>
#import <Three20/Three20.h>
#interface Photo : NSObject <TTPhoto> {
NSString *_caption;
NSString *_urlLarge;
NSString *_urlSmall;
NSString *_urlThumb;
id <TTPhotoSource> _photoSource;
CGSize _size;
NSInteger _index;
}
#property (nonatomic, copy) NSString *caption;
#property (nonatomic, copy) NSString *urlLarge;
#property (nonatomic, copy) NSString *urlSmall;
#property (nonatomic, copy) NSString *urlThumb;
#property (nonatomic, assign) id <TTPhotoSource> photoSource;
#property (nonatomic) CGSize size;
#property (nonatomic) NSInteger index;
- (id)initWithCaption:(NSString *)caption urlLarge:(NSString
*)urlLarge urlSmall:(NSString *)urlSmall urlThumb:(NSString *)urlThumb
size:(CGSize)size;
#end
// Photo.m
#import "Photo.h"
#implementation Photo
#synthesize caption = _caption;
#synthesize urlLarge = _urlLarge;
#synthesize urlSmall = _urlSmall;
#synthesize urlThumb = _urlThumb;
#synthesize photoSource = _photoSource;
#synthesize size = _size;
#synthesize index = _index;
- (id)initWithCaption:(NSString *)caption urlLarge:(NSString
*)urlLarge urlSmall:(NSString *)urlSmall urlThumb:(NSString *)urlThumb
size:(CGSize)size {
if ((self = [super init])) {
self.caption = caption;
self.urlLarge = urlLarge;
self.urlSmall = urlSmall;
self.urlThumb = urlThumb;
self.size = size;
self.index = NSIntegerMax;
self.photoSource = nil;
}
return self;
}
- (void) dealloc {
self.caption = nil;
self.urlLarge = nil;
self.urlSmall = nil;
self.urlThumb = nil;
[super dealloc];
}
#pragma mark TTPhoto
- (NSString*)URLForVersion:(TTPhotoVersion)version {
switch (version) {
case TTPhotoVersionLarge:
return _urlLarge;
case TTPhotoVersionMedium:
return _urlLarge;
case TTPhotoVersionSmall:
return _urlSmall;
case TTPhotoVersionThumbnail:
return _urlThumb;
default:
return nil;
}
}
#end
// A TTPhotoSource class
// PhotoSet.h
#import <Foundation/Foundation.h>
#import "Three20/Three20.h"
#interface PhotoSet : TTURLRequestModel <TTPhotoSource> {
NSString *_title;
NSArray *_photos;
NSArray* _tempPhotos;
NSTimer* _fakeLoadTimer;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, retain) NSArray *photos;
- (id) init;
#end
// PhotoSet.m
#import "PhotoSet.h"
#import "Photo.h"
#implementation PhotoSet
#synthesize title = _title;
#synthesize photos = _photos;
- (id) init {
_title = #"Test photo album";
_photos = [[NSArray alloc] initWithObjects:
[[[Photo alloc] initWithCaption:#"coming soon"
urlLarge:#"http://farm5.static.flickr.com/
4066/4653156849_0905e6b58e_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4066/4653156849_0d15f0e3f0_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4066/4653156849_0d15f0e3f0_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
[[[Photo alloc] initWithCaption:#"coming soon 2"
urlLarge:#"http://farm5.static.flickr.com/
4023/4653774402_05e6acd995_o.jpg"
urlSmall:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
urlThumb:#"http://farm5.static.flickr.com/
4009/4653157237_c2f5f59e0d_s.jpg"
size:CGSizeMake(220, 112)] autorelease],
nil];
for (int i = 0; i < _photos.count; ++i) {
id<TTPhoto> photo = [_photos objectAtIndex:i];
if ((NSNull*)photo != [NSNull null]) {
NSLog(#"in here 65434");
photo.photoSource = self;
photo.index = i;
}
}
return self;
}
- (void) dealloc {
self.title = nil;
self.photos = nil;
[super dealloc];
}
#pragma mark TTModel
- (BOOL)isLoading {
return NO;
}
- (BOOL)isLoaded {
return YES;
}
#pragma mark TTPhotoSource
- (NSInteger)numberOfPhotos {
return _photos.count;
}
- (NSInteger)maxPhotoIndex {
return _photos.count-1;
}
- (id<TTPhoto>)photoAtIndex:(NSInteger)photoIndex {
if (photoIndex < _photos.count) {
return [_photos objectAtIndex:photoIndex];
} else {
return nil;
}
}
#end
// A TTPhotoViewController
// EventDetailViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <Three20/Three20.h>
#import "PhotoSet.h"
#class Event;
#interface EventDetailViewController :
TTPhotoViewController<UINavigationControllerDelegate,
UIImagePickerControllerDelegate> {
NSArray *photos;
Event *event;
PhotoSet *_photoSet;
}
#property (nonatomic, retain) NSArray *photos;
#property (nonatomic, retain) Event *event;
#property (nonatomic, retain) PhotoSet *photoSet;
- (id)initWithEvent:(Event *)e;
// EventDetailViewController.m
#import "EventDetailViewController.h"
#import "Event.h"
#import "PhotoSet.h"
#import "Photo.h"
#implementation EventDetailViewController
#synthesize photos;
#synthesize event;
#synthesize photoSet = _photoSet;
#pragma mark -
#pragma mark Initialization
- (void)viewDidLoad {
self.photoSet = [[PhotoSet alloc] init];
self.photoSource = self.photoSet;
}
- (id)initWithEvent:(Event *)e {
if (self) {
self.event = e;
}
return self;
}
#end
You may find an answer here: http://www.raywenderlich.com/1430/how-to-use-the-three20-photo-viewer