I'm working on creating a rotation of 32 names using UILabels. How would I random rotate all 32 names?
- (IBAction)buttonPressed
{
int randomInt = rand() % [nameArray count];
[nameLabel setText:[nameArray objectAtIndex:randomInt]]
}
In your .h file you must have:
IBOutlet UILabel *nameLabel;
EDIT
I built this project and here is the exact code I used:
This is the .h file:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UILabel *nameLabel;
NSArray *nameArray;
}
- (IBAction)buttonPressed;
#end
This is the .m file:
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
nameArray = [[NSArray alloc] initWithObjects:#"name1", #"name2", #"name3", #"name4", #"name5", #"name6", nil];
}
- (IBAction)buttonPressed
{
int randomInt = rand() % [nameArray count];
[nameLabel setText:[nameArray objectAtIndex:randomInt]];
}
- (void)dealloc
{
[super dealloc];
[nameArray release];
nameArray = nil;
}
#end
Make sure that both the UILabel and button actions are connected in interface builder.
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
NSMutableArray *nameArray;
NSMutableArray *textFieldArray;
UIScrollView *scrollView;
}
- (IBAction)buttonPressed;
- (void)addTextFields:(int)count;
// Random sort function for the shuffle method
int randomSort(id obj1, id obj2, void *context );
#end
#import "ViewController.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// If you want to pre load values
nameArray = [[NSMutableArray alloc] initWithObjects:#"name1", #"name2", #"name3", #"name4", #"name5", #"name6", nil];
// Initilize the array to contain all the textfields
textFieldArray = [[NSMutableArray alloc] init];
// inititlize and add the scrollview
scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
[self.view addSubview:scrollView];
// Create and add the button to randomize the fields
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setFrame:CGRectMake(self.view.frame.size.width/2 - 150, 20, 150, 50)];
[button addTarget:self action:#selector(buttonPressed) forControlEvents:UIControlEventTouchUpInside];
[button setTitle:#"Randomize" forState:UIControlStateNormal];
[scrollView addSubview:button];
// method to create any number of textfields (currently sending number of items in nameArray)
[self addTextFields:[nameArray count]];
}
- (void)addTextFields:(int)count
{
// adjust these to get the size and positions you like
#define X_POSITION 20
#define TEXT_FIELD_WIDTH 300
#define TEXT_FIELD_HEIGHT 50
// Where to place the first text field
int yPosition = 90;
for (int textFieldCount = 0; textFieldCount<count; textFieldCount++) {
//Create and add the text field
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(X_POSITION, yPosition, TEXT_FIELD_WIDTH, TEXT_FIELD_HEIGHT)];
[textField setTag:textFieldCount];
[scrollView addSubview:textField];
[textFieldArray addObject:textField];
[textField setText:[nameArray objectAtIndex:textFieldCount]];
// Where to place the next text field
yPosition += (TEXT_FIELD_HEIGHT + 20);
}
// set the scroll view content size so it will fit all the text fields
[scrollView setContentSize:CGSizeMake(self.view.frame.size.width, yPosition+TEXT_FIELD_HEIGHT+20)];
}
- (IBAction)buttonPressed
{
// release and remove everyting from the name array
[nameArray release];
nameArray = nil;
// reinitilize the name array
nameArray = [[NSMutableArray alloc] init];
// Loop through the textfields to get the names into the nameArray
for (int textFieldCount = 0; textFieldCount<[textFieldArray count]; textFieldCount++) {
[nameArray addObject:[[textFieldArray objectAtIndex:textFieldCount] text]];
}
// Randomly sort the names in the array
[nameArray sortUsingFunction:randomSort context:nil];
// Add the random names back into the text fields
for (int textFieldCount = 0; textFieldCount<[textFieldArray count]; textFieldCount++) {
[[textFieldArray objectAtIndex:textFieldCount] setText:[nameArray objectAtIndex:textFieldCount]];
}
}
int randomSort(id obj1, id obj2, void *context ) {
// returns random number -1 0 1
return (arc4random()%3 - 1);
}
- (void)dealloc
{
[super dealloc];
[nameArray release];
nameArray = nil;
}
Related
I am a beginner with Objective-C and I am working on existing code base.
In the following code, UITapGestureRecognizer doesn't seem to trigger tap method. I have tried adding
[self setUserInteractionEnabled:YES];
Can anyone help me figure out what is not working here.
This is my UITableViewCell implementation class:
#interface ELCAssetCell ()
#property(nonatomic, strong) NSArray * rowAssets;
#property(nonatomic, strong) NSMutableArray * rowViews;
#end
#implementation ELCAssetCell
#synthesize rowAssets;
- (id)initWithReuseIdentifier:(NSString *)_identifier cellWidth:(CGFloat)width {
if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:_identifier]) {
self.rowViews = [[NSMutableArray alloc] init];
for (int i = 0; i < 4; i++) {
[self.rowViews addObject:[[AssetView alloc] initWithFrame:CGRectZero]];
}
for (AssetView * view in self.rowViews) {
[self addSubview:view];
}
_width = width;
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat itemWidth = _width / 4;
CGRect frame = CGRectMake(2, 2, itemWidth - 4, itemWidth - 4);
for (AssetView * view in self.rowViews) {
[view setFrame:frame];
[[view gestureRecognizers] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL
*stop) {
[view removeGestureRecognizer:obj];
}];
[view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(tap:)]];
frame.origin.x += itemWidth;
}
}
- (void)tap:(UITapGestureRecognizer *)gest {
[self.delegate assetPressed:[(AssetView *)[gest view] asset]];
[(AssetView *)[gest view] toggleSelection];
}
#end
The most likely problem is that you are adding the views to the cell itself -- they should be added to the cell's contentView.
Change:
for (AssetView * view in self.rowViews) {
[self addSubview:view];
}
to:
for (AssetView * view in self.rowViews) {
[self.contentView addSubview:view];
}
Aside from that, this looks absolutely terrible!
you should be using auto-layout instead of setting frames
layoutSubviews can be called multiple times... you should be adding the UITapGestureRecognizer when you create the views, not removing / re-adding every time layoutSubviews is called.
Step 1:-
Create a class with sub Class UITextView and put the name of class KDPlaceHolderTextView
copy and paste the code in KDPlaceHolderTextView.h file
#import <UIKit/UIKit.h>
IB_DESIGNABLE
#interface KDPlaceHolderTextView : UITextView
#property (nonatomic, retain) IBInspectable NSString *placeholder;
#property (nonatomic, retain) IBInspectable UIColor *placeholderColor;
/*!
This method is used to set the UITextView Notification and UitextField begin nitification to set the placeholder text
#param NSNotification to be a notification
#return void
*/
-(void)textChanged:(NSNotification*)notification;
#end
Step 2:-
Add the this code in KDPlaceHolderTextView.m file
#import "KDPlaceHolderTextView.h"
#interface KDPlaceHolderTextView ()
#property (nonatomic, retain) UILabel *placeHolderLabel;
#end
#implementation KDPlaceHolderTextView
CGFloat const UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION = 0.25;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)awakeFromNib
{
[super awakeFromNib];
// Use Interface Builder User Defined Runtime Attributes to set
// placeholder and placeholderColor in Interface Builder.
if (!self.placeholder) {
[self setPlaceholder:#""];
}
if (!self.placeholderColor) {
[self setPlaceholderColor:[UIColor lightGrayColor]];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
/*!
This method is used to set the frame Placeholder lable
#param CGrect frame to be a frame
#return id
*/
- (id)initWithFrame:(CGRect)frame
{
if( (self = [super initWithFrame:frame]) )
{
[self setPlaceholder:#""];
[self setPlaceholderColor:[UI Color lightGrayColor]];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(textChanged:) name:UITextViewTextDidChangeNotification object:nil];
}
return self;
}
- (void)textChanged:(NSNotification *)notification
{
if([[self placeholder] length] == 0)
{
return;
}
[UIView animateWithDuration:UI_PLACEHOLDER_TEXT_CHANGED_ANIMATION_DURATION animations:^{
if([[self text] length] == 0)
{
[[self viewWithTag:999] setAlpha:1];
}
else
{
[[self viewWithTag:999] setAlpha:0];
}
}];
}
- (void)setText:(NSString *)text {
[super setText:text];
[self textChanged:nil];
}
/*!
This method is used to draw the rect in placeholder lable acording to amount of text
#param CGrect to be a rect
#return void
*/
- (void)drawRect:(CGRect)rect
{
if( [[self placeholder] length] > 0 )
{
if (_placeHolderLabel == nil )
{
_placeHolderLabel = [[UILabel alloc] initWithFrame:CGRectMake(8,8,self.bounds.size.width - 16,0)];
_placeHolderLabel.lineBreakMode = NSLineBreakByWordWrapping;
_placeHolderLabel.numberOfLines = 0;
_placeHolderLabel.font = self.font;
_placeHolderLabel.backgroundColor = [UIColor clearColor];
_placeHolderLabel.textColor = self.placeholderColor;
_placeHolderLabel.alpha = 0;
_placeHolderLabel.tag = 999;
[self addSubview:_placeHolderLabel];
}
_placeHolderLabel.text = self.placeholder;
[_placeHolderLabel sizeToFit];
[self sendSubviewToBack:_placeHolderLabel];
}
if( [[self text] length] == 0 && [[self placeholder] length] > 0 )
{
[[self viewWithTag:999] setAlpha:1];
}
[super drawRect:rect];
}
#end
Step 3:-
Go to storyboard file and drag the UITexview in viewcotroller and assign the class KDPlaceHolderTextView
and see the attribute inspector set the PlaceHolder text or color
finally build and run the project
Check this in GitHub
You just have to change class name to (GCPlaceholderTextView) in UITextView interface.
It is not directly possible to add a Placeholder in textView But we can make use of UILabel to do the same.
Take a property of UILabel
#property (weak, nonatomic) UILabel *placeholederLabel;
Then in YourViewDidLoad.
placeholederLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 5.0,textView.frame.size.width - 30.0, 40.0)];
[placeholederLabel setText:#"Enter Your text here."];
[placeholederLabel setBackgroundColor:[UIColor clearColor]];
[placeholederLabel setTextColor:[UIColor yellowColor]];
[textView addSubview:placeholederLabel];
And then write textView delegate Methods
- (void)textViewDidEndEditing:(UITextView *)theTextView
{
if (![textView hasText]) {
placeholederLabel.hidden = NO;
}
}
- (void) textViewDidChange:(UITextView *)textView
{
if(![textView hasText]) {
placeholederLabel.hidden = NO;
}
else{
placeholederLabel.hidden = YES;
}
}
How can I fix the problem of Incomplete Implementation?
View of Controller.m :
#import "Quiz_GameViewController.h"
#implementation Quiz_GameViewController
#synthesize theQuestion, timer, theScore, theLives, answerOne, answerTwo, answerThree, answerFour, theQuiz
;
-(void)askQuestion
{
// Unhide all the answer buttons.
[answerOne setHidden:NO];
[answerTwo setHidden:NO];
[answerThree setHidden:NO];
[answerFour setHidden:NO];
// Set the game to a "live" question (for timer purposes)
questionLive = YES;
// Set the time for the timer
time = 8.0;
// Go to the next question
questionNumber = questionNumber + 1;
// We get the question from the questionNumber * the row that we look up in the array.
NSInteger row = 0;
if(questionNumber == 1)
{
row = questionNumber - 1;
}
else
{
row = ((questionNumber - 1) * 6);
}
// Set the question string, and set the buttons the the answers
NSString *selected = [theQuiz objectAtIndex:row];
NSString *activeQuestion = [[NSString alloc] initWithFormat:#"Question: %#", selected];
[answerOne setTitle:[theQuiz objectAtIndex:row+1] forState:UIControlStateNormal];
[answerTwo setTitle:[theQuiz objectAtIndex:row+2] forState:UIControlStateNormal];
[answerThree setTitle:[theQuiz objectAtIndex:row+3] forState:UIControlStateNormal];
[answerFour setTitle:[theQuiz objectAtIndex:row+4] forState:UIControlStateNormal];
rightAnswer = [[theQuiz objectAtIndex:row+5] intValue];
// Set theQuestion label to the active question
theQuestion.text = activeQuestion;
// Start the timer for the countdown
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
[selected release];
[activeQuestion release];
}
-(void)updateScore
{
// If the score is being updated, the question is not live
questionLive = NO;
[timer invalidate];
// Hide the answers from the previous question
[answerOne setHidden:YES];
[answerTwo setHidden:YES];
[answerThree setHidden:YES];
[answerFour setHidden:YES];
NSString *scoreUpdate = [[NSString alloc] initWithFormat:#"Score: %d", myScore];
theScore.text = scoreUpdate;
[scoreUpdate release];
// END THE GAME.
NSInteger endOfQuiz = [theQuiz count];
if((((questionNumber - 1) * 6) + 6) == endOfQuiz)
{
// Game is over.
if(myScore > 0)
{
NSString *finishingStatement = [[NSString alloc] initWithFormat:#"Game Over!\nNice Game \nYou scored %i!", myScore];
theQuestion.text = finishingStatement;
[finishingStatement release];
}
else
{
NSString *finishingStatement = [[NSString alloc] initWithFormat:#"Game Over!\n You're terrible! \nYou scored %i.", myScore];
theQuestion.text = finishingStatement;
[finishingStatement release];
}
theLives.text = #"";
// Make button 1 appear as a reset game button
restartGame = YES;
[answerOne setHidden:NO];
[answerOne setTitle:#"Restart game!" forState:UIControlStateNormal];
}
else
{
// Give a short rest between questions
time = 3.0;
// Initialize the timer
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(countDown) userInfo:nil repeats:YES];
}
}
-(void)countDown
{
// Question live counter
if(questionLive==YES)
{
time = time - 1;
theLives.text = [NSString stringWithFormat:#"Time remaining: %i!", time];
if(time == 0)
{
// Loser!
questionLive = NO;
theQuestion.text = #"HAHA now you lost alot of points!";
myScore = myScore - 1000;
[timer invalidate];
[self updateScore];
}
}
// In-between Question counter
else
{
time = time - 1;
theLives.text = [NSString stringWithFormat:#"Next question coming in...%i!", time];
if(time == 0)
{
[timer invalidate];
theLives.text = #"";
[self askQuestion];
}
}
if(time < 0)
{
[timer invalidate];
}
}
- (IBAction)buttonOne
{
if(questionNumber == 0){
// This means that we are at the startup-state
// We need to make the other buttons visible, and start the game.
[answerTwo setHidden:NO];
[answerThree setHidden:NO];
[answerFour setHidden:NO];
[self askQuestion];
}
else
{
NSInteger theAnswerValue = 1;
[self checkAnswer:(int)theAnswerValue];
if(restartGame==YES)
{
// Create a restart game function.
}
}
}
- (IBAction)buttonTwo
{
NSInteger theAnswerValue = 2;
[self checkAnswer:(int)theAnswerValue];
}
- (IBAction)buttonThree
{
NSInteger theAnswerValue = 3;
[self checkAnswer:(int)theAnswerValue];
}
- (IBAction)buttonFour
{
NSInteger theAnswerValue = 4;
[self checkAnswer:(int)theAnswerValue];
}
// Check for the answer (this is not written right, but it runs)
-(void)checkAnswer:(int)theAnswerValue
{
if(rightAnswer == theAnswerValue)
{
theQuestion.text = #"Daaamn";
myScore = myScore + 50;
}
else
{
theQuestion.text = #"hahaha!";
myScore = myScore - 50;
}
[self updateScore];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
questionLive = NO;
restartGame = NO;
theQuestion.text = #"Think you can do it?";
theScore.text = #"Score:0";
theLives.text = #"";
questionNumber = 0;
myScore = 0;
myLives = 0;
[answerOne setTitle:#"I think i can!" forState:UIControlStateNormal];
[answerTwo setHidden:YES];
[answerThree setHidden:YES];
[answerFour setHidden:YES];
[self loadQuiz];
}
-(void)loadQuiz
{
// This is our forced-loaded array of quiz questions.
// FORMAT IS IMPORTANT!!!!
// 1: Question, 2 3 4 5: Answers 1-4 respectively, 6: The right answer
// THIS IS A TERRIBLE WAY TO DO THIS. I will figure out how to do nested arrays to make this better.
NSArray *quizArray = [[NSArray alloc] initWithObjects:#"Who is the president in USA?",#"Me",#"Obama",#"George Bush",#"Justin Bieber",#"2",
#"Capital in Norway?", #"Bergen", #"Trondheim", #"Oslo", #"Bærum", #"3",
#"The right answer is 3!", #"41", #"24", #"3", #"9", #"1",
#"Do I have a cat?", #"Yes", #"No", #"No, you have a dog", #"No, you have a flying hamster", #"4",
#"Baba", #"Daba jaba?", #"Laba daba haba?", #"Saba daba gaba?", #"Haba haba?", #"4",
nil];
self.theQuiz = quizArray;
[quizArray release];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
- (void)dealloc {
[theQuestion release];
[theScore release];
[theLives release];
[answerOne release];
[answerTwo release];
[answerThree release];
[answerFour release];
[theQuiz release];
[timer release];
[super dealloc];
}
#end
I'am new here and this is an example script from the internet...I use it to learn the language Objective-C and Cocoa...ViewController.h :
#import <UIKit/UIKit.h>
#interface Quiz_GameViewController : UIViewController {
IBOutlet UILabel *theQuestion;
IBOutlet UILabel *theScore;
IBOutlet UILabel *theLives;
IBOutlet UIButton *answerOne;
IBOutlet UIButton *answerTwo;
IBOutlet UIButton *answerThree;
IBOutlet UIButton *answerFour;
NSInteger myScore;
NSInteger myLives;
NSInteger questionNumber;
NSInteger rightAnswer;
NSInteger time;
NSArray *theQuiz;
NSTimer *timer;
BOOL questionLive;
BOOL restartGame;
}
#property (retain, nonatomic) UILabel *theQuestion;
#property (retain, nonatomic) UILabel *theScore;
#property (retain, nonatomic) UILabel *theLives;
#property (retain, nonatomic) UIButton *answerOne;
#property (retain, nonatomic) UIButton *answerTwo;
#property (retain, nonatomic) UIButton *answerThree;
#property (retain, nonatomic) UIButton *answerFour;
#property (retain, nonatomic) NSArray *theQuiz;
#property (retain, nonatomic) NSTimer *timer;
-(IBAction)buttonOne;
-(IBAction)buttonTwo;
-(IBAction)buttonThree;
-(IBAction)buttonFour;
-(void)checkAnswer;
-(void)askQuestion;
-(void)updateScore;
-(void)loadQuiz;
-(void)countDown;
#end
In your headerfile, you have declared the method -(void)checkAnswer, while in the .m file you have declared it -(void)checkAnswer:(int)theAnswerValue.
This means that your .m file is looking for a method -(void)checkAnswer, which does not exist, and it yields an Incomplete implementation warning. Simply change your declaration in the .h file to - (void)checkAnswer:(int)theAnswerValue, and you'll be fine.
See in .h you have (method with no parameters):
-(void)checkAnswer;
and in .m you have (method with one int parameter):
-(void)checkAnswer:(int)theAnswerValue
Incomplete Implementation means you declared something in .h but didn't implement that in .m.
The signature of checkAnswer is different in you .h and .m
in Quiz_GameViewController.h:
-(void)checkAnswer;
in Quiz_GameViewController.m
-(void)checkAnswer:(int)theAnswerValue
FIX : Change the Quiz_GameViewController.h to:
- (void)checkAnswer:(int)theAnswerValue,
In my iPad program I have an array which holds images. How can I display my all images (from an image array) in my viewController the same as the below screen shot? Is there a good way to do it, any sample application paths to refer or sample code?
I need the following functionality.
Tapping an image will show it full screen
A close button to close this view as the same as the screen shot.
Two buttons to display the remaining and previous images.
A sample screen shot is attached below. We can see that the below application is showing all images at the right side of the screen.
Alright, this should be easy, though a bit of coding is needed.
Start out with a simple view based app template.
I don't know where the images come from so I just put all the images to be shown in the resources folder.
The view controller PictureViewController will accept an array of UIImages and should be presented modally. I'll post the code below.
The code to show the PictureViewController is placed in the view controller created by the template. I just added a simple UIButton to the view to trigger an action which looks something like this:
- (IBAction)onShowPictures
{
// Load all images from the bundle, I added 14 images, named 01.jpg ... 14.jpg
NSMutableArray *images = [NSMutableArray array];
for (int i = 1; i <= 14; i++) {
[images addObject:[UIImage imageNamed:[NSString stringWithFormat:#"%02d.jpg", i]]];
}
PictureViewController *picViewController = [[PictureViewController alloc] initWithImages:images];
[self presentModalViewController:picViewController animated:YES];
[picViewController release];
}
The view controller's view was created with interface builder, looking like this:
PictureViewController.xib
View Hierarchy
The fullscreen image is linked to an outlet fullScreenImage seen in the following header file. Actions are connected as well.
I've set the fullscreen imageView's content mode to Aspect Fit.
The Thumbnails will be added dynamically with code. Here's the view controller's code
PictureViewController.h
#interface PictureViewController : UIViewController
{
NSMutableArray *imageViews;
NSArray *images;
UIImageView *fullScreenImage;
int currentPage;
}
#property (nonatomic, retain) NSMutableArray *imageViews;
#property (nonatomic, retain) NSArray *images;
#property (nonatomic, retain) IBOutlet UIImageView *fullScreenImage;
- (id)initWithImages:(NSArray *)images;
- (IBAction)onClose;
- (IBAction)onNextThumbnails;
- (IBAction)onPreviousThumbnails;
#end
PictureViewController.m
The define MAX_THUMBNAILS on top defines the maximum of thumbnails seen. A UITapGestureRecognizer will take care of the tap events for the thumbnails. Adjust the CGRectMake in setupThumbnailImageViews to position the thumbnails as you wish. This controller is just a basic approach without orientation support.
#import "PictureViewController.h"
#define MAX_THUMBNAILS 6
#interface PictureViewController ()
- (void)showSelectedImageFullscreen:(UITapGestureRecognizer *)gestureRecognizer;
- (void)setupThumbnailImageViews;
- (void)setThumbnailsForPage:(int)aPage;
- (UIImage *)imageForIndex:(int)anIndex;
#end
#implementation PictureViewController
#synthesize imageViews, images, fullScreenImage;
- (id)initWithImages:(NSArray *)someImages
{
self = [super init];
if (self) {
self.images = someImages;
self.imageViews = [NSMutableArray array];
currentPage = 0;
}
return self;
}
- (void)viewDidLoad
{
self.fullScreenImage.image = [images objectAtIndex:0];
[self setupThumbnailImageViews];
[self setThumbnailsForPage:0];
}
- (void)showSelectedImageFullscreen:(UITapGestureRecognizer *)gestureRecognizer
{
UIImageView *tappedImageView = (UIImageView *)[gestureRecognizer view];
fullScreenImage.image = tappedImageView.image;
}
- (void)setupThumbnailImageViews
{
for (int i = 0; i < MAX_THUMBNAILS; i++) {
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20.0,
166.0 + (130.0 * i),
130.0,
90.0)];
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self
action:#selector(showSelectedImageFullscreen:)];
tapGestureRecognizer.numberOfTapsRequired = 1;
tapGestureRecognizer.numberOfTouchesRequired = 1;
[imageView addGestureRecognizer:tapGestureRecognizer];
[tapGestureRecognizer release];
imageView.userInteractionEnabled = YES;
[imageViews addObject:imageView];
[self.view addSubview:imageView];
}
}
- (void)setThumbnailsForPage:(int)aPage
{
for (int i = 0; i < MAX_THUMBNAILS; i++) {
UIImageView *imageView = (UIImageView *)[imageViews objectAtIndex:i];
UIImage *image = [self imageForIndex:aPage * MAX_THUMBNAILS + i];
if (image) {
imageView.image = image;
imageView.hidden = NO;
} else {
imageView.hidden = YES;
}
}
}
- (UIImage *)imageForIndex:(int)anIndex
{
if (anIndex < [images count]) {
return [images objectAtIndex:anIndex];
} else {
return nil;
}
}
#pragma mark -
#pragma mark user interface interaction
- (IBAction)onClose
{
[self dismissModalViewControllerAnimated:YES];
}
- (IBAction)onNextThumbnails
{
if (currentPage + 1 <= [images count] / MAX_THUMBNAILS) {
currentPage++;
[self setThumbnailsForPage:currentPage];
}
}
- (IBAction)onPreviousThumbnails
{
if (currentPage - 1 >= 0) {
currentPage--;
[self setThumbnailsForPage:currentPage];
}
}
#pragma mark -
#pragma mark memory management
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[images release];
}
- (void)viewDidUnload
{
[super viewDidUnload];
[imageViews release];
[fullScreenImage release];
}
- (void)dealloc
{
[images release];
[imageViews release];
[fullScreenImage release];
[super dealloc];
}
#end
The result:
I've got a problem at programming for iOS. Already looked for some similar problems but haven't found anything yet.
I'm creating at least 8 custom UIViews. As you can see in the appended code i'm running through a loop creating one instance per round. The reference of every object is on a different space in the memory but when i change a value in one object it only affects the object that has been created in the last loop-round (last created instance).
Any Ideas?
PadView.h:
#import <UIKit/UIKit.h>
#interface PadView : UIView {
}
- (void)setText:(NSString*)text;
#end
PadView.m:
#import "PadView.h"
#import "AVFoundation/AVFoundation.h";
#implementation PadView
AVAudioPlayer *player;
UILabel *label;
- (void)setText:(NSString*)text {
label.text = text;
}
- (void)initialize {
label = [[ UILabel alloc ] initWithFrame:CGRectMake(0.0, 93.0, 107.0, 13.0)];
label.backgroundColor = [UIColor clearColor];
label.font = [UIFont boldSystemFontOfSize:9];
label.textAlignment = UITextAlignmentCenter;
label.text = #"Empty";
[self addSubview:label];
[label release];
}
- (id) initWithCoder:(NSCoder *)aCoder {
if (self = [super initWithCoder:aCoder]) {
[self initialize];
}
return self;
}
- (id) initWithFrame:(CGRect)rect {
if (self = [super initWithFrame:rect]) {
[self initialize];
}
return self;
}
- (void)dealloc {
[super dealloc];
}
#end
Create the Objects:
NSMutableArray *pads = [[NSMutableArray alloc] initWithCapacity:8];
for (int i = 0; i < 8; i++) {
PadView *pad = [[PadView alloc] initWithFrame:CGRectMake(0.0, i*150, 107.0, 107.0)];
[padsView addSubview:pad];
[pads addObject:pad];
}
Call setText:
PadView *pad = [pads objectAtIndex:5];
[pad setText:#"test"];
Your variables:
AVAudioPlayer *player;
UILabel *label;
are defined in the #implementation block, so they are effectively global variables (in the C sense).
So basically, all your instances of PadView will change the same UILabel when you set its text property (which explains the behavior you are seeing).
I'm lacking some context, but it seems that you want label to be an instance variable instead (and I'd assume player as well). If that's the case, you need to declare them in the #interface block as follows:
#interface PadView : UIView {
AVAudioPlayer *player;
UILabel *label;
}
- (void)setText:(NSString*)text;
#end
pads is not initialized
NSMutableArray *pads = [[NSMutableArray alloc] initWithCapacity:8];
and you must release pad after adding as subview and to the array
By convention the class should be named PadView, not padView
edit
for(padView *pad in pads){
//manipulate each pad
}
//manipulate a certain pad
padView *pad = [pads objectAtIndex:5];
pad. //...