Setting UILabel Text Multiple Times Within A Loop - objective-c

I'm fooling around in XCode, trying to learn a little about the iOS SDK and Objective-C.
I have this for loop below, and it should print out several values to the screen (depending on the amount of months chosen), but instead, it's only printing out the final value.
Can anybody point out why?
Thanks a bunch, in advance!
for (int i = 1; i <= myMonthsDouble; i++)
{
myPaymentAmount = (myBalanceDouble/10) + myInterestDouble;
myBalanceDouble -= myPaymentAmount;
//convert myPaymentAmount double into string named myPaymentAmountString
NSString *myPaymentAmountString = [NSString stringWithFormat:#"%f", myPaymentAmount];
NSString *paymentInformation = [[NSString alloc] initWithFormat:#"%# months, %# per month.", monthsString, myPaymentAmountString];
myInterestDouble = (myBalanceDouble * (myInterestDouble/100))/12;
self.label.text = paymentInformation;
}

It is only printing the last value to the screen because you only have one label. Each time you get to the end of the loop, you are setting that label's text which is overriding the last value. If you want to print all of them to the screen, you will need to have either multiple labels or you will have to append the strings together and put them in either a label or a UITextView that is formatted so that they can all be seen (most likely a text view but it can be done with a label.)
One example of doing this would be:
label.text = [label.text stringByAppendingString:newString];
numLines++; //this starts at 0;
and then at the end:
label.numberOfLines = numLines;

Related

NSTextView select specific line

I am on Xcode 10, Objective-C, macOS NOT iOS.
Is it possible to programmatically select a line in NSTextView if the line number is given? Not by changing any of the attributes of the content, just select it as a user would do it by triple clicking.
I know how to get selected text by its range but this time i need to select text programmatically.
I've found selectLine:(id) but it seems to be for an insertion point.
A pointer to the right direction would be great and very much appreciated.
The Apple documentation here https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextLayout/Tasks/CountLines.html should be useful for what you're attempting to do.
In their example of counting lines of wrapped text they use the NSLayoutManager method lineFragmentRectForGlyphAtIndex:effectiveRange https://developer.apple.com/documentation/appkit/nslayoutmanager/1403140-linefragmentrectforglyphatindex to find the effective range of the line, then increase the counting index to the end of that range (i.e. starting at the next line). With some minor modification, you can use it to find the range of the line you'd like to select, then use NSTextView's setSelectedRange: to select it.
Here's it modified to where I believe it would probably work for what you're attempting to accomplish:
- (void)selectLineNumber:(NSUInteger)lineNumberToSelect {
NSLayoutManager *layoutManager = [self.testTextView layoutManager];
NSUInteger numberOfLines = 0;
NSUInteger numberOfGlyphs = [layoutManager numberOfGlyphs];
NSRange lineRange;
for (NSUInteger indexOfGlyph = 0; indexOfGlyph < numberOfGlyphs; numberOfLines++) {
[layoutManager lineFragmentRectForGlyphAtIndex:indexOfGlyph effectiveRange:&lineRange];
// check if we've found our line number
if (numberOfLines == lineNumberToSelect) {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self.testTextView setSelectedRange:lineRange];
}];
break;
}
indexOfGlyph = NSMaxRange(lineRange);
}
}
Then you could call it with something like:
[self selectLineNumber:3];
Keep in mind that we're starting at index 0. If you pass in a lineNumberToSelect that is greater than the numberOfLines, it should just be a no-op and the selection should remain where it is.
Thanks #R4N! Your answer helped me figure out how jump to specific line with NSTextView. I converted your Obj-C to Swift 5:
func selectLineNumber(lineNumberToJumpTo: Int) {
let layoutManager = textView.layoutManager!
var numberOfLines = 1
let numberOfGlyphs = layoutManager.numberOfGlyphs
var lineRange: NSRange = NSRange()
var indexOfGlyph = 0
while indexOfGlyph < numberOfGlyphs {
layoutManager.lineFragmentRect(forGlyphAt: indexOfGlyph, effectiveRange: &lineRange, withoutAdditionalLayout: false)
// check if we've found our line number
if numberOfLines == lineNumberToJumpTo {
textView.selectedRange = lineRange
textView.scrollRangeToVisible(lineRange)
break
}
indexOfGlyph = NSMaxRange(lineRange)
numberOfLines += 1
}
}

Repeating my text on my textView Objective C

How do I make the following script repeat the text input into it?
self.textView.text = self.userTextInput
The above script was written as a text input from a ViewController but I want it to loop 10 times in its text viewer, how do I write that?
thanks.
Use following code to get your desired result.
NSMutableString *teststring = [NSMutableString string];
for(int i = 0; i<10;i++)
{
[teststring appendString:self.userTextInput];
}
self.textView.text = teststring;

2 text fields to always equal 100 percent xcode

I have two text fields that are for percentages to be entered in. If i put 20 in the first field I would like the second text field to be updated to 60. And later on if I changed the second one to say 30, I would like the first updated to 70.
For ease of showing what I mean, say I have two text fields _firstPercent and _secondPercent with associated labels _firstTotal and _secondTotal:
float firstPercent = [_firstPercent.text floatValue];
float firstAmount = (firstSalePercent / 100) * firstOrigonalAmount;
_firstTotal.text = [NSString stringWithFormat:#"%1.0f",firstAmount];
float secondPercent = [_secondPercent.text floatValue];
float secondAmount = (secondSalePercent / 100) * secondOrigonalAmount;
_secondTotal.text = [NSString stringWithFormat:#"%1.0f",secondAmount];
I really don't know how to handle this so I tried adding this below its respective code. It works for the first one, but not the second.
float percentToSecond = 100 - firstPercent;
_secondPercent.text = [NSString stringWithFormat:#"%1.0f", percentToSecond];
float percentToFirst = 100 - secondPercent;
_firstPercent.text = [NSString stringWithFormat:#"%1.0f", percentToFirst];
I have tried other solutions but don't know what to do.
I would just like someone to lead me in the right direction.
Thanks
How about using the delegate method controlTextDidEndEditing: to see what value was entered, and then set the value for the other text field. In the following code tf1 and tf2 are the IBOutlets for the two text fields.
-(void)controlTextDidEndEditing:(NSNotification *)obj {
float value = [[[obj.userInfo valueForKey:#"NSFieldEditor"] string] floatValue];
if (obj.object == self.tf1) {
self.tf2.stringValue = [NSString stringWithFormat:#"%1.0f",100. - value];
}else if (obj.object == self.tf2) {
self.tf1.stringValue = [NSString stringWithFormat:#"%1.0f",100. - value];
}
}
You'd have to do some more checking to make sure the user didn't enter a number greater than 100 or something not a number.

Xcode - Multiple values from single input

I'm trying to learn a little about Xcode, and I'm stuck on trying to get multiple values from a single input.
- (void)degreeConvert:(id)sender
{
double timelonn = [tempTextBox.text doubleValue];
double monedslonn = (timelonn * 162.5);
// double arslonn = (timelonn * 1950);
[tempTextBox resignFirstResponder];
NSString *convertResult = [[NSString alloc] initWithFormat: #"Månedslønn: %0.f", monedslonn];
// NSString *convertResult = [[NSString alloc] initWithFormat: #"Årslønn: %0.f", arslonn];
calcResult.text = convertResult;}
This takes my input 'timelonn' (hourly wage/income) and returns 'monedslonn' (monthly wage/income). The double-dashed comments is my rookie idea of how I could get it to display 'arslonn' (yearly wage/income) as well.
Am I far off here?
You're not too far off. If you uncomment your first commented line, and then change your line where you set your convertResult, you can set the convertResult string to something with multiple lines, like so:
- (void)degreeConvert:(id)sender
{
double timelonn = [tempTextBox.text doubleValue];
double monedslonn = (timelonn * 162.5);
double arslonn = (timelonn * 1950);
[tempTextBox resignFirstResponder];
NSString *convertResult = [[NSString alloc] initWithFormat: #"Månedslønn: %0.f\nÅrslønn: %0.f", monedslonn, arslonn];
calcResult.text = convertResult;
}
Note here that in the format string, "Månedslønn: %0.f\nÅrslønn: %0.f", the \n stands for a newline.
Also note that you will have to edit your .nib and change a property of your UILabel. Click on the label and change the (I'm going off Xcode 4 here) Lines property to 2 (or however many lines you wanted). On Xcode 4 it should be the second from the top in the 4-th tab of the Utilities pane (Command-Option-4). While you're at it, resize your UILabel so that it has enough space to hold your multiple lines ;)

interacting with UIViews stored inside a NSMutableArray

a big noob needs help understanding things.
I have three UIViews stored inside a NSMutableArray
lanes = [[NSMutableArray arrayWithCapacity:3] retain];
- (void)registerLane:(Lane*)lane {
NSLog (#"registering lane:%i",lane);
[lanes addObject:lane];
}
in the NSLog I see: registering lane:89183264
The value displayed in the NSLog (89183264) is what I am after.
I'd like to be able to save that number in a variable to be able to reuse it elsewhere in the code.
The closest I could come up with was this:
NSString *lane0 = [lanes objectAtIndex:0];
NSString *description0 = [lane0 description];
NSLog (#"description0:%#",description0);
The problem is that description0 gets the whole UIView object, not just the single number (dec 89183264 is hex 0x550d420)
description0's content:
description0:<Lane: 0x550d420; frame = (127 0; 66 460); alpha = 0.5; opaque = NO; autoresize = RM+BM; tag = 2; layer = <CALayer: 0x550d350>>
what I don't get is why I get the correct decimal value with with NSLog so easily, but seem to be unable to get it out of the NSMutableArray any other way. I am sure I am missing some "basic knowledge" here, and I would appreciate if someone could take the time and explain what's going on here so I can finally move on. it's been a long day studying.
why can't I save the 89183264 number easily with something like:
NSInteger * mylane = lane.id;
or
NSInteger * mylane = lane;
thank you all
I'm really confused as to why you want to save the memory location of the view? Because that's what your '89183264' number is. It's the location of the pointer. When you are calling:
NSLog (#"registering lane:%i",lane);
...do you get what's actually being printed out there? What the number that's being printed means?
It seems like a really bad idea, especially when if you're subclassing UIView you've already got a lovely .tag property which you can assign an int of your choosing.
You're making life infinitely more complex than it needs to be. Just use a pointer. Say I have an array containing lots of UIViews:
UIView *viewToCompare = [myArray objectAtIndex:3];
for (id object in myArray) {
if (object == viewToCompare) {
NSLog(#"Found it!");
}
}
That does what you're trying to do - it compares two pointers - and doesn't need any faffing around with ints, etc.