I have one label, two button. One to +1 and one to -1 from the label.
I use following code:
.h
int counter;
IBOutlet UILabel *count;
}
-(IBAction)plus:(id)sender;
-(IBAction)minus:(id)sender;
.m
-(IBAction)plus {
counter=counter + 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
-(IBAction)minus {
counter=counter - 1;
count.text = [NSString stringWithFormat:#"%i",counter];
}
The two buttons are linked to the label(count) in IB.
Now to my question. If I want to have more buttons and labels like this, how can I do that?
I know I can copy the code and relinked them in IB but that gonna take to long.
And when the buttons are linked to the count label, it doesn't work to just copy them in IB, the buttons works but it counting the first label. I need to count every label each.
So, how can I do this and save time? Its gonna be many of those.
You can generate your buttons in series, store them in an NSArray, and do the same with the labels. Then you can relate them using their index in the arrays.
// Assuming a view controller
#interface MyVC: UIViewController {
NSMutableArray *buttons;
NSMutableArray *labels;
}
// in some initialization method
buttons = [[NSMutableArray alloc] init];
labels = [[NSMutableArray alloc] init];
for (int i = 0; i < numberOfButtonsAndLabels; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// configure the button, then
[self.view addSubview:btn];
[buttons addObject:btn];
UILabel *lbl = [[UILabel alloc] initWithFrame:aFrame];
// configure the label, then
[self.view addSubview:lbl];
[labels addObject:lbl];
[lbl release];
}
- (void)buttonClicked:(UIButton *)sender
{
NSUInteger index = [buttons indexOfObject:sender];
UILabel *label = [labels objectAtIndex:index];
// use index, sender and label to do something
}
Related
MainViewController contains UISegmentedControl with 3 segments.
SliderSubViewController contains a UISlider and -(void) sliderValueChanged:(UISlider*)sender
I want to add a code like this in SliderSubViewController.m but I'm stuck on how to access the UISegmentedControl and add an image:
- (void)viewDidLoad
{
[super viewDidLoad];
mainController = [[MainViewController alloc] initWithNibName:nil bundle:nil];
[minPrisSlider addTarget:self
action:#selector(sliderValueChanged:)
forControlEvents:UIControlEventValueChanged];
- (void)sliderValueChanged:(UISlider*)sender
{
NSUInteger index = (NSUInteger)(minPrisSlider.value + 0.5); // Round the number.
[minPrisSlider setValue:index animated:NO];
int progressAsInt =(int)(minPrisSlider.value + 0.5f);
NSString *newText =[[NSString alloc] initWithFormat:#"%d,-",progressAsInt];
minPrisText.text = newText;
if (minPrisSlider.value != 70) {
/*mainController.segmentedControl add main bundle image named "CheckboxChecked.png"
to current segment*/
}
}
If you have added SliderViewController as subview on MainViewController, One approach you can try is to just declare object of MainViewController in SliderViewController write #property and #synthesize, dont allocate it and while adding SliderView as subview just assign it as
sliderviewcontrollerObject.mainViewControllerObject = self;
now you can access segmentedControl from sliderview ass self.mainViewControllerObject.segmentedbar
Also you can try delegate approach.
I have the following code which takes a touch on one button and draws a border around that button, then makes sure that all the other buttons have no border (8 buttons total). This is a method in a singleton class called AnswerButtons. This code works fine.
- (IBAction)button1WasTouched:(id)sender {
NSLog(#"Hello from button 1");
// retrieve, modify and update clueAnsState
NSMutableArray *newCAS = [[GameData gameData].curData objectForKey:#"clueAnsState"];
[newCAS replaceObjectAtIndex:0
withObject:#"2"];
[[GameData gameData].curData setObject:newCAS
forKey:#"clueAnsState"];
// Highlight the pressed button & make sure other buttons are not highlighted
for (NSInteger idx = 0; idx < 8; idx++) {
NSString *temp = [newCAS objectAtIndex:idx];
if ([temp isEqualToString:#"1"]) {
UIButton *b = [[AnswerButtons answerButtons].buttons objectAtIndex:idx];
[[b layer] setBorderWidth:0.0f];
}
if ([temp isEqualToString:#"2"]) {
UIButton *b = [[AnswerButtons answerButtons].buttons objectAtIndex:idx];
[[b layer] setBorderWidth:2.0f];
}
}
}
Now, I need to use this code for all 8 buttons, so I should write a method with one argument, the button number to modify (pos). In the singleton class .m I put which is virtually the same code:
- (void)activateAnswerAtPos:(int)pos {
// retrieve, modify and update clueAnsState
NSMutableArray *newCAS = [[GameData gameData].curData objectForKey:#"clueAnsState"];
[newCAS replaceObjectAtIndex:pos
withObject:#"2"];
[[GameData gameData].curData setObject:newCAS
forKey:#"clueAnsState"];
NSLog(#"%#", newCAS);
for (NSInteger idx = 0; idx < 8; idx++) {
NSString *temp = [newCAS objectAtIndex:idx];
if ([temp isEqualToString:#"1"]) {
UIButton *b = [[AnswerButtons answerButtons].buttons objectAtIndex:idx];
[[b layer] setBorderWidth:0.0f];
}
if ([temp isEqualToString:#"2"]) {
UIButton *b = [[AnswerButtons answerButtons].buttons objectAtIndex:idx];
[[b layer] setBorderWidth:2.0f];
}
}
}
So I changed the first code chunk to make it a call to the new method:
- (IBAction)button1WasTouched:(id)sender {
NSLog(#"Hello from button 1");
[sender activateAnswerAtPos:0];
}
Unfortunately, I'm doing something wrong as I get the following exception:
2012-03-30 19:41:40.199 P3[6751:f803] Hello from button 1
2012-03-30 19:41:40.201 P3[6751:f803] -[UIRoundedRectButton activateAnswerAtPos:]: unrecognized selector sent to instance 0x6e709f0
I'm not sure what's going on here; several alternatives don't work either and I think my troubleshooting is sending me in the wrong direction. What's wrong with the way I am calling this method? Clearly I'm not even getting to run the method. TIA.
It's hard to follow what you are trying to do but I would probably send all button actions to one method like this
- (void)buttonTapped:(UIButton *)buttonTapped;
{
NSArray *buttons = [AnswerButtons answerButtons].buttons;
// some kind of switch statement of logic to perform options depending on which button
// Can use the following to get the index
// NSInteger buttonIndex = [buttons indexOfObject:buttonTapped]
for (UIButton *button in buttons) {
if (button == buttonTapped) {
// highlight
} else {
// remove highlight
}
}
}
You're calling -activateAnswerAtPos: on sender, which is the button that was touched. You should instead call it on the instance of the class that defines the -activateAnswerAtPos: method. It's not clear from your code what that is, but my guess is self:
[self activateAnswerAtPos:0];
I am fairly new to Objective-C, this is the first time I really don't know what to do.
I have a class - Parser - which creates UIImageViews, inits them with images and adds them to the UIView. The class also adds these UIImageViews to NSMutableArray - imgArray, which is a property of another class - Page.
Then, on the click of a button, I call the Page class from a Manager class, loop through the imgArray and try to set a new images for the UIImageViews in the array.
It doesn't work. Actually nothing I do to the UIImageViews doesn't work.
I try [img removeFromSuperView], [img setHidden:YES] and more. It doesn't response.
Here I declare the Array property in Page:
#property (nonatomic, retain) NSMutableArray *imgArray;
Here is the code from Parser where I create the image and add it to the array:
UIImageView *img = [[UIImageView alloc] initWithFrame: frame];
NSString *name = [c imageSource];
[img setImage: [UIImage imageFromBook: name]];
[view addSubview: img];
[c setImage:img];
if (!page.imgArray)
{
page.imgArray = [[NSMutableArray alloc] init];
}
[page.imgArray addObject:img];
[img release];
Here is the loop code from the Manager:
- (void) set3D:(bool)is3D
{
Page *page = [[DataManager data] currentPage];
int count = [page.imgArray count];
for (int i = 0; i < count; i++)
{
UIImageView *img = [page.imgArray objectAtIndex:i];
[img setImage:[UIImage imageNamed:image3DSource]];
}
}
Thanks in advance for any help!
There is no need to store the UIImageView's in an array.
When the UIImageView's are created, you can tag them with an arbitrary number, like.
#define K_MIN_IMGV 100
#define K_MAX_IMGV 120
- (void) setupViews
{
for (NSInteger count = K_MIN_IMGV; count < K_MAX_IMGV; ++count)
{
UIImageView *imgV = // create image view, set properties
imgV.tag = count; // tag the views for easy retrieval later
...
[mainView addSubview: imgV]; // add subviews
[imgV release], imgV = nil; // mainView now manages, release our allocation
}
}
// how to set new images
- (void) setupNewImages
{
for (NSInteger count = K_MIN_IMGV; count < K_MAX_IMGV; ++count)
{
UIImageView *imgV = (UIImageView *) [mainView viewWithTag: count]; // retrieve imageView
[imgV setImage: newImage]; // set new image
}
}
// To remove the imageView, you can use
UIImageView *imgV = (UIImageView *) [mainView viewWithTag: 123];
[imgV removeFromSuperview];
Have you tried to enumerate through the array using:
for(UIImageView* imageView in page.imgArray)
{
//Do code
}
This will tell you if there any imageViews in page.imgArray.
How are you adding objects to NSMutableArray and how are you initialising your NSMutableArray.
I remember having a problem adding objects to NSMutableArray but setting my init to solved this:
NSMutableArray* mutableArray = [NSMutableArray array];
Also what properties have you set on imgArray in page? Are you retaining the values?
Need to see more code to gain a fuller understanding.
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;
}
I'm trying to add button to a scroll view using a NSMutableArray. The code works fine in a twitter example I am using as a reference, but for some reason it is not working in this case. In the twitter search case the code is implemented in the main class. While in this case I am implementing it in the flipside view. Could anyone help me out since I am a bit new to Objective c.
Thanks in Advance.
Here is the init where the NSMutableArray Buttons is initialized
- (id)init
{
self = [super init]; // initialize the superclass members
if (self != nil) // if the superclass initialized properly
{
// creates list of valid directories for saving a file
NSArray *paths = NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory, NSUserDomainMask, YES);
// get the first directory
NSString *dir = [paths objectAtIndex:0];
// concatenate the file name "tagsIndex.plist" to the path
filePath = [[NSString alloc] initWithString:
[dir stringByAppendingPathComponent:#"tagsIndex.plist"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
// if the file does not exist, create an empty NSMutableDictionary;
// otherwise, initialize an NSDictionary with the file's contents
if ([fileManager fileExistsAtPath:filePath] == NO)
{
tags = [[NSMutableDictionary alloc] init];
} // end if
else
{
tags = [[NSMutableDictionary alloc]
initWithContentsOfFile:filePath];
} // end else
buttons = [[NSMutableArray alloc] init]; // create array
infoButtons = [[NSMutableArray alloc] init]; // create array
}
return self; // if self == nil, object not initialized properly
} // end method init
Here we have the method where we are adding the object to the buttons array but it stays empty.
- (void)addNewButtonWithTitle:(NSString *)title
{
// create a new button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
// give the button the title of the tag
[button setTitle:title forState:UIControlStateNormal];
// tell the button to call buttonTouched: when it is touched
[button addTarget:self action:#selector(buttonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[buttons addObject:button]; // add the UIButton to the end of the array
//This Doesn't add it stays 0;
// sort the NSMutableArray by the UIButton's titles
[buttons sortUsingSelector:#selector(compareButtonTitles:)];
[self refreshList]; // refresh the list of favorite search Buttons
// Adjust the content size of the view to include the new button. The
// view scrolls only when the content size is greater than its frame.
CGSize contentSize = CGSizeMake(scrollView.frame.size.width,
buttons.count * (BUTTON_HEIGHT + BUTTON_SPACING) + BUTTON_SPACING);
[scrollView setContentSize:contentSize];
}
Here is the dealloc where I release the buttons array.
- (void)dealloc {
[buttons release];
[super dealloc];
}
I can't Figure out where the mistake is.
Here is the Code that is supposed to add a new button.
- (IBAction)addTag:sender
{
// make the keyboard disappear
[ItemTitleField resignFirstResponder];
[QuantityField resignFirstResponder];
NSString *key = ItemTitleField.text; // get the text in tagField
NSString *value = QuantityField.text; // get the text in queryField
// test if either field is empty
if (value.length == 0 || key.length == 0)
return; // exit from the method
if ([tags valueForKey:key] == nil) // test if the tag already exists
[self addNewButtonWithTitle:key]; // if not, add a new button
[tags setValue:value forKey:key]; // add a new entry in tags
ItemTitleField.text = nil; // clear tagField of text
QuantityField.text = nil; // clear queryField of text
[tags writeToFile:filePath atomically:NO]; //save the data
} // end method addTag:
- (void)addNewButtonWithTitle:(NSString *)title
{
// create a new button
// UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *button = [[UIButton alloc] init];
or
UIButton *button = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain];
// give the button the title of the tag
[button setTitle:title forState:UIControlStateNormal];
// tell the button to call buttonTouched: when it is touched
[button addTarget:self action:#selector(buttonTouched:)
forControlEvents:UIControlEventTouchUpInside];
[buttons addObject:button]; // add the UIButton to the end of the array
//This Doesn't add it stays 0;
// sort the NSMutableArray by the UIButton's titles
[buttons sortUsingSelector:#selector(compareButtonTitles:)];
[self refreshList]; // refresh the list of favorite search Buttons
// Adjust the content size of the view to include the new button. The
// view scrolls only when the content size is greater than its frame.
CGSize contentSize = CGSizeMake(scrollView.frame.size.width,
buttons.count * (BUTTON_HEIGHT + BUTTON_SPACING) + BUTTON_SPACING);
[scrollView setContentSize:contentSize];
}