UIPickerView values - objective-c

I want UIPicker to start from 2 (0, 1 to be not displayed)
self.tmpArray = [NSMutableArray arrayWithCapacity:10];
for(int x = 2; x < 10; x++)
{
[self.tmpArray addObject:[NSNumber numberWithInt:x]];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.tmpArray count];
}
With the code above UIPicker shows 0,1,2,3 etc...

You're not in any way passing on the values from tmpArray, so they have no bearing on what UIPickerView displays.
You need to implement viewForRow:forComponent: and be able to supply suitable views when the picker view requests them.

Related

UIButton with random text/value or tag [duplicate]

This question already has answers here:
iOS: How do I generate 8 unique random integers?
(6 answers)
Closed 9 years ago.
I have 10 UIButtons created in historyboard, OK?
I want to add random numbers that do not repeat these numbers, ie, numbers from 0 to 9 that interspersed whenever the View is loaded.
I tried to find on Google and here a way to use my existing buttons ( 10 UIButton ), and just apply them to random values​​. Most ways found ( arc4random() % 10 ), repeat the numbers.
Here's one
here's another
here's another
All results found that creating buttons dynamically. Anyone been through this?
Create an array of the numbers. Then perform a set of random swapping of elements in the array. You now have your unique numbers in random order.
- (NSArray *)generateRandomNumbers:(NSUInteger)count {
NSMutableArray *res = [NSMutableArray arrayWithCapacity:count];
// Populate with the numbers 1 .. count (never use a tag of 0)
for (NSUInteger i = 1; i <= count; i++) {
[res addObject:#(i)];
}
// Shuffle the values - the greater the number of shuffles, the more randomized
for (NSUInteger i = 0; i < count * 20; i++) {
NSUInteger x = arc4random_uniform(count);
NSUInteger y = arc4random_uniform(count);
[res exchangeObjectAtIndex:x withObjectAtIndex:y];
}
return res;
}
// Apply the tags to the buttons. This assumes you have 10 separate ivars for the 10 buttons
NSArray *randomNumbers = [self generateRandomNumbers:10];
button1.tag = [randomNumbers[0] integerValue];
button2.tag = [randomNumbers[1] integerValue];
...
button10.tag = [randomNumbers[9] integerValue];
#meth has the right idea. If you wanna make sure the numbers aren't repeating, try something like this: (note: top would the highest number to generate. Make sure this => amount or else this will loop forever and ever and ever ;)
- (NSArray*) makeNumbers: (NSInteger) amount withTopBound: (int) top
{
NSMutableArray* temp = [[NSMutableArray alloc] initWithCapacity: amount];
for (int i = 0; i < amount; i++)
{
// make random number
NSNumber* randomNum;
// flag to check duplicates
BOOL duplicate;
// check if randomNum is already in your array
do
{
duplicate = NO;
randomNum = [NSNumber numberWithInt: arc4random() % top];
for (NSNumber* currentNum in temp)
{
if ([randomNum isEqualToNumber: currentNum])
{
// now we'll try to make a new number on the next pass
duplicate = YES;
}
}
} while (duplicate)
[temp addObject: randomNum];
}
return temp;
}

Logically Layout Multiple Items into a View by their X and Y coordinates

I have a UIView and I want to add a series of programmatically generated UIButtons to it.
I've created a method that places each button (of standard size) via a CGPoint.
I want to lay these buttons out 3 in a row, over as many rows as needed.
I've no idea how to go about programatically generating the x and y coordinates to place the items on the view. I'm stuck on how to get the buttons to drop onto a new row once three have been placed.
Here's my code, I want to process something in this method to return the coordinates based only upon the index of the button:
- (CGPoint)calculateCoordinatesWithIndex:(NSInteger)index{
NSInteger x = 100;
NSInteger y = 50;
return CGPointMake(x, y);
}
The only solutions I can think of seem really clunky and inefficient.
Hello what about something like :
#define BUTTON_WIDTH 100
#define BUTTON_HEIGHT 50
- (void) placeButtonsFromButtonsArray:(NSArray *) buttons{
CGFloat currentXPosition = 0.0;
CGFloat currentYPosition = 0.0;
for (NSUInteger i = 0; i < [buttons count]; i++){
b.frame = CGRectMake(currentXPosition, currentYPosition, BUTTON_WIDTH, BUTTON_HEIGHT);
if (i%3 == 2){
currentXPosition = 0;
currentYPostion += BUTTON_HEIGHT;
}
else currentXPosition += BUTTON_WIDTH;
}
}
or Using your method :
- (CGPoint)calculateCoordinatesWithIndex:(NSInteger)index{
//computes on which line the button should be
NSUInteger line = (index/3);
//computes on which row the button should be
NSUInteger row = (index%3) ;
return CGPointMake(row*BUTTON_WIDTH, line*BUTTON_HEIGHT);
}
If you're targeting iOS 6, you could use a UICollectionView for this.
try this,
in .h
{
NSInteger x;
NSInteger y;
int noOfbtninrow;
}
-(void)viewDidload
{
x = 100;
y = 50;
noOfbtninrow=0;
}
- (CGPoint)calculateCoordinatesWithIndex:(NSInteger)index
{
if(noOfbtninrow==3)
{
x=100;
y=y+100
noOfbtninrow=0;
}
else
{
noOfbtninrow++;
x=x+100;
}
return CGPointMake(x, y);
}

loop Nsmutable arrray of uiimages from end to beginning

I have an NSMUtable array of images where a different image is displayed with a previous and a next button, but when I get to the end of the array the simulator crashes. I want to loop the end of the array to the beginning so that when I get to the end of the array of images when I hit the next button again it loops back to the first image, also when Im at the first image if I hit the previous button it loops to the last image with no crashes
What you want is a circular array, which is easy to implement using a standard NSMutableArray. For instance, say you store your images in an array called imageArray and use a simple variable to keep track of the index of your current image, like:
int currentImageIndex = 0;
...then you might implement nextImage and previousImage like:
- (UIImage*) nextImage {
currentImageIndex = (currentImageIndex + 1) % [imageArray count];
return [imageArray objectAtIndex:currentImageIndex];
}
- (UIImage*) previousImage {
currentImageIndex--;
if (currentImageIndex < 0) {
currentImageIndex = [imageArray count] - 1;
}
return [imageArray objectAtIndex:currentImageIndex];
}
Then just use nextImage and previousImage whenever you want to step through the array, and problem solved.
Simple enough to do. all you need to do is create a check to see if you're on the last element, and if so, set your tracker (like count or i etc) to 0 again,
Heres the psudo code
//set index
if ( array [ index ] == len(array) - 1) //at end
{
index = 0
}
if(array [index] == -1)//at beginning
{
index = len(array) -1
}
// do something with array[index]
I want to propose this solution:
A property for the selected UIImage, a NSInteger property to hold the current index.
-(IBAction) nextButtonTapped:(id)sender
{
self.currentIndex = self.currentIndex++ % [self.images count];
self.selectedImage= [self.images objectAtIndex:self.currentIndex];
[self reloadImageView];
}
-(IBAction) previousButtonTapped:(id)sender
{
self.currentIndex--;
if (self.currentIndex < 0)
self.currentIndex += [self.images count];
self.selectedImage= [self.images objectAtIndex:self.currentIndex];
[self reloadImageView];
}
-(void)reloadImageView
{
//do, what is necessary to display new image. Animation?
}

Label display not instant with iPhone app

I am developing an application for the iPhone. The question I have is how to display a new label with a different text every .5 seconds. For example, it would display Blue, Red, Green, Orange and Purple; one right after one another. Right now I am doing this:
results = aDictionary;
NSArray *myKeys = [results allKeys];
NSArray *sortedKeys = [myKey sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
int keyCount = [sortedKeys count];
while (flag == NO) {
NSTimeInterval timeMS = [startDate timeIntervalSinceNow] * -10000.0;
if (timeMS >= i) {
ii++;
i += 1000;
NSLog(#"endDate = %f", timeMS);
int randomNumber = rand() % keyCount + 1;
lblResult.text = [results valueForKey:[sortedKeys objectAtIndex:(randomNumber - 1)]];
result = [results valueForKey:[sortedKeys objectAtIndex:(randomNumber - 1)]];
lblResult.text = result;
}
if (ii > 25) {
flag = YES;
}
}
lblResult.text = [results valueForKey:[sortedKeys objectAtIndex:(sortedKeys.count - 1)]];
this function is called at the viewDidAppear Function and currently isn't displaying the new labels. It only displays the one at the end. Am I doing anything wrong? What would be the best method to approach this?
The problem is that you're not giving the run loop a chance to run (and therefore, drawing to happen). You'll want to use an NSTimer that fires periodically and sets the next text (you could remember in an instance variable where you currently are).
Or use something like this (assuming that items is an NSArray holding your strings):
- (void)updateText:(NSNumber *)num
{
NSUInteger index = [num unsignedInteger];
[label setText:[items objectAtIndex:index]];
index++;
// to loop, add
// if (index == [items count]) { index = 0; }
if (index < [items count]) {
[self performSelector:#selector(updateText:) withObject:[NSNumber numberWithUnsignedInteger:index] afterDelay:0.5];
}
}
At the beginning (e.g. in viewDidAppear:), you could then call
[self updateText:[NSNumber numberWithUnsignedInteger:0]];
to trigger the initial update.
You'd of course need to ensure that the performs are not continuing when your view disappears, you could do this by canceling the performSelector, or if you're using a timer, by simply invalidating it, or using a boolean, or ...
And if you want to get really fancy, use GCD :)

Enter fractions in a uitextfield from 3 UIPickers?

So what I'm intending to do is instead of typing in decimals, I want to be able to enter whole numbers and fractions in a textfield. Or select them from a UIPicker.
Example: Feet, Inches, fractions.(2 - 4 1/2).
What's the best way to accomplish this? Please be detailed in your answer. Thank you in advance!
Update: Ok maybe a little more detail is needed.
I'm going to use the picker, and want to display 5 rows like this:
<Ft> <In>
0 0 S 0 0 S 1/16
1 1 P 1 1 P 1/8
2 2 A 2 2 A 3/16
3 3 C 3 3 C 1/4
4 4 E 4 4 E 5/16
ect...all the way to 9, and to 15/16 for the fractions. (Note the space between Ft and Inches and title for row).
Ok, So I was able to get 3 pickers to display on screen just how I wanted, my biggest issue is getting it to display in the textfield properly. So just how the example is above, ft has it's own picker, inches has it's own, and fractions has it's own, How would you get all three to display as "00ft 00 0/0in" in one text field?
UPDATE: the code below is correct, make sure you create an IBOutlet for your UIView that contains the pickers, and hook it up in IB.
.m file
feetArray = [[NSMutableArray alloc] init];
for(int feet = 0; feet <= 9; feet ++){
NSString *feetString = [NSString stringWithFormat:#"%d%", feet];
[feetArray addObject:feetString]; // Add the string.
}
inchArray = [[NSMutableArray alloc] init];
for(int inch = 0; inch <= 12; inch ++){
NSString *inchString = [NSString stringWithFormat:#"%d%", inch];
[inchArray addObject:inchString]; // Add the string.
}
fractionArray = [[NSMutableArray alloc] init];
for(int frac = 0; frac <= 15; frac ++){
NSString *fractionString = [NSString stringWithFormat:#"%d/16", frac];
[fractionArray addObject:fractionString]; // Add the string.
}
}
//How many rows in each Picker.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
if (pickerView.tag == 1) {
return 2;
}
if (pickerView.tag == 2) {
return 2;
}
return 1;
}
//Selects array for each picker.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (pickerView.tag == 1) {
return [feetArray count];
}
if (pickerView.tag == 2) {
return [inchArray count];
}
return [fractionArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerView.tag == 1) {
return [feetArray objectAtIndex:row];
}
if (pickerView.tag == 2) {
return [inchArray objectAtIndex:row];
}
return [fractionArray objectAtIndex:row];
}
//Formats the textfield based on the pickers.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *result = [feetArray objectAtIndex:[feetPicker selectedRowInComponent:0]];
result = [result stringByAppendingFormat:#"%#ft", [feetArray objectAtIndex:[feetPicker selectedRowInComponent:1]]];
result = [result stringByAppendingFormat:#" %#", [inchArray objectAtIndex:[inchesPicker selectedRowInComponent:0]]];
result = [result stringByAppendingFormat:#"%#", [inchArray objectAtIndex:[inchesPicker selectedRowInComponent:1]]];
result = [result stringByAppendingFormat:#" %#in", [fractionArray objectAtIndex:[fractionPicker selectedRowInComponent:0]]];
RiseTextField.text = result;
}
By setting up UIPickerView object as the inputView, you won't need to worry about text input. Tapping on the text field would bring up the picker and make the input constrained just as you want it. You can either subclass or set them directly in your controller. I set it up as a subclass here. Its a rough implementation of what you need as I understand it. You can take a look and see if it helps.
I would advice to use a picker, it's way easier then typing fractions and will prevent the input of incorrect fractions.
There are two ways to get the fractions into your UIPicker, use the pickerView:titleForRow:forComponent: method of your UIPicker delegate to give the fraction as a string. You can use UTF8 fraction characters like ¼ with this function.
If is not giving enough flexibility. You could make images of the fractions and put the images into the picker by using the pickerView:viewForRow:forComponent:reusingView: method of your delegate.
The documentation will give you lots of information! Good luck!
It sounds like you want something like the date picker with multiple wheels to choose each part of the distance. Unfortunately there isn't a way to do this. You have 2 options though. The simple option is to use several pickers next to each other. It wont look quite the same but it's simple. The more complicated option is to build one with UIScrollViews and style it to look the way you want it too.