How to get a counter of an UITextView? - iphone

I want a counter that shows in a UILabel how many charachters the UITextView has.
I tried this:
IBOutlet UITextView *twittermessage;
UIActionSheet * loadingActionSheet;
IBOutlet UILabel * anzahl;
Here the .m:
- (void)textViewDidChange:(UITextView *)twittermessage{
int count = [twittermessage.text length];
anzahl.text = (NSString *)count;
}
Thanks for your help and sorry for my bad English.

You can't cast an integer to a NSString using C-style casts. You have to apply a string formatter to count to get a string representation of count.
Your code should look like:
- (void)textViewDidChange:(UITextView *)theTwitterMessage{
int count = [theTwitterMessage.text length];
anzahl.text = [NSString stringWithFormat:#"%d",count];
}

Related

Assign string to UIButton's tag value

I wanted to give a string value to UIButton tag for unique identities.
I tried this code.But it doesnt work.
NSString *A;
NSString *B;
NSString *C;
NSString *D;
firstOptionABtn.tag=[A integerValue];
secondOptonBbtn.tag=[B integerValue];
thirdOptionCbtn.tag=[C integerValue];
fourthOptionDbtn.tag=[D integerValue];
- (IBAction)BtnClicked:(UIButton *)sender {
NSLog(#"%ld",(long)sender.tag);
}
I don't like this way but it will print 0 every time. Where am I going wrong?
Please help. Thanks
It returns zero as you did not initialize string, and it has null value when you convert it into integer it returns you zero. And it seems that you create your button from NIB so you can set their tag value from there and then get there value by implementing.
-( IBAction )buttonClicked:(id)sender
{
UIButton *btn= (UIButton *)sender;
NSLog(#"%d",btn.tag);
}
but if u want the output A,B,C, D then there is also a way
-(void)viewDidLoad{
btn1.accessibilityLabel=#"A";
btn2.accessibilityLabel=#"B";
btn3.accessibilityLabel=#"C";
btn4.accessibilityLabel=#"D";
}
-(IBAction)buttonClicked:(id)sender {
UIButton *btn= (UIButton *)sender;
NSLog(#"%#",btn.accessibilityLabel);
}
output is A, B, C, D
What need to use string for set tag value of button... why not set tag of Button statically simply set like :-
firstOptionABtn.tag=1;
First time seen this setting tag with string to int convert
In your queston First is you are not seting the value of you string
NSString *A;
NSString * B;
NSString * C;
NSString * D;
if you set value of string like
A=#"2"
then your code working and you got the value at the button click event
firstOptionABtn.tag=[A integerValue];
its output is
sender tag 2
Into you String value consider any Number value then the covert string to Intiger cosider only Number not alphabet character like
for example
If you set value of string like A=#"2aaabbb" then the output of button tag is 2 But if you set string value like A=#"bb2aaabbb" then output of button tag is Always 0 consider.
UPDATE
if you wish to set character to int
you can convert NSString to ASCII Like Bellow
A=#"A"
int ASCIINumber = [A characterAtIndex:0];
button.tag=ASCIINumber;
OUTPUT IS:- 65 for Upper case if lower case OUTPUT IS 97
But as using above method i suggest to you use simply set tag=intNumber instead of doing above.
It's not possible dear to set string in tag. Tag only takes int value as you said you know.
Create a custom view which is composed of UIButton and a NSString property or an ivar which will serve as tag.
#interface MyButton: UIView
#property(nonatomic, strong) UIButton *button;
#property(nonatomic, strong) NSString *uniqueTag;
#end
Hope that helps!
we can make a category for tag string in UIButton.
#interface UIButton (setTag)
#property(nonatomic, retain) NSString *tagString;
#end
And any where in your file you can set the tag string to your UIButton.
e.g
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTagString:#"Hello"];
you can always create a custom class containing a string property to go along with said classes
for example : create a custom class for UIButton
and then at the Header File put :
#property (nonatomic, strong)NSString *labelTag;
- (id)initWithFrame:(CGRect)frame withLabelTag:(NSString *)str;
and then, at the implementation create a super method of init with frame so it looked like this :
- (id)initWithFrame:(CGRect)frame withLabelTag:(NSString *)str{
self = [super initWithFrame:frame];
if (self) {
//Init code
_labelTag = str;
}
return self;
}
after that, whenever you want to set or call the string tag of the button you only need to declare it and call it like this :
MyCustomButton *button = [[MyCustomButton alloc]initWithFrame:frame withLabelTag:#"this is the title"];
//and to call it :
NSLog (#"the button's tag is :%#", button.labelTag)
or, you could always just use the button's title property and if you don't want it to show on your button, just set its HIDDEN prop to YES
There are two scenarios.
Case 1: If your tag string contains only numbers - (Eg: tagStringValue = "1433")
Use myButton.tag = [tagStringValue intValue];
Get back the button using
UIButton *myButton = ([[self.view viewWithTag:[tagStringValue intValue]] isKindOfClass:[UIButton class]])?(UIButton *)[self.view viewWithTag:[tagStringValue intValue]]:nil;
Case 2: If your tag string contains numbers and strings - (Eg: tagStringValue = "ss1433kk")
Subclass the UIButton and add a property like:
#property (nonatomic, strong) NSString *stringTag; and use this instead of default Tag.

Using an array of strings for UISlider

I want to change a UILabel with strings based on an array. Here is what I have so far:
- (IBAction) sliderValueChanged:(UISlider *)sender {
scanLabel.text = [NSString stringWithFormat:#" %.f", [sender value]];
NSString *wholeText = #"Very Bad";
self.scanLabel.text = wholeText;
}
Instead of just "Very Bad," I want different values to show "very Bad, Bad, Okay, Good, Very Good."
Where do I declare the NSMutableArray, and how do I implement it with the slider?
Update: Thank you all for your help! (I love stackoverflow)
This is not compiler checked...but you may get some idea.
NSArray *texts=[NSArray arrayWithObjects:#"very Bad", #"Bad", #"Okay", #"Good", #"Very Good",nil];
NSInteger sliderValue=[sender value]; //make the slider value in given range integer one.
self.scanLabel.text=[texts objectAtIndex:sliderValue];
You declare it in the same class as the above method.
Let's say it's called wholeTexts.
The code will look like this:
- (IBAction) sliderValueChanged:(UISlider *)sender {
scanLabel.text = [NSString stringWithFormat:#" %.f", [sender value]];
NSString *wholeText = [wholeTexts objectAtIndex:(wholeTexts.count - 1) * (int)(sender.value - sender.minimumValue)/(sender.maximumValue - sender.minimumValue)];
self.scanLabel.text = wholeText;
}
Put your text values into an array
NSArray* array = #[#"very Bad", #"Bad", #"Okay", #"Good", #"Very Good"];
set your slider to have a min value of 0 and maximum value of 4
turn your [sender value] into an int, eg floor([sender value])
pick an item from the array using your int, eg
NSString* result = [array objectAtIndex:myInt];
You can implement the array anywhere you want, as long as it's created before you need to use the slider. Sliders can only have a value between 0 and 1 in iOS, so you'll need to multiply the value by something to get numbers as high as the number of items in your array (minus 1), and you'll need to convert them to an integer, so you can use that value as the index into the array. Something like this:
- (IBAction) sliderValueChanged:(UISlider *)sender {
scanLabel.text = [myArray objectAtIndex:(int)(sender.value * 10)];
}

read number from UITextfield

I need the user in the interface builder text field to enter a number and i want to read it as number i think the system read it as string and no output
here is my code if you can kindly assist
in the interface
{
IBOutlet UITextField *arr_values;}
#property (nonatomic ,retain) IBOutlet UITextField *arr_values;
and in the .m file
int inputNumber = [arr_values.text intValue];
NSLog(#"%#",inputNumber);
but no output when i enter # in the Interface builder
with thanks
You can get value from textField like this.
float val=[txtField.text floatValue];
replace the %# by %d, as for an integer we have %d:
NSLog(#"%d",inputNumber);
As for the custom keyboard, in the viewDidLoad method add the line:
[inputNumber setKeyboardType: UIKeyboardTypeNumberPad];

How to dynamically adjust method names and calls with Objective-C

I am trying to condense my code for a method and was wondering how I would achieve the following:
I have a bunch of variables that differ only in their number such as:
int intVariable1
int intVariable2
UILabel Label1
UILabel Label2
BOOL bool1
BOOL bool2
etc.
So I want to call a method and pass in an int. That int would determine which ints, UILablels, and BOOLs get worked on. So if a 1 was passed in the method would work on these variables like this:
- (void) DyanamicMethod: (int) inputNumber {
//something that uses the inputNumber to act on the 1 variables
intVariable1 = someValue;
[Label1 setText:someText];
bool1 = YES;
}
Obviously if a 2 were passed in I would want the variables to be of the 2 type. I'm assuming you would do something with creating a string somehow, but I'm not sure how to adjust that to use it to become a variable name. Any insight would be appreciated. Thank you for your time.
Declare the variables as arrays:
int intVariable[2];
UILabel *Label[2];
BOOL bools[2];
Then the method would look like this:
intVariable[inputNumber] = someValue;
[Label[inputNumber] setText:#"someText"];
bools[inputNumber] = YES;
Keep in mind that array indexes are zero-based so in the arrays above, variable "1" is at index 0 and variable "2" is at index 1. Your method could also just take the inputNumber and subtract one from it to get the array index.
You can use key-value coding.
- (void) DyanamicMethod: (int) inputNumber {
//something that uses the inputNumber to act on the 1 variables
NSString* key = [NSString stingWithFormat:#"Label%i", number];
UILabel* label = [self valueForKey:key];
label.text = newString;
}
If you needed something like that you could keep an NSArray of all of the labels ...
Like
in the class interface section:
NSArray* labels ;
In init:(or loadView)
labels = [[NSArray alloc] initWithObjects:Label1, Label2,etc] ;
In dealloc:
[labels release] ;
in DyanamicMethod: (int) inputNumber
UILabel* label = [labels objectAtIndex:inputNumber] ;
Repeat for each type ... Or make a new class holding the label, int and the bool, and have the array be of that type.
Another way might be:
Make properties for each of your member variables.
Then in your function:
UILabel label1 = [self performSelector:sel_getUid([[NSString stringWithFormat:#"label%d", inputNumber] UTF8String])] ;
I think using an array of some sort is better for this situation, but its possible to do it this way. See NSObject Documentation for performSelector.
You could do this with properties (well, you don't NEED properties, but they'd make it simpler), though you'd have to switch to objects:
#property (nonatomic, readwrite, retain) NSNumber *variable1, *variable2;
#property (nonatomic, readwrite, retain) NSNumber *bool1, *bool2;
#property (nonatomic, readwrite, retain) UILabel *label1, *label2;
- (void) DyanamicMethod: (int) inputNumber {
[[self valueForKey: [NSString stringWithFormat: #"label%d", inputNumber] setText: someText];
[self setValue: [NSNumber numberWithInt: inputNumber]
forKey: [NSString stringWithFormat: #"variable%d", inputNumber]];
[self setValue: [NSNumber numberWithBool: YES]
forKey: [NSString stringWithFormat: #"bool%d", inputNumber]];
}
Do you have too many variables for a simple switch statement?
switch(inputNumber) {
case 1:
intVariable1 = someValue;
[Label1 setText:someText];
bool1 = YES;
break;
case 2:
intVariable2 = someValue;
[Label2 setText:someText];
bool2 = YES;
break;
// etc
}

What is the best way to enter numeric values with decimal points?

In my app users need to be able to enter numeric values with decimal places. The iPhone doesn't provides a keyboard that's specific for this purpose - only a number pad and a keyboard with numbers and symbols.
Is there an easy way to use the latter and prevent any non-numeric input from being entered without having to regex the final result?
Thanks!
I think it would be good to point out that as of iOS 4.1 you can use the new UIKeyboardTypeDecimalPad.
So now you just have to:
myTextField.keyboardType=UIKeyboardTypeDecimalPad;
A more elegant solution happens to also be the simplest.
You don't need a decimal separator key
Why? Because you can simply infer it from the user's input. For instance, in the US locale when you what to enter in $1.23, you start by entering the numbers 1-2-3 (in that order). In the system, as each character is entered, this would be recognized as:
user enters 1: $0.01
user enters 2: $0.12
user enters 3: $1.23
Notice how we inferred the decimal separator based on the user's input. Now, if the user wants to enter in $1.00, they would simply enter the numbers 1-0-0.
In order for your code to handle currencies of a different locale, you need to get the maximum fraction digits of the currency. This can be done with the following code snippet:
NSNumberFormatter *currencyFormatter = [[NSNumberFormatter alloc] init];
[currencyFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
int currencyScale = [currencyFormatter maximumFractionDigits];
For example, the Japanese yen has a maximum fraction digit of 0. So, when dealing with yen input, there is no decimal separator and thus no need to even worry about fractional amounts.
This approach to the problem allows you to use the stock numeric input keypad provided by Apple without the headaches of custom keypads, regex validation, etc.
Here is an example for the solution suggested in the accepted answer. This doesn't handle other currencies or anything - in my case I only needed support for dollars, no matter what the locale/currency so this was OK for me:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
double currentValue = [textField.text doubleValue];
//Replace line above with this
//double currentValue = [[textField text] substringFromIndex:1] doubleValue];
double cents = round(currentValue * 100.0f);
if ([string length]) {
for (size_t i = 0; i < [string length]; i++) {
unichar c = [string characterAtIndex:i];
if (isnumber(c)) {
cents *= 10;
cents += c - '0';
}
}
} else {
// back Space
cents = floor(cents / 10);
}
textField.text = [NSString stringWithFormat:#"%.2f", cents / 100.0f];
//Add this line
//[textField setText:[NSString stringWithFormat:#"$%#",[textField text]]];
return NO;
}
The rounds and floors are important a) because of the floating-point representation sometimes losing .00001 or whatever and b) the format string rounding up any precision we deleted in the backspace part.
I wanted to do exactly the same thing, except with currencies rather than straight decimal values.
I ended up creating a custom view which contains a UITextField and a UILabel. The label covers the text field, but the text field still receives touches. I use the UITextFieldTextDidChange notification to observe changes in the text field (and I used a NSNumberFormatter to turn the resulting number into a formatted currency value) to update the label.
To disable the loupe that allows the user to reposition the insertion point, you'll need to use a custom UITextField subclass and override touchesBegan:withEvent: and set it to do nothing.
My solution might be different from what you need because the decimal point is always fixed -- I use the system's currency setting to determine how many there digits ought to be after the decimal point. However, the numeric keypad doesn't have a decimal point on it. And you can't add any buttons to the keyboard (which is especially aggravating because there's a blank button in the lower-left corner of the keyboard that would be perfect for a decimal point!) So I don't have a solution for that, unfortunately.
Depending on the specific application, providing a slider that the user can select a position from might be a better choice on the iphone. Then no digits need to be entered at all.
You may want to use a slider (as suggested by Martin v. Löwis) or a UIPickerView with a separate wheel for each of the digits.
I built a custom Number pad view controller with decimal point... check it out:
http://sites.google.com/site/psychopupnet/iphone-sdk/tenkeypadcustom10-keypadwithdecimal
As of iOS4.1, there is a new keyboard type UIKeyboardTypeNumberPad, but unfortunately, as of yet it doesn't seem to appear in the Interface Builder pick list.
Here's how to do it without using floats, round() or ceil() in a currency agnostic manner.
In you view controller, set up the following instance variables (with associated #property statements if that's your bag):
#interface MyViewController : UIViewController <UITextFieldDelegate> {
#private
UITextField *firstResponder;
NSNumberFormatter *formatter;
NSInteger currencyScale;
NSString *enteredDigits;
}
#property (nonatomic, readwrite, assign) UITextField *firstResponder;
#property (nonatomic, readwrite, retain) NSNumberFormatter *formatter;
#property (nonatomic, readwrite, retain) NSString *enteredDigits;
#end
and your viewDidLoad method should contain the following:
- (void)viewDidLoad {
[super viewDidLoad];
NSNumberFormatter *aFormatter = [[NSNumberFormatter alloc] init];
[aFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
currencyScale = -1 * [aFormatter maximumFractionDigits];
self.formatter = aFormatter;
[aFormatter release];
}
Then implement your UITextFieldDelegate methods as follows:
#pragma mark -
#pragma mark UITextFieldDelegate methods
- (void)textFieldDidBeginEditing:(UITextField *)textField {
// Keep a pointer to the field, so we can resign it from a toolbar
self.firstResponder = textField;
self.enteredDigits = #"";
}
- (void)textFieldDidEndEditing:(UITextField *)textField {
if ([self.enteredDigits length] > 0) {
// Get the amount
NSDecimalNumber *result = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
NSLog(#"result: %#", result);
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
// Check the length of the string
if ([string length]) {
self.enteredDigits = [self.enteredDigits stringByAppendingFormat:#"%d", [string integerValue]];
} else {
// This is a backspace
NSUInteger len = [self.enteredDigits length];
if (len > 1) {
self.enteredDigits = [self.enteredDigits substringWithRange:NSMakeRange(0, len - 1)];
} else {
self.enteredDigits = #"";
}
}
NSDecimalNumber *decimal = nil;
if ( ![self.enteredDigits isEqualToString:#""]) {
decimal = [[NSDecimalNumber decimalNumberWithString:self.enteredDigits] decimalNumberByMultiplyingByPowerOf10:currencyScale];
} else {
decimal = [NSDecimalNumber zero];
}
// Replace the text with the localized decimal number
textField.text = [self.formatter stringFromNumber:decimal];
return NO;
}
Only tested this with pounds and pence, but it should work with Japanese Yen too. If you want to format decimals for non-currency purposes, then just read the documentation on NSNumberFormatter and set whatever format/maximumFractionDigits you want.
A Swift 2 implementation of Mike Weller's post, also only USD:
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
guard let str = textField.text else {
textField.text = "0.00"
return false
}
let value = (str as NSString).doubleValue
var cents = round(value * 100)
if string.characters.count > 0 {
for c in string.characters {
if let num = Int(String(c)) {
cents *= 10
cents += Double(num)
}
}
}
else {
cents = floor(cents / 10)
}
textField.text = NSString(format: "%.2f", cents/100) as String
return false
}
You can use STATextField and set currencyRepresentation to YES which:
Ensures no more than one decimal point is entered and that no more than 2 digits are entered to the right of said decimal point.
There's also STAATMTextField which supports currency mode and ATM text entry by default:
Provides a text field that mimics ATM machine input behavior.