How to reference iOS UITextFields - ios

I am creating a crossword puzzle-type app, and am using the following code to make the grid:
- (void) viewDidLoad{
[...]
//we are inside 2 loops (puzzleRow and i), 15 rows (puzzleRow), 15 cols (i)...
UITextField *inputBox = [[UITextField alloc] initWithFrame:letterFrame];
key = (puzzleRow * 100) + i;
[inputBox setTag:key];
[....]
}
Later, I want to reference the UITextField and get their value, check it against the correct answer, etc.
- (IBAction)checkSolutionButton:(id)sender {
int i = 1;
for (id obj in self.Puzzle) {
int len = [obj length];
for(int j = 0; j < len; j++){
NSRange range = NSMakeRange(j, 1);
NSString *answer = [obj substringWithRange:range];
int key = (i * 100) + j;
UIView *userGuessSquare = [self.view viewWithTag:key];
UITextField *userGuessTextField = [userGuessSquare viewWithTag:key];
NSString *guess = userGuessTextField.text;
NSLog(#"guess: %#", guess);
}
}
}
self.Puzzle is an NSArray of strings (ANSWER1..ANSWER2,ANSWER3..ANSWER4) constituting a crossword puzzle's rows, dots are black squares. The UIView are holders for the UITextField, each UIView and its UITextField has an identical key.
Here I am stuck. I get a warning Incompatible pointer types initializing UITextField with an expression type UIView I thought it was a subclass?
NSString *guess = userGuessTextField.text;
is a no go.
QUESTION:
How can I make a bunch of UITextField(s) and then access them and their values later?
(EDITED to include entire IBAction method).

Using the tags should be fine. To get the UITextField you should be doing this:
UITextField *userGuessTextField = (UITextField*) [self.view viewWithTag:key];
NSString *guess = userGuessTextField.text;
This will cast the UIView to the more specific UITextField, which is ok since you know you've used it. Make sure your tags start above 0 as well.

Related

Does characterAtIndex only have to be used for an NSString? And what is the main purpose of characterAtIndex?

I am writing an app on xcode and I am working on the code for the guess button so if the user enters a letter which is correct then the letter will appear in the location, length of the word in the label. I am using a characterAtIndex but an error continues to occure and I don't truly understand what the point of characterAtIndex is. This is my code so far.
#property (weak, nonatomic) IBOutlet UITextField *input; //user input
#property (weak, nonatomic) IBOutlet UILabel *Guessesinc; //number of incorrect guesses
#property (weak, nonatomic) IBOutlet UILabel *word; //the state of word as the user is guessing
#property (weak, nonatomic) NSString *rndw; //the correct and unknown word
- (IBAction)Guess;
- (IBAction)Guess
{
bool match = NO;
NSRange inputRange;
char charinput = [input characterAtIndex: 0];
for(int i = 0; i < self.rndw.length; i++)
{
char tempString = [self.rndw characterAtIndex: i];
if (charinput ==tempString)
{
match = YES;
inputRange = NSMakeRange(i, 1); //location, length
self.word.text = [self.word.text stringByReplacingCharactersInRange: inputRange withString: input];
}
The input characterAtIndex does not work but I do not understand why. Is there a way to fix this issue. If this code did run this portion of the code should produce something like this --d-. So for example if the user entered a d and the correct word is code the word label should look like --d-. Would this code work for what it had to do??
This answer makes a few guesses:
The input text field contains the letter the user entered for the current guess.
The word label shows the current state of the exposed word as the user make their guesses.
rndw is the current word the user is trying to guess.
Given those assumptions about your code, your Guess method is close. It seems your biggest issue is the attempt to get the first letter from the input text field. You are trying to call characterAtIndex: on a UITextField instead of on the field's text property (which is an NSString). You are also attempting to replace a substring with a UILabel.
Here's your Guess method with a few little changes and cleanup. Also note that it is standard convention that variable and method names start with lowercase letters and class names start with uppercase letters.
- (IBAction)guess
{
bool match = NO;
unichar charinput = [self.input.text characterAtIndex:0];
for (NSInteger i = 0; i < self.rndw.length; i++)
{
char tempChar = [self.rndw characterAtIndex:i];
if (charinput == tempChar)
{
match = YES;
NSRange inputRange = NSMakeRange(i, 1); //location, length
self.word.text = [self.word.text stringByReplacingCharactersInRange:inputRange withString:self.rndw.substringWithRange:inputRange];
}
This line:
char charinput = [input characterAtIndex: 0];
...is wrong.
Input is a UILabel. A UILabel is not an NSString. You probably want something like this:
NSString *inputString = self.input.text;
if (inputString.length == 0) {
return; //Don't try to fetch a character from an empty string.
}
char charinput = [input characterAtIndex: 0];
However, even that doesn't make much sense because input is a UILabel, which is a display-only field, not an input field. If you're trying to collect text from the user you want a UITextField or UITextView. For gather a single line of text from the usr a UITextField is probably what you want.
It also isn't clear why you first try to fetch the character from index 0 in your input UILabel, and then later try to fetch characters from a string self.rndw that you never seem to initialize. I guess rdnw is the word the user is supposed to be guessing?

Create Two UILabels dynamically using Objective C

In one array I have one string and one more array I want to display this dynamically in custom cell. My array structure is given below. It will change according to data coming from web service.
{
subDescription = (
"Worship Hours 5.00am to 12.30pm & 4.00pm to 10.00pm",
"The temple is open all days of the week"
);
subHeading = Hours;
}
And i tried like this using this format i can display subHeading Value only how to display subDescription array
float xCoordinate=10.0,yCoordinate=30.0,width=320,height=40;
float ver_space=20.0;
for (int i = 0; i <test.count; i++)
{
NSDictionary *lanuage=[test objectAtIndex:i];
NSString *work=[lanuage objectForKey:#"subHeading"];
NSArray *er=[lanuage objectForKey:#"subDescription"];
UILabel *label = [[UILabel alloc] initWithFrame:
CGRectMake(xCoordinate,yCoordinate,width,height)];
label.text = work;
[events.contentView addSubview:label];
yTCoordinate=yTCoordinate+heightT+ver_space;
}
I am not sure that I understand, but why dont you use CollectionView instead of a label. There you can define header cell and sub cells. I think this fits your problem.
In case that you do not want to use collection view you can adjust your code and iterate with loop through your sub items array.
for (NSString *item in er) {
UILabel *label = [[UILabel alloc] initWithFrame:
CGRectMake(xCoordinate,yCoordinate,width,height)];
label.text = item;
[events.contentView addSubview:label];
yCoordinate=yCoordinate+height+ver_space;
}

compare two UIButton.tag elements in one array objective-c

I have an array called '_orderOfCardPlacement' which gets objects put in it after every turn of my game. These objects are UIButtons which have a number of details such as setImage, setBounds, setCenter and most importantly to this question setTag. There are two possible outcomes for setTag either '1' or '2', They are initially set with one or the other and this can be changed via another method which is called every turn. What i need to do is look through this array and see how many times '1' has come up and how many times '2' has come up and then compare that result. So if '1' comes up nine times and '2' comes up 7 times then '1' wins in this case. So when i NSLog my array (say after one turn) i get this:
"<OBShapedButton: 0x7ff6f968e6a0; baseClass = UIButton; frame = (103 387.5; 150 135); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; tag = 1; layer = <CALayer: 0x7ff6f968e8a0>>"
and subsequent turns will add more buttons to the array. But I need to know once this array is full and the game is complete how to access the 'tag = ' part of the objects to compare. Thanks for any advice, ill add more code if necessary!
Here's the solution in full, if there's a more elegant way to do what i'm doing here, definitely interested to know!
//set the amount of cards each player has
_howManyCardsForComputer = 0;
_howManyCardsForPlayer = 0;
for (int i = 0; i < _orderOfCardPlacement.count; i++) {
UIButton *auxButton = (UIButton *) [_orderOfCardPlacement objectAtIndex:i];
NSInteger playerScore = auxButton.tag;
NSMutableArray *totalScoreArray = [[NSMutableArray alloc] init];
[totalScoreArray addObject:[NSNumber numberWithInteger:playerScore]];
for (int j = 0; j < totalScoreArray.count; j++) {
if ([[totalScoreArray objectAtIndex:j] isEqualToNumber:[NSNumber numberWithInteger:1]]) {
_howManyCardsForPlayer++;
}
if ([[totalScoreArray objectAtIndex:j] isEqualToNumber:[NSNumber numberWithInteger:2]]) {
_howManyCardsForComputer++;
}
}
}
_playerScore.text = [NSString stringWithFormat:#"Players cards %i", _howManyCardsForPlayer];
_playerScore.hidden = NO;
_computerScore.text = [NSString stringWithFormat:#"Computers cards %i", _howManyCardsForComputer];
_computerScore.hidden = NO;
I am not sure if I understood clearly what you want to achieve. If your buttons are stored in a NSMutableArray, you can check their tags by geting the i-th element (inside a for-loop) and apply a casting.
NSMutableArray *arrayWithButtons = [[NSMutableArray alloc] init];
//... Fill the array
//Check tags
for(int i=0; i<numButtons; i++){
UIButton *auxButton = (UIButton*) [arrayWithButton objectAtIndex:i];
int auxTag = auxButton.tag;
//... perform the proper operations
}
I hope I understand it well, and this can help you.

Adding textfield input to label

I feel like this is a rookie question but I'm stumped. The app will become much more complex than this (subtraction, division, multiplication, math) but in order to work from a foundation... Well, I don't even have a foundation.
-(IBAction)change:(id)sender {
NSString *xText = x.text;
int xValue = [xText intValue];
NSString *yText = y.text;
int yValue = [yText intValue];
int zValue = xValue + yValue;
NSString *zText = [NSString stringWithFormat:#"%d", zValue];
zText = z.text;
Basically what I'm trying to do right now is have two separate text fields collect user-typed numbers. When the "Calculate" button is pressed, the label will change to show the answer. (i.e. x = 4, y = 3, press calculate, z label changes to 7)
My guess is you would like to add the zText to a label?
Simply go:
[label setText:zText];
Where label is the IBOutlet to your label

Title of Segmented Control does not fit, overlaps

In my segmented control, sometimes the title is wider than fits its segment. How can I make it truncate?
Let's say the title of segment 1 is Text overlaps and segment 2 is named ok.
How I want it to look:
[Text ov...| ok ]
What it looks like:
T[ext overla|ps ok ]
What I tried:
Setting the width of the segment programmatically setWidth:forSegment. Still overlapping, not truncating.
Studying the properties of UISegmentedControl
Do I have to truncate it myself, before setting the title of the segment?
You have to truncate it yourself.
There is no public API for setting the truncation. Even if you dig through the UISegmentedControl's private view hierarchy, find the labels, and set lineBreakMode to UILineBreakModeTailTruncation, it won't truncate the labels for you. (I tried.)
EDIT: I got this to work. It's not pretty, it might stop working in a future iOS release, and it might get you rejected from the App Store.
static void fixLineBreakMode(UIView *view)
{
if ([view respondsToSelector:#selector(setLineBreakMode:)]) {
[(id)view setLineBreakMode:UILineBreakModeTailTruncation];
[view setFrame:CGRectInset([view.superview bounds], 6, 0)];
} else {
for (UIView *subview in view.subviews)
fixLineBreakMode(subview);
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
fixLineBreakMode(self.segmentedControl);
}
I had the same challenge when I needed to populate a segmented control with x number of segments. Some titles were overhanging. I have tried to truncate the titles in middle if they were too long. I did something like:
NSString *s = #"This title is too long to fit";
NSMutableString *mS = [[NSMutableString alloc] init];
int len = [s length];
if (len > 10) {
for (int i = 0; i < len; i++) {
unichar ch = [s characterAtIndex:i];
if(i > 3 && i < 6){
[mS appendString:#"."];
} else {
[mS appendString:[NSString stringWithFormat: #"%C", ch]];
}
}
}
This is just to give you some idea. You can limit the number of dots in the middle, just count the number of dots appended and stop adding when e.g. it reaches 3. When you have the truncated string you can use that to set a segment title. The same logic for head, tail truncating.

Resources