Drawing one NSString in multiple rects - iphone

I have a really long string, with thousands of line with a default font. So rather than draw the whole thing out in one table view cell, I'm going to make several cells to draw the same string, each drawing the next part of the string.
I'm having a hard time finding a starting point. Say I draw the first 500 pixels of height of the string in the rect - how do I know where to start in my second rect? If it's the same string, how can I specify for it to draw only some parts of the string?
Each cell will know it's own row number, so I'll be able to determine where exactly in the table I am, I just don't know how the string will know which part it's supposed to draw..
Or another question would be: how can I break up one string into multiple strings based on a certain number of lines?
Edit: Here are some NSString methods I'm finding that might be useful, but I still don't know how I would use them in my case:
- (void)getLineStart:(NSUInteger *)startIndex end:(NSUInteger *)lineEndIndex contentsEnd:(NSUInteger *)contentsEndIndex forRange:(NSRange)aRange
- (NSRange)lineRangeForRange:(NSRange)aRange

Use substringWithRange: This will allow you to select a start and end point of the string. I would grab each section by a number of characters. So section 1 would be 0-500 section 2 would be 500-1000. The problem here would be you may cut off in the middle of a sentence. You can use something like lineRangeForRange to determine your ranges for the substring.
lineRangeForRange
Returns the range of characters representing the line or lines containing a given range.
- (NSRange)lineRangeForRange:(NSRange)aRange
Parameters
aRange
A range within the receiver.
Return Value
The range of characters representing the line or lines containing aRange, including the line termination characters.
EDIT
NSString *string = #"tjykluytjghklukytgjhkkghkj sdkjlhfkjsadgfiulgeje fuaeyfkjasdgfueghf aksjgflkj. wyruehskjluishfoeifh uasyeajhkfa uiyelkjahsdf uayekljshdf aehkfjsd. \n I iheio;fajkdsf sdfhlueshkfjskdhf ujhelkjfh. luehljkfhlsdf. leufhlkjdshfa. \n euoiywhfldsjkhf euyhfsdlkj. ewhlkjfsd. euilhfsdkjishdkjf euhjklsfd. \n";
NSLog(#"string length:%i", [string length]);
NSRange range;
range.length = [string length]/2;
range.location = 0;
NSLog(#"LineRangeForRange:%i", [string lineRangeForRange:range].length);
NSLog(#"Substring:%#", [string substringWithRange:[string lineRangeForRange:range]]);
Log displays:
string length:295
LineRangeForRange:148
Substring:tjykluytjghklukytgjhkkghkj sdkjlhfkjsadgfiulgeje fuaeyfkjasdgfueghf aksjgflkj. wyruehskjluishfoeifh uasyeajhkfa uiyelkjahsdf uayekljshdf aehkfjsd.
So what this did was I supplied LineRangeForRange a range which was from zero to half of the string. It could the last end line "\n" with in that range. Then I grabbed that substring

Doesn't sound like a way I would wanna read text in an app. Why not use a textView?
Edit: my recommendation wasn't to put a textView in a tableViewCell but to display the beginning of the text truncated and on click push a viewControllers that displays a textView. Kind of like Mail does.

Related

NSTextField: How to detect when a string is too long?

In my UI I have an NSTextField (used as a label). This text field's string value changes dynamically. I'd like to know when its string value is too long to display. I've configured the text field to truncate its contents:
myLabel.lineBreakMode = NSLineBreakMode.ByTruncatingTail
which works fine but I need to know when truncation occurs because in that situation I need to do something else in my UI.
First of all, calculate number of character the label can take (determine the maximum number of characters a UILabel can take).
Suppose, the label takes x characters then check, if(x < label.text.characters.count) { //Do you work.}

Check if textfield text is almost equal to string

I have a UITextField called textfield. And I have this code to check if the text in the textfield is equal to "exampletext"
if ([textfield.text isEqualToString:#"exampletext"]) {
NSLog(#"Correct");
} else {
NSLog(#"Wrong");
}
But I also want to check if the text in the textfield is almost equal to "exampletext", if the text is almost the same as "exampletext". Like if the text was "eampletex" I want to NSLog(#"Close")
Are there any ways to check if the textfield text is like 50% equal to "exampletext"?
Or any ways to check if the textfield text has 50% the same characters as "exampletext"?
Or something else like that?
What you are looking for is an implementation of the levenshtein distance, levenshtein("hello", "hallo") => 1, levenshtein("hello", "ellos") => 2. You can check this library.
Once you have the distance between the two strings, you could get it as a percentage calculating: percentage = 100 * levenshtein(original,other) / length(original)
Here's my go at it. Create a custom character set from the string you want to match. Check each character in the texfield.text against that character set, and if the number of matches is close to the number of letters in the string, do something..
NSString *testString = #"wordToCompare";
NSString *textFromTextfield = textfield.text;
//create a custom character set from the word you want to compare to...
NSCharacterSet *characterSetForString = [NSCharacterSet characterSetWithCharactersInString:testString];
//keep track of how many matches...
int numberOfCharsThatMatchSet = 0;
for (int x = 0; x < [textFromTextField length]; x++) {
unichar charToCheck = [textFromTextField characterAtIndex:x];
if ([characterSetForString characterIsMember:charToCheck] == YES) {
numberOfCharsThatMatchSet++;
}
NSLog(#"%d", numberOfCharsThatMatchSet);
}
// if the number of matches is the same as the length of the word + or - 2...
if ((numberOfCharsThatMatchSet > [testString length] - 2 ) && (numberOfCharsThatMatchSet < [testString length] + 2 )) {
NSLog(#"close match...");
}
Not sure if this is 100% what you're looking for, but maybe it will help anyway...
I'm sure there might be some open source out there somewhere that would do this for you..however, one approach I can think of that will give you a bit of a lead...
Sort out the characters of both your strings into arrays. Determine which string you want to be the master string and grab the string length of it.
Now compare each character. Ex: Word 1: hello, Word 2: ello.
Each time a letter is found add one to a count. If by the end of your looping your count is 80% of the original length you grabbed from the master string or greater then you most likely have a partial match.
So for our example Word 1 will be our master string and its length is 5. "ello" contains 4/5 characters and therefore is matches 80% of the original string.
I don't think there is an easy way (with several lines of code) of solving this. There are several algorithms you might consider and pick the one which suits your needs most.
You should look at this question. Although it has been designed and answered for another language, you asked for a way or method so you have your solution there.

Compare, Getting string from a label

I'm making a word game and I've finally come up to one of the most important parts of my game, the compare part.
I got this label which will be invisible when it launches with the word that has to be guessed displaying in it with a random word generator. For example the word is: GARAGE
Now, for my game I have to compare the word with the input now I've already done this with the entire word with NSString but I want it to compare every letter. I want to be able to show that if the input has G as the first letter aswell, like garage. I want it to do something.
I want to know if this is possible and which methods you would use. I was thinking about making 6 strings since all my random words have 6 letters, and then break the word to 6 strings and the input aswell and then compare strings?
Hope someone has some usefull tips or example code thanks
So, assuming your string to be guessed...
NSString *stringToGuess = #"GARAGE";
and you were checking to see if it started with "GA"
NSString *myString = #"GA";
you would check it with hasPrefix:
if ([stringToGuess hasPrefix:myString]) {
// <stringToGuess> starts with <myString>
}
The documentation for NSString describes lots of neat methods for just about anything string related.
hasPrefix will let you tell if one string begins with another string. There's also characterAtIndex. You could use that to get one character from each string and compare it to the other.
You could write a method that would take an integer index and compare the two strings at that index:
- (BOOL) compareStringOne: (NSString *) stringOne
toStringTwo: (NSString *) stringTwo
atIndex: (NSUInteger) index;
{
if ([stringOne length] < index+1 || [stringTwo length] < index+1)
return FALSE;
return [stringOne characterAtIndex: index] == [stringTwo characterAtIndex: index];
}

UILabel splitting

if I have a UILabel: label1.text (maximum length 6 character) In this example GARAGE is the word in it.
is it possible to have code that would make
label1a: G
label1b: A
label1c: R
label1d: A
label1e: G
label1f: E
I need this so I can compare every character in a word with every character in a other word.
Been struggling with this for a couple of days now :S
edit
I got a random word generator that generates word with a length of 6 like 'GARAGE' or 'SAILOR' it generates it into a label for this We'll call the label: 'randomword.text'
now We got a input label where the character display that we put in with our own made keyboard. this label is 'input.text'
now we can compare those 2 labels with if (randomword.text == input.text') { NSLog: #'these words are the same' };
What I want to do is to seperate every letter in random.text: so have label1 say G, label2 say A, label3 say R, label4 say A, label5 say G, label6 say E.
If I separate my input.text in the same way like I did above with random.text I got another 6 UILabel for example have this one separated in label7,8,9,10,11,12. Now I can compare label 1 to label 7, label 2 to 8. etc That way I can see if Letters are on the place they should be even if the entire word do not equal each other.
Still confused by all that stuff about labels. I don't think your question has anything to do with labels, but with comparing strings or parts of them. So if you wan't to check if to strings are equal use
[aString isEqualToString:anotherString]; (not ==).
If you want to extract a letter from a string use
[aString characterAtIndex:i]; or [aString substringWithRange:NSMakeRange(i, i+1)] .
If you want to check if a letter is on a certain position (say i) in a string use:
NSString *aLetter;
[[aString substringWithRange:NSMakeRange(i, i+1)] isEqualToString:aLetter];
or
unichar aLetter;
[aString characterAtIndex:i] == aLetter;
If you want to get 'what's shown on a UILabel' as NSString use aLabel.text .
Hope that helps.

Objective C - Adding characters at specific parts of a string

I have made a quadratic equation solver for the iPhone and when the text box is clicked, my own custom keypad appears. I have a button that changes whether the number is positive or negative. Right now I what happens is that when the button is pressed (0 - current value of text) is what is displayed in the text box, so if the number is positive, it will become negative and if it is negative it will become positive. I am having some problems doing this so what I wanted to is to put a minus sign at the beginning of the string if the number is positive and if the number is negative, the minus sign will be removed. Can anyone give me guidance on this?
Instead of negating using a mathematical function I assigned a NSMutableString to my UITextField then I inserted a "-" sign using insertString:atIndex: then I reassigned the changed string to my UITextField. To toggle between positive and negative, I created an if function so if the float value of my textfield is greater or equal to 0, then an "-" is inserted but if the float value of my text field is less than zero, the "-" is removed using deleteCharactersInRange. Here is my code as it stands:
- (IBAction)positivity{
NSMutableString *a = [NSMutableString stringWithString:aVal.text];
if([aVal.text floatValue]>=0){
[a insertString: #"-" atIndex: 0];
aVal.text = a;
}
else if([aVal.text floatValue]<0){
NSRange range = {0,1};
[a deleteCharactersInRange:range];
aVal.text = a;
}
}
aVal is the name of the UITextField that i am changing.
An alternative to the straight string approach is to not use a string. A while back I wrote a graphing calculator for iPhone that stored the equation internally in an NSMutableArray of NSStrings. Each slot in the array corresponded to one element in the equation, such as "x", "^", "sin(", etc.
When I needed to negate the equation, it was much easier to tell the array to insertObject:#"-" atIndex:0 than to try and insert it directly into the string. Then whenever the array was changed, I just remade the equation string like this:
NSString * newEquation = [equationElements componentsJoinedByString:#""];
While you could directly manipulate a string representation of a numeric value, such an approach is a bad idea. Not only is it less efficient than other alternatives, but potentially incorrect. (For example, #Ken's answer would result in two minus signs.)
What you probably want to do is negate the numeric value (just multiply it by -1, or subtract it from 0 as you suggested) and reflect that change in the interface (you mention a text box).
If you're using standard Cocoa controls (which inherit from NSControl, as NSTextField does) I suggest using -[NSControl setIntegerValue:] to change the text of the text field. If you (can) break up your UI well and have a text field for each variable in the quadratic equation, this should be fairly simple. (If you're using something other than an integer value, use something like -setDoubleValue: or -setFloatValue: instead.)
If you must create your own string beforehand, using an integer format specifier will display a "-" sign automatically if appropriate. Be sure to use %ld instead of %d (thanks, #Peter!) as the format specifier for NSInteger values to avoid possibly truncating values larger than 32-bit. For example:
NSString *result = [NSString stringWithFormat:#"%ld", nsIntegerValue];
In a more general sense, if you need to insert a dynamically-obtained string (not just something for which you can create a format string at compile time) you can also use an NSMutableString and its methods -appendString: and -insertString:atIndex: as well.