Multiple rating bars with DYRateView - iphone

I have a view with 3 ratings bars on it.
How do I tell them apart in the code? Right now if I change the top one it sees it fine but if I then change either or the other two it cannot separate them from one another.
The code is from git https://github.com/dyang/DYRateView
- (void)changedToNewRate:(NSNumber *)rate {
NSString *rating = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"rating: %#",rating);
}
This is where is sees the changing.
And this is the .m file
#import "Survey.h"
#implementation Survey
#synthesize btnSubmit;
- (void)setUpEditableRateView {
DYRateView *rateService = [[DYRateView alloc] initWithFrame:CGRectMake(0, 55, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateService.padding = 20;
rateService.alignment = RateViewAlignmentCenter;
rateService.editable = YES;
rateService.delegate =self;
[scroller addSubview:rateService];
[rateService release];
DYRateView *rateFood = [[DYRateView alloc] initWithFrame:CGRectMake(0, 130, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateFood.padding = 20;
rateFood.alignment = RateViewAlignmentCenter;
rateFood.editable = YES;
rateFood.delegate = self;
[scroller addSubview:rateFood];
[rateFood release];
DYRateView *rateCleanliness = [[DYRateView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateCleanliness.padding = 20;
rateCleanliness.alignment = RateViewAlignmentCenter;
rateCleanliness.editable = YES;
rateCleanliness.delegate = self;
[scroller addSubview:rateCleanliness];
[rateCleanliness release];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
- (void)changedToNewRate:(NSNumber *)rate {
NSString *rating = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"rating: %#",rating);
}
- (IBAction)btnSubmit:(id)sender{
}
-(IBAction)mainMenu{
[self dismissModalViewControllerAnimated: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.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(320, 600)];
scroller.BackgroundColor = [UIColor clearColor];
[self setUpEditableRateView];
[btnSubmit useGreenConfirmStyle];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
UPDATE
ok with the new code I added an if statement
- (void)rateView:(DYRateView *)rateView changedToNewRate:(NSNumber *)rate {
NSString *barName = [NSString stringWithFormat:#"%#", rateView];
if (barName == #"rateView1") {
NSString *bar1 = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"bar 1: %#",bar1);
}else if(barName == #"rateView2"){
NSString *bar2 = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"bar 2: %#",bar2);
}else{
NSLog(#"NO BAR: %#",barName);
}
self.rateLabel.text = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
}
It works however Instead of getting back "rateView1" or 2 or 3. I get back
NO BAR: <DYRateView: 0x78229b0; frame = (0 40; 320 20); opaque = NO; layer =
<CALayer:0x7824900>>
Which is correct in nature but I was hoping for the name of the rateView such as "rateView1"
SOLUTION:
in .h file #property your 2 or 3 bars
#property(nonatomic, retain) DYRateView *rateView1,*rateView2;
in .m #synthesize them
#synthesize rateView1;
#synthesize rateView2;
then
(void)setUpEditableRateView {
rateView1 = [[DYRateView alloc] initWithFrame:CGRectMake(0, 40, self.view.bounds.size.width, 20) fullStar:[UIImage imageNamed:#"StarFullLarge.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge.png"]];
rateView1.padding = 20;
rateView1.alignment = RateViewAlignmentCenter;
rateView1.editable = YES;
rateView1.delegate = self;
[self.view addSubview:rateView1];
[rateView1 release];
rateView2 = [[DYRateView alloc] initWithFrame:CGRectMake(0, 100, self.view.bounds.size.width, 20) fullStar:[UIImage imageNamed:#"StarFullLarge.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge.png"]];
rateView2.padding = 20;
rateView2.alignment = RateViewAlignmentCenter;
rateView2.editable = YES;
rateView2.delegate = self;
[self.view addSubview:rateView2];
[rateView2 release];
// Set up a label view to display rate
self.rateLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 80, self.view.bounds.size.width, 20)] autorelease];
self.rateLabel.textAlignment = UITextAlignmentCenter;
self.rateLabel.text = #"Tap above to rate";
[self.view addSubview:self.rateLabel];
}
Then Finally
- (void)rateView:(DYRateView *)rateView changedToNewRate:(NSNumber *)rate {
if (rateView == rateView1) {
NSString *bar1 = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"bar 1: %#",bar1);
}else if(rateView == rateView2){
NSString *bar2 = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
NSLog(#"bar 2: %#",bar2);
}else{
NSLog(#"NO BAR: %#",rateView);
}
self.rateLabel.text = [NSString stringWithFormat:#"Rate: %d", rate.intValue];
}

Thanks for using DYRateView!
The current version of DYRateView doesn't support listening to multiple instances all at the same time, but that doesn't mean that we can't do that. :)
If you don't mind updating the source code, you can find a method named notifyDelegate in DYRateView.m, and change [self.delegate performSelector:#selector(changedToNewRate:) withObject:[NSNumber numberWithFloat:self.rate]] to something like [self.delegate performSelector:#selector(rateView:changedToNewRate:) withObject:self withObject:[NSNumber numberWithFloat:self.rate]]. In this way you are able to pass the rateView itself as a parameter to its listener.
I haven't tried the above code yet as I don't have access to my Mac at this point, but I think this should give you an idea regarding how to achieve your goal.

I just set the tag for each of my rateviews to tell them apart, so in your example, I add a tag to each one:
#define serviceTag 1
#define foodTag 2
#define cleanlinessTag 3
- (void)setUpEditableRateView {
DYRateView *rateService = [[DYRateView alloc] initWithFrame:CGRectMake(0, 55, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateService.padding = 20;
rateService.alignment = RateViewAlignmentCenter;
rateService.editable = YES;
rateService.tag = serviceTag;
rateService.delegate =self;
[scroller addSubview:rateService];
[rateService release];
DYRateView *rateFood = [[DYRateView alloc] initWithFrame:CGRectMake(0, 130, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateFood.padding = 20;
rateFood.alignment = RateViewAlignmentCenter;
rateFood.editable = YES;
rateFood.tag = foodTag;
rateFood.delegate = self;
[scroller addSubview:rateFood];
[rateFood release];
DYRateView *rateCleanliness = [[DYRateView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 40) fullStar:[UIImage imageNamed:#"StarFullLarge#2x.png"] emptyStar:[UIImage imageNamed:#"StarEmptyLarge#2x.png"]];
rateCleanliness.padding = 20;
rateCleanliness.alignment = RateViewAlignmentCenter;
rateCleanliness.editable = YES;
rateCleanliness.delegate = self;
rateCleanliness.tag = cleanlinessTag;
[scroller addSubview:rateCleanliness];
[rateCleanliness release];
}
Then, in the delegate method, you can just check the tag:
- (void)rateView:(DYRateView *)rateView changedToNewRate:(NSNumber *)rate {
switch (rateView.tag) {
case foodTag:
// Do something for food
break;
case serviceTag:
// Do something for service
break;
case cleanlinessTag:
// Do something for cleanliness
break;
default:
break;
}
}

Related

Identifying an UIImageView without tag

I have some generic generated ImageViews in a scrollView each of these images have 2 gestureRecognizer for single/double tapping on the ImageView. Now my problem is how to identify whether the ImageView was tapped for first or second time. In some scenarios it's easy to use the tag of an ImageView, but I have two different gestureRecognizer on each ImageView and every gestureRecognizer uses a different identification method based on the tag number, to identify the image.
Here I generate the ImageViews dynamically:
-(void) initLevels{
_level = [Level alloc];
_unit = [Unit alloc];
self->_units = [[NSMutableArray alloc] init];
_keys = [[NSMutableArray alloc] init]
;
int x = 0;
int y = 0;
int i = 0;
for (NSObject *object in self->_levels) {
if ([object isKindOfClass:_level.class] && i != 0) {
x = x + MARGIN_RIGHT + OBJECT_WIDTH;
y = 0;
}
else if ([object isKindOfClass:_unit.class]){
_unit = (Unit *) object;
[self->_units addObject:_unit.description];
UIImageView *imageView = [[UIImageView alloc] initWithImage:self.box];
[imageView setFrame:CGRectMake(x, y, OBJECT_WIDTH, BOX_HEIGHT)];
imageView.highlighted = TRUE;
imageView.tag = i; //when this is not outlined the gestureRecognizer for singleTapping works but on the other hand the double tap gestureRecognizer just works for the first object, because its' tag is set on 0.
UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(unitDoubleTapped:)];
doubleTapGesture.numberOfTapsRequired = 2;
imageView.userInteractionEnabled = YES;
[imageView addGestureRecognizer:doubleTapGesture];
UITapGestureRecognizer *singleTapGesture =
[[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(unitSingleTapped:)];
singleTapGesture.numberOfTapsRequired = 1;
//telling the singleTapGesture to fail the doubleTapGesture, so both doesn't fire at the same time
[singleTapGesture requireGestureRecognizerToFail:doubleTapGesture];
[imageView addGestureRecognizer:singleTapGesture];
UILabel *labelHeadline = [[UILabel alloc] initWithFrame:CGRectMake(5, 2, 220, 20)];
[labelHeadline setFont:[UIFont boldSystemFontOfSize:12]];
labelHeadline.textAlignment = NSTextAlignmentCenter;
[labelHeadline setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0]];
labelHeadline.text = _unit.headline;
labelHeadline.numberOfLines = 0;
[labelHeadline sizeToFit];
UILabel *labelPrice = [LabelUtils deepLabelCopy:labelHeadline withText:[NSString stringWithFormat:#"Price: %#",_unit.price] withFrame:NO];
[labelPrice setTextAlignment:NSTextAlignmentLeft];
[labelPrice setFrame:CGRectMake(labelHeadline.frame.origin.x, labelHeadline.frame.origin.y + labelHeadline.frame.size.height + 2, 220, 20)];
UILabel *labelCRM = [LabelUtils deepLabelCopy:labelHeadline withText:[NSString stringWithFormat:#"CRM: %#", _unit.crm] withFrame:NO];
[labelCRM setTextAlignment:NSTextAlignmentLeft];
[labelCRM setFrame:CGRectMake(labelPrice.frame.origin.x, labelPrice.frame.origin.y + labelPrice.frame.size.height + 2, 220, 20)];
UITextView *textView= [[UITextView alloc] initWithFrame:CGRectMake(0,0, OBJECT_WIDTH, OBJECT_HEIGHT)];
[textView addSubview:labelHeadline];
[textView addSubview:labelPrice];
[textView addSubview:labelCRM];
[textView setUserInteractionEnabled:NO];
[textView setEditable:NO];
textView.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0];
textView.textAlignment = NSTextAlignmentLeft;
[imageView addSubview:textView];
[_scrollView addSubview:imageView];
y = y + MARGIN_BOTTOM + BOX_HEIGHT;
}
[self->_keys addObject:[NSNumber numberWithInt:i]];
i++;
}//remove the last keys which are to much in the _keys array
while ([self->_keys count] > ([self->_units count])) {
[_keys removeLastObject];
i--;
}
self.contents = [NSDictionary dictionaryWithObjects:self->_units forKeys:_keys];
}
Here is the code for the two gesture Recognizer
-(void)unitDoubleTapped:(UIGestureRecognizer *)gestureRecognizer{
self->_unitViewForDoubleTapIdentification = (UIImageView *)gestureRecognizer.view;
switch (self->_unitViewForDoubleTapIdentification.tag) {
case 0:
[_unitViewForDoubleTapIdentification setHighlightedImage:self.transparentBox];
self->_unitViewForDoubleTapIdentification.tag = 1;
break;
case 1:
[_unitViewForDoubleTapIdentification setHighlightedImage:self.box];
self->_unitViewForDoubleTapIdentification.tag = 0;
break;
default:
break;
}
}
and Here the singleTap
- (IBAction)unitSingleTapped:(id)sender {
[self dismissAllPopTipViews];
UIGestureRecognizer *gestureRecognizer = [UIGestureRecognizer alloc];
gestureRecognizer = (UIGestureRecognizer *)sender;
UIImageView *imageView = [[UIImageView alloc] init];
imageView = (UIImageView *)gestureRecognizer.view;
if (sender == _currentPopTipViewTarget) {
// Dismiss the popTipView and that is all
self.currentPopTipViewTarget = nil;
}
NSString *contentMessage = nil;
UIImageView *contentView = nil;
NSNumber *key = [NSNumber numberWithInt:imageView.tag];
id content = [self.contents objectForKey:key];
if ([content isKindOfClass:[NSString class]]) {
contentMessage = content;
}
else {
contentMessage = #"A large amount ot text in this bubble\najshdjashdkgsadfhadshgfhadsgfkasgfdasfdhasdkfgaodslfgkashjdfg\nsjfkasdfgkahdjsfghajdsfgjakdsfgjjakdsfjgjhaskdfjadsfgjdsfahsdafhjajdskfhadshfadsjfhadsjlfkaldsfhfldsa\ndsfgahdsfgajskdfgkafd";
}
NSArray *colorScheme = [_colorSchemes objectAtIndex:foo4random()*[_colorSchemes count]];
UIColor *backgroundColor = [colorScheme objectAtIndex:0];
UIColor *textColor = [colorScheme objectAtIndex:1];
CMPopTipView *popTipView;
if (contentView) {
popTipView = [[CMPopTipView alloc] initWithCustomView:contentView];
}
else {
popTipView = [[CMPopTipView alloc] initWithMessage:contentMessage];
}
[popTipView presentPointingAtView:imageView inView:self.view animated:YES];
popTipView.delegate = self;
popTipView.disableTapToDismiss = YES;
popTipView.preferredPointDirection = PointDirectionUp;
if (backgroundColor && ![backgroundColor isEqual:[NSNull null]]) {
popTipView.backgroundColor = backgroundColor;
}
if (textColor && ![textColor isEqual:[NSNull null]]) {
popTipView.textColor = textColor;
}
popTipView.animation = arc4random() % 2;
popTipView.has3DStyle = (BOOL)(arc4random() % 2);
popTipView.dismissTapAnywhere = YES;
[popTipView autoDismissAnimated:YES atTimeInterval:3.0];
[_visiblePopTipViews addObject:popTipView];
self.currentPopTipViewTarget = sender;
}
Hope you can help me, thanks in advance.
that's a lot of code to go through.. but I add more identifiers to UIViews (ie other than the tag identifier) by using obj-c runtime associative references..
So this is a category I attach to my UIView:
#import "UIView+Addons.h"
#import <objc/runtime.h>
#define kAnimationDuration 0.25f
#implementation UIView (Addons)
static char infoKey;
static char secondaryInfoKey;
-(id)info {
return objc_getAssociatedObject(self, &infoKey);
}
-(void)setInfo:(id)info {
objc_setAssociatedObject(self, &infoKey, info, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(id)secondaryInfo {
return objc_getAssociatedObject(self, &secondaryInfoKey);
}
-(void)setSecondaryInfo:(id)info {
objc_setAssociatedObject(self, &secondaryInfoKey, info, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
#end
here is an example of my own code where I use the above to address a problem similar to the one you're facing:
if (![[view info] boolValue]) { // not selected?
self.moveToFolderNumber = [view secondaryInfo];
[view setInfo:#YES];
}

Multiple UITextfield Create Dynamically in iphone sdk

I have to create a multiple textfield dynamically on scrollview in ipad app. textfield created successfully and i use popup view on clicked textfield but when i clicked on textfield i dont get the Tag of Textfield. i get tag of last textfield so i cant set the text on the current textfield.
Following code i used...
int j = 430;
int k = 413;
int RB = 423;
for (int i=0; i<[appDelegate.questions count]; i++) {
imgTxtQue = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"textbox.png"]];
imgTxtQue.frame = CGRectMake(267, k, 490, 60);
// UIImageView *imgRatingBtn = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#""]];
// imgRatingBtn.frame = CGRectMake(633, RB, 102, 39);
//ratingButton1.hidden = NO;
ratingButton1 = [[UIButton alloc] initWithFrame:CGRectMake(633, RB, 102, 39)];
[ratingButton1 setImage:[UIImage imageNamed:#"rating_selected.png"] forState:UIControlStateNormal];
txtQuestions = [[UITextField alloc] initWithFrame:CGRectMake(296, j, 429, 24)];
//txtQuestions.tag = i;
[txtQuestions setTag:i];
NSLog(#"%d", txtQuestions.tag);
txtQuestions.delegate = self;
[txtQuestions setPlaceholder:[[appDelegate.questions objectAtIndex:i] objectForKey:#"question"]];
txtQuestions.borderStyle = UITextBorderStyleNone;
// txtQuestions.background = imgTxtQue.image;
[scrView addSubview:imgTxtQue];
[scrView addSubview:ratingButton1];
[scrView addSubview:txtQuestions];
j = j+50;
k = k+50;
RB = RB+50;
}
-(void)loadQuestion
{
txtQuestionOne.hidden=NO;
imgTxtQue.hidden=NO;
CGRect aFrame1 = imgTxtQue.frame;
aFrame1.size.width = aFrame1.size.width + 200;
// aFrame.size.height = newHeight;
NSString *strQue = [NSString stringWithFormat:#"%#",[[appDelegate.questions objectAtIndex:0] objectForKey:#"question"]];
CGSize newSize1 = [strQue sizeWithFont: [UIFont fontWithName: #"TrebuchetMS" size: 12] ];
if (strQue.length > 42) {
imgTxtQue.frame = CGRectMake(267, 413, newSize1.width+353, 60);
[txtQuestionOne setFrame:CGRectMake(294, 430, newSize1.width+350, 24)];
ratingButton1.frame = CGRectMake(855, 423, 102, 39);
ratingLabel1.frame = CGRectMake(900, 430, 42, 21);
}
[txtQuestionOne setPlaceholder:[[appDelegate.questions objectAtIndex:0] objectForKey:#"question"]];
appDelegate.dynamicQues =[[appDelegate.questions objectAtIndex:0] objectForKey:#"question"];
NSLog(#"current q1 %#", [[appDelegate.questions objectAtIndex:0] objectForKey:#"question"]);
if ([[[appDelegate.questions objectAtIndex:0] objectForKey:#"permission"] isEqualToString:#"1"]) {
ratingButton1.hidden=NO;
ratingLabel1.hidden=NO;
}
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
BOOL editing=YES;
for (UIImageView *img in ViewPost.subviews)
{
if ([img isKindOfClass:[UIImageView class]])
{
if (img.tag==textField.tag)
{
[img setImage:[UIImage imageNamed:#"Redtextbox.png"]];;
}
else{
if (img.tag!=0) {
if (img.tag != 10) {
[img setImage:[UIImage imageNamed:#"textbox.png"]];
}
else
{
[img setImage:[UIImage imageNamed:#"inputbox.png"]];
}
}
}
}
}
if (textField==txtcategory) {
[textField resignFirstResponder];
appDelegate.category=YES;
editing=NO;
touchflag=1;
[self performSelectorOnMainThread:#selector(CategoryListClick) withObject:nil waitUntilDone:YES];
//[self CategoryListClick];
return NO;
}
if (textField==txtsubcategory) {
appDelegate.category=NO;
editing=NO;
[self performSelectorOnMainThread:#selector(CategoryListClick) withObject:nil waitUntilDone:YES];
}
if (txtQuestions.tag) {
// if (textField==txtQuestions) {
editing=NO;
index=txtQuestions.tag;
NSLog(#"%d",txtQuestions.tag);
touchflag = 1;
[self performSelectorOnMainThread:#selector(loadAnswers) withObject:nil waitUntilDone:YES];
// }
}
-(void)loadAnswers{
if (touchflag==1) {
[Name resignFirstResponder];
[Email resignFirstResponder];
[txtCityCode resignFirstResponder];
[txtcategory resignFirstResponder];
[txtTitle resignFirstResponder];
[txtQuestions resignFirstResponder];
[txtsubcategory resignFirstResponder];
SubcategoryPopViewController *objPopview = [[SubcategoryPopViewController alloc]initWithNibName:#"SubcategoryPopViewController" bundle:nil];
objPopview.delegate = self;
objPopview.index=txtQuestions.tag;
popView =[[UIPopoverController alloc]initWithContentViewController:objPopview];
[self RescheduleTimer];
[popView presentPopoverFromRect:imgTxtQue.frame inView:ViewPost permittedArrowDirections:0 animated:NO];
[popView setPopoverContentSize:CGSizeMake(376, 260)];
}
}
-(void) didSelectAnswer{
touchflag=0;
[popView dismissPopoverAnimated:YES];
[self RescheduleTimer];
if (appDelegate.ansDynamic==YES) {
// txtQuestionOne.text=appDelegate.answerOne;
if (txtQuestions.tag) {
txtQuestions.text = appDelegate.answerDynamic;
}
appDelegate.ansDynamic=NO;
questionIndex=txtQuestions.tag;
if (![ratingButton1 isHidden]) {
ratingButton1.enabled=YES;
RatingPopViewController *objPopview = [[RatingPopViewController alloc]initWithNibName:#"RatingPopViewController" bundle:nil];
objPopview.index=txtQuestions.tag;
objPopview.checkedCell=ratingLabel1.text;
objPopview.QuestionText=appDelegate.answerDynamic;
objPopview.delegate=self;
popSweepStakes =[[UIPopoverController alloc]initWithContentViewController:objPopview];
[popSweepStakes presentPopoverFromRect:ratingButton1.frame inView:ViewPost permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];
[popSweepStakes setPopoverContentSize:CGSizeMake(300, 400)];
}
return;
}
In the above code i get the tag correctly but when i use tag on other mathod then i only get the last textfields tag.
Thanks,
Rahul Virja
You overwrite txtQuestions variable.
Declare a class attribute like this NSMutableArray * _textFieldArray. (It's import declare a NSMutableArray object for add your textField).
In the init method of your class allocate and init your array: _textFieldArray = [[NSmutableArray alloc]init].
In your for statement use the following code for allocate a textField:
UItextField * txtQuestions = [[UITextField alloc] initWithFrame:CGRectMake(296, j, 429, 24)];
After setting all your property on txtQuestions object, add it to the array
[_textFieldArray addObject:txtQuestions]
When you need for a textfield use this code:
[_textFieldArray objectAtIndex:txtQuestions.tag]
Is it Clear?

Error: this class is not key value coding-compliant for the key projectToolBar? [duplicate]

This question already has answers here:
Xcode - How to fix 'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X" error?
(79 answers)
Closed 7 years ago.
Hey I can't figure out an error I got. I had my App working and then I'm not sure what I did but it won't open now and instead I get this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TaskViewController 0x16c9b0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key projectToolBar.'
Any Ideas what might be the problem? I can add my project code if I need to...
edit:
So i looked and in the interface builder/storyboard there was a link to projectToolBar that didn't have a corresponding line in the header file. I deleted the problem in IB, however, now I am getting a new error and it still isn't working.
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<TaskViewController 0x132dd0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key projectView.'
Here is my taskviewController class:
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "newTaskWindow.h"
#interface TaskViewController : UIViewController <DismissPopoverDelegate>{
IBOutlet UIScrollView *taskScrollView;
AppDelegate * _appDelegate;
UIDeviceOrientation orientation;
IBOutlet UIView *newTaskView;
IBOutlet UIBarButtonItem *newTaskButton;
IBOutlet UIBarButtonItem *newTeamMemberButton;
IBOutlet UIBarButtonItem *newProjectButton;
IBOutlet UIView*taskView;
IBOutlet UIToolbar *taskToolBar;
NSMutableArray *teamMembers;
NSMutableArray *projects;
NSMutableArray *tasks;
//UIPopoverController *taskPop;
int countForX;
int countForY;
int xOffSet;
int yOffset;
int xMult;
int yMult;
int viewContentSize;
int countForTaskView;
int maxCountForX;
int maxCountForY;
int incrementForYOffset;
int viewContentSizeBase;
}
- (IBAction)newTask:(id)sender;
- (IBAction)newTeamMember:(id)sender;
- (IBAction)newProject:(id)sender;
-(void)setTasksInScreen;
#property(nonatomic, retain) AppDelegate * appDelegate;
#property (nonatomic, retain) UIPopoverController *myPopover;
#end
#protocol NewsVcDelegate <NSObject>
- (void)FirstViewController:(TaskViewController*)controller didSelectObject:(id)object;
#end
// FirstViewController.m
#import "TaskViewController.h"
#import "newTaskWindow.h"
#import "TeamMember.h"
#import "Project.h"
#import "newTeamMemberWindow.h"
#import "newProjectWindow.h"
#implementation TaskViewController
#synthesize myPopover;
#synthesize appDelegate;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
NSLog(#"Made it to TaskViewController");
self.appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(deviceOrientationDidChange:) name: UIDeviceOrientationDidChangeNotification object: nil];
[self setTasksInScreen];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
//create new Team member in popover myPopover
-(IBAction)newTeamMember:(id)sender{
if ([self.myPopover isPopoverVisible]) {
//using the setters and getters "goes thru the proper channels" when accessing objects
[self.myPopover dismissPopoverAnimated:YES];
} else {
newTeamMemberWindow *teamMemberWindow = [[newTeamMemberWindow alloc]init];
[teamMemberWindow setDelegate:self];
UIPopoverController *teamMemberPop = [[UIPopoverController alloc]initWithContentViewController:teamMemberWindow];
[teamMemberPop setDelegate:self];
[teamMemberPop setPopoverContentSize:CGSizeMake(300, 450)];
//NSLog(#"Got to 6");
self.myPopover = teamMemberPop;
[self.myPopover presentPopoverFromBarButtonItem:newTeamMemberButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
//Create new Project in popover myPopover
-(IBAction)newProject:(id)sender{
if ([self.myPopover isPopoverVisible]) {
//using the setters and getters "goes thru the proper channels" when accessing objects
[self.myPopover dismissPopoverAnimated:YES];
} else {
newProjectWindow *projectWindow = [[newProjectWindow alloc]init];
[projectWindow setDelegate:self];
UIPopoverController *projectPop = [[UIPopoverController alloc]initWithContentViewController:projectWindow];
[projectPop setDelegate:self];
[projectPop setPopoverContentSize:CGSizeMake(300, 450)];
self.myPopover = projectPop;
[self.myPopover presentPopoverFromBarButtonItem:newProjectButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
//Create new Task in popover myPopover
-(IBAction)newTask:(id)sender{
if ([self.myPopover isPopoverVisible])
{
[self.myPopover dismissPopoverAnimated:YES];
} else {
NSString* test1 = [[NSString alloc]initWithFormat:#"Robby"];
[teamMembers addObject:test1];
newTaskWindow *newTaskWin = [[newTaskWindow alloc]init];
[newTaskWin setDelegate:self];
UIView *test = [[UIView alloc]init];
[newTaskWin setTeamMembers:teamMembers];
test = newTaskWin.view;
UIPopoverController *taskPop = [[UIPopoverController alloc]initWithContentViewController:newTaskWin];
[taskPop setDelegate:self];
[taskPop setPopoverContentSize:CGSizeMake(300, 450)];
self.myPopover = taskPop;
[self.myPopover presentPopoverFromBarButtonItem:newTaskButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}
-(void)setTasksInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(#"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(#"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
tasks = [[NSMutableArray alloc] initWithArray:self.appDelegate.tasks];
Task *tempTask = [[Task alloc]init];
for(int i =0; i < [tasks count]; i++){
tempTask = [tasks objectAtIndex:i];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//Set the style that you want the date to be here (ie. MM-DD-YYYY ect)
[formatter setDateStyle:NSDateFormatterFullStyle];
NSDate *endDateForButton = [tempTask endDate];
//Use custom Button so that you can add in background pic
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:#"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *taskName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
taskName.text = [tempTask taskName];
[taskName setTextAlignment:UITextAlignmentCenter];
[button addSubview:taskName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = #"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
UILabel *endDate = [[UILabel alloc]initWithFrame:CGRectMake(5, 80, 200, 45)];
endDate.text = [formatter stringFromDate:[tempTask endDate]];
[endDate setTextAlignment:UITextAlignmentCenter];
[button addSubview:endDate];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
-(void)setProjectsInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(#"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(#"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
projects = [[NSMutableArray alloc] initWithArray:self.appDelegate.projects];
Project *tempProject = [[Project alloc]init];
for(int i =0; i < [tasks count]; i++){
tempProject = [tasks objectAtIndex:i];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:#"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *projectName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
projectName.text = [tempProject projectName];
[projectName setTextAlignment:UITextAlignmentCenter];
[button addSubview:projectName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = #"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
-(void)setTeamMembersInScreen{
//remove all views that were in The task view. If you don't do this, a new view is placed on top everytime you call setTasksInScreen method and the buttons begin to overlap.
for (UIView *view in [taskView subviews]) {
[view removeFromSuperview];
}
//The placement of the buttons is different depending on which orientation we are in. We handle this with an if statement
if((self.interfaceOrientation == UIInterfaceOrientationPortrait) || (self.interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)){
countForX = 0;
countForY = 0;
xOffSet = 27;
yOffset = 60;
maxCountForX = 3;
maxCountForY = 4;
incrementForYOffset = 911;
xMult = 250;
yMult = 210;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 911;
NSLog(#"Portrait view");
}
else{
countForX = 0;
countForY = 0;
maxCountForX = 4;
maxCountForY = 3;
incrementForYOffset = 654;
xOffSet = 41;
yOffset = 50;
xMult = 240;
yMult = 200;
viewContentSize = 0;
countForTaskView = 1;
viewContentSizeBase = 654;
NSLog(#"LandScape view");
}
//Create Scrollview to be able to scroll through the different tasks
taskScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height -45)];
tasks = [[NSMutableArray alloc] initWithArray:self.appDelegate.tasks];
Task *tempTask = [[Task alloc]init];
for(int i =0; i < [tasks count]; i++){
tempTask = [tasks objectAtIndex:i];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//Set the style that you want the date to be here (ie. MM-DD-YYYY ect)
[formatter setDateStyle:NSDateFormatterFullStyle];
NSDate *endDateForButton = [tempTask endDate];
//Use custom Button so that you can add in background pic
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(xOffSet+(countForX*xMult), yOffset +(countForY*yMult), 215, 156);
UIImage *buttonBackground = [UIImage imageNamed:#"rectangleImage.png"];
[button setBackgroundImage:buttonBackground forState:UIControlStateNormal];
//add labels to button for information
UILabel *taskName = [[UILabel alloc]initWithFrame:CGRectMake(5, 5, 200, 45)];
taskName.text = [tempTask taskName];
[taskName setTextAlignment:UITextAlignmentCenter];
[button addSubview:taskName];
//Label that says "Due on"
UILabel *dueLabel = [[UILabel alloc]initWithFrame:CGRectMake(5, 50, 200, 45)];
dueLabel.text = #"Due on";
[dueLabel setTextAlignment:UITextAlignmentCenter];
[button addSubview:dueLabel];
UILabel *endDate = [[UILabel alloc]initWithFrame:CGRectMake(5, 80, 200, 45)];
endDate.text = [formatter stringFromDate:[tempTask endDate]];
[endDate setTextAlignment:UITextAlignmentCenter];
[button addSubview:endDate];
countForX++;
if(countForX >= maxCountForX)
{
countForY++;
countForX = 0;
}
if(countForY >=maxCountForY)
{
countForY = 0;
countForX = 0;
yOffset +=incrementForYOffset;
countForTaskView++;
}
[taskScrollView addSubview:button];
}//for loop
[taskView addSubview:taskScrollView];
[taskView bringSubviewToFront:taskToolBar];
//[taskScrollView addSubview:viewForTaskScrollView];
viewContentSize = viewContentSizeBase * (countForTaskView);
taskScrollView.contentSize = CGSizeMake(taskView.frame.size.width, viewContentSize);
[taskScrollView setPagingEnabled:YES];
}
- (void) dismissPopover:(NSString *)data
{ /* Dismiss you popover here and process data */
[self.myPopover dismissPopoverAnimated:YES];
[self setTasksInScreen];
//[myPopover dismissPopoverAnimated:YES];
}
// Some method, when you create popover
-(BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController{
return YES;
}
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}
- (void)deviceOrientationDidChange:(NSNotification *)notification {
[self setTasksInScreen];
}
#end
Most likely you have a xib file that houses a toolBar that is still connected to a (now nonexistent) outlet named projectToolBar.
You removed IBOutlet UIToolBar *projectToolBar; from your TaskViewController.h file.
You should think about using source control management, so you can see what you did. ;-)
Xcode 4 Guide - Managing Versions of Your Project
I'm betting you're trying to fill your TaskViewController using setValuesForKeysWithDictionary: or something like that, and projectToolBar isn't a valid #property in your view controller's header file.
It could also be what #MatthiasBauch said.
I had the same error after adding a few objects to a UITableViewCell on storyboard. Before that, the app was working perfectly.
I was able to resolve this issue by going Xcode > Preferences > Locations > Derived Data, ,opened the directory and deleted the folders with the app's name.
Hope my comment will be helpful for those come here later.

Background image not displayed on UIView

I have a class that implements "UIView" and inside - (void)drawRect:(CGRect)rect method I add some custom buttons to self. Inside a UIViewController I declare an instance of this view and i add it to self.view.
If i do this in - (void)viewDidLoad, everything works perfect, but if I create a method that is called when I push a button, and add that view to self.view, the buttons background is displayed after a few second. Till then only the name of the button appears written in white.
What do i do wrong?
Regards
#implementation CustomButton
#synthesize isPressed, buttonViewNumber;
- (id)initWithFrame:(CGRect)frame
title:(NSString *)title
tag:(int)tag
{
self = [super initWithFrame:frame];
if (self) {
[self setTitle:title forState:UIControlStateNormal];
[self setTag:tag];
self.titleLabel.font = [UIFont fontWithName:#"Helvetica" size:14];
self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
self.contentEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
[self setTitleColor:[UIColor grayColor] forState:UIControlStateNormal];
[self setBackgroundImage:[[UIImage imageNamed:#"btn_white_add.png"] stretchableImageWithLeftCapWidth:20.0 topCapHeight:0.0] forState:UIControlStateNormal];
[self addTarget:self action:#selector(didSelect) forControlEvents:UIControlEventTouchUpInside];
self.isPressed = NO;
}
return self;
}
#implementation ButtonsView
#synthesize listOfButtons;
- (id)initWithFrame:(CGRect)frame bundle:(NSArray *)data
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
listOfNames = [[NSArray arrayWithArray:data] retain];
listOfButtons = [[NSMutableArray alloc] init];
currentViewNumber = 0;
viewNumber = 0;
}
return self;
}
- (void)drawRect:(CGRect)rect
{
CGSize maximumLabelSize = CGSizeMake(300,24);
UIFont *buttonFont = [UIFont fontWithName:#"Helvetica" size:14.0];
float lineSize = 0;
float lineNumber = 0;
NSArray *listOfFrameX = [NSArray arrayWithObjects:
[NSString stringWithFormat:#"%d",FIRST_LINE_Y],
[NSString stringWithFormat:#"%d",SECOND_LINE_Y],
[NSString stringWithFormat:#"%d",THIRD_LINE_Y],
nil];
for (int i = 0; i < [listOfNames count]; i++) {
CGSize expectedLabelSize = [[[listOfNames objectAtIndex:i] objectForKey:#"name"] sizeWithFont:buttonFont
constrainedToSize:maximumLabelSize
lineBreakMode:UILineBreakModeTailTruncation];
if ((lineSize + expectedLabelSize.width) > 260) {
lineNumber++;
lineSize = 0;
}
if (lineNumber > 2) {
viewNumber ++;
lineSize = 0;
lineNumber = 0;
}
CGRect newFrame = CGRectMake(lineSize,
[[listOfFrameX objectAtIndex:lineNumber] floatValue],
expectedLabelSize.width+30,
24);
CustomButton *myButton = [[CustomButton alloc] initWithFrame:newFrame
title:[[listOfNames objectAtIndex:i] objectForKey:#"name"]
tag:[[[listOfNames objectAtIndex:i] objectForKey:#"id"] intValue]];
myButton.buttonViewNumber = viewNumber;
[listOfButtons addObject:myButton];
if (viewNumber == 0) {
[self addSubview:myButton];
}
lineSize += expectedLabelSize.width + 40;
[myButton release];
}
}
this way it works:
- (void)viewDidLoad
{
[super viewDidLoad];
placeholders = [[NSArray arrayWithObjects:
something,something, something,something,nil] retain];
CGRect frame = CGRectMake(10, 247, 300, 84);
buttonsView = [[ButtonsView alloc] initWithFrame:frame bundle:placeholders];
[self.view addSubview:buttonsView];
and like this is doesnt work:
- (void)getCompanyNames:(id)result
{
NSArray *listOfCompanies = (NSArray *)result;
CGRect frame = CGRectMake(10, 247, 300, 84);
buttonsView = [[ButtonsView alloc] initWithFrame:frame bundle:listOfCompanies];
[self.view addSubview:buttonsView];
}
i need to add the "buttonsView" object to self.view after the -viewDidLoad
drawRect: isn't exactly the place you should be creating subviews (Buttons are subviews) for your view. This should either go into initWithFrame: or awakeFromNib, depending on your view creation method: programmatically or using a nib.

UIButton failed to call functions?

I have a viewcontroller(mainViewController) and view class(UIView class, mainView). mainViewController, I called a method "generateView" from mainView class. Here is the code:
Method 1:
- (void) generateView {
container = [[UIScrollView alloc] initWithFrame: CGRectMake(10, 10, 500, 300)];
container.backgroundColor = [UIColor clearColor];
container.contentSize = CGSizeMake(500,1200);
container.showsVerticalScrollIndicator = YES;
[container setScrollEnabled:TRUE];
container.backgroundColor = [UIColor redColor];
int row = 0;
int col = 0;
for (int i = 0; i < 5; i++) {
if(i % 4 == 0 && i != 0){
row++;
col = 0;
}
UIButton *b = [[UIButton alloc] initWithFrame: CGRectMake(col*120, row*120, 100, 100)];
NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:[NSString stringWithFormat:#"%#/images/items/%i.png", HOSTADDR, i ]]];
[b setBackgroundImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal];
[b setBackgroundColor: [UIColor colorWithRed:0x42/255.0f green:0x30/255.0f blue:0x27/255.0f alpha:1]];
[b setTag: i];
[b addTarget:self action:#selector(testFunction:) forControlEvents:UIControlEventTouchUpInside];
[b setEnabled:TRUE];
[b setUserInteractionEnabled:TRUE];
[container addSubview:b];
col++;
}
[self addSubview:container];
}
- (void) testFunction: (id) sender {
NSLog(#"Function called. Sender tag number: %i", [sender tag]);
}
Method 2:
- (void) generateView {
container = [[UIScrollView alloc] initWithFrame: CGRectMake(10, 10, 500, 300)];
container.backgroundColor = [UIColor clearColor];
container.contentSize = CGSizeMake(500,1200);
container.showsVerticalScrollIndicator = YES;
[container setScrollEnabled:TRUE];
container.backgroundColor = [UIColor redColor];
int row = 0;
int col = 0;
for (int i = 0; i < 5; i++) {
if(i % 4 == 0 && i != 0){
row++;
col = 0;
}
UIButton *b = [[UIButton alloc] initWithFrame: CGRectMake(col*120, row*120, 100, 100)];
NSData *imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:[NSString stringWithFormat:#"%#/images/items/%i.png", HOSTADDR, i ]]];
[b setBackgroundImage:[UIImage imageWithData:imageData] forState:UIControlStateNormal];
[b setBackgroundColor: [UIColor colorWithRed:0x42/255.0f green:0x30/255.0f blue:0x27/255.0f alpha:1]];
[b setTag: i];
[b addTarget:mainViewController action:#selector(updateData:) forControlEvents:UIControlEventTouchUpInside];
[b setEnabled:TRUE];
[b setUserInteractionEnabled:TRUE];
[container addSubview:b];
col++;
}
[self addSubview:container];
}
What I really need is method 2, cuz I want to call the updateData in mainViewController, but no matter how i tried, the button is not calling the function thats supposed to be called. Any idea?
EDIT:
This is how I called the view class
- (void) loadContent: (id) sender {
[self removeSubmenus];
switch ([sender tag]) {
case 2001:
{
MainView *mainView = [[MainView alloc] initWithSubmenu:CGRectMake(420, 85, 0, 0)];
[self.view addSubview:mainView];
break;
}
default:
break;
}
}
You should set delaysContentTouches to YES on the UIScrollView.
You're also leaking a bunch of memory. Make sure you're releasing both the UIButton (b) and NSData (imageData) objects as soon as you're done with them.
--
EDIT: I tried your code and it works fine. But it seems you wanted all this code in a UIView, so I threw together a quick sample.
TestView.h
#import <UIKit/UIKit.h>
#interface TestView : UIView {}
#end
TestView.m
#import "TestView.h"
#implementation TestView
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIScrollView *container = [[UIScrollView alloc] initWithFrame: CGRectMake(10, 10, 500, 300)];
int row = 0;
int col = 0;
for (int i = 0; i < 5; i++) {
if(i % 4 == 0 && i != 0){
row++;
col = 0;
}
UIButton *b = [[UIButton alloc] initWithFrame: CGRectMake(col*120, row*120, 100, 100)];
[b setBackgroundColor: [UIColor colorWithRed:0x42/255.0f green:0x30/255.0f blue:0x27/255.0f alpha:1]];
[b setTag: i];
[b addTarget:self action:#selector(testFunction:) forControlEvents:UIControlEventTouchUpInside];
[container addSubview:b];
[b release];
col++;
}
[self addSubview:container];
}
return self;
}
- (void) testFunction: (id) sender {
NSLog(#"Function called. Sender tag number: %i", [sender tag]);
}
- (void)dealloc {
[super dealloc];
}
#end
TestController.h
#interface TestController : UIViewController { }
#end
TestController.m:
#import "TestController.h"
#import "TestView.h"
#implementation TestController
- (void) generateView {
TestView *tv = [[TestView alloc]initWithFrame:[self.view frame]];
[self.view addSubview:tv];
[tv release];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self generateView];
}
- (void)dealloc {
[super dealloc];
}
#end
Try adding this code to your method
container.delaysContentTouches = NO;
container.canCancelContentTouches = NO;
Pls modify your code to avoid memory leaks. Make sure you delete objects that you take ownership of.
Try this,
[b addTarget:mainViewController.view action:#selector(updateData:) forControlEvents:UIControlEventTouchUpInside];