How to put a character limit on a UITextField - xcode

I would like to put a character limit on a UITextField but don't know how. I want it to have a maximum of 16 characters in it. How do I do this.

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
NSUInteger newLength = [textField.text length] + [string length] - range.length;
return (newLength > 12) ? NO : YES;
}

Related

IBAction float, have a equal different numbers depending on input

New to objective-c and I just can't find the answer to this question anywhere. I'm running a IBAction for a calculation but I need the input from a label to actually equal something else in the equation.
For example:
-(IBAction)calculate; {
float a = 1.05 if ([label1.text] == 1in);
a = 2.07 if ([label1.text] == 2in);
a = 3.07 if ([label1.text] == 3in);
float b = a*([textField1.text floatValue]);
label2.text = [[NSString alloc] initWithFormat:#"%2.f", b];
}
I know I'm not even close to getting it right but I hope you get the idea as to what I'm looking for.
Thank you!
- (void)calculate {
float a;
if ([self.inputField.text isEqualToString:#"1in"]) a = 1.05f;
else if ([self.inputField.text isEqualToString:#"2in"]) a = 2.07f;
else if ([self.inputField.text isEqualToString:#"3in"]) a = 3.07f;
else a = 0.0f;
if (a) {
float b = a * ([self.inputField.text floatValue]);
self.inputField.text = [[NSString alloc] initWithFormat:#"%.2f", b];
}
else self.inputField.text = #"Invalid";
}
- (void)viewDidLoad
{
//...
self.inputField = [[UITextField alloc] initWithFrame:CGRectMake(10.0f, 20.0f, 300.0f, 30.0f)];
[self.inputField setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:self.inputField];
UIButton * doneButton = [[UIButton alloc] initWithFrame:CGRectMake(10.0f, 55.0f, 300.0f, 30.0f)];
[doneButton setBackgroundColor:[UIColor blackColor]];
[doneButton setTitle:#"Done" forState:UIControlStateNormal];
[doneButton addTarget:self action:#selector(calculate) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:doneButton];
[doneButton release];
}
Note: I replaced the output format %2.f to %.2f, cause I guess you may need this format. E.g:
Input > 1in
Output< 1.05
Input > 2in
Output< 4.14
Input > 3in
Output< 9.21

How do i get the range of the current paragraph in a NSTextView where the cussor stayed there?

Now i need to change the alignment of a paragraph in a nstextview without select it ,so i need to know the range of the current range of the paragraph?
I have a subclass of NSTextView so you need to access textStorage and selectedRange different than [self textStorage] and [self selectedRange].
NSTextStorage *textStorage = [self textStorage];
NSString *string = [textStorage string];
NSUInteger editEnd = [self selectedRange].location;
NSUInteger editStart = editEnd-[textStorage editedRange].length;
NSUInteger maxLength = [string length];
while (editStart > 0) {
unichar theChr = [string characterAtIndex:editStart-1];
if( theChr == '\n' || theChr == '\r' ) {
break;
}
--editStart;
}
while (editEnd < maxLength) {
unichar theChr = [string characterAtIndex:editEnd];
if( theChr == '\n' || theChr == '\r' ) {
break;
}
++editEnd;
}
NSRange paragraphRange = NSMakeRange(editStart, editEnd-editStart);
Here's a shortcut:
NSRange paragraphRange = [textView.textStorage.string paragraphRangeForRange: [textView selectedRange]];
First, get the range where the cursor stayed through [textView selectedRange]
Then you can get the line range through - (NSRange)lineRangeForRange:(NSRange)range of [textView string]
Here is a example code:
NSRange sel = [textView selectedRange];
NSString *viewContent = [textView string];
NSRange lineRange = [viewContent lineRangeForRange:NSMakeRange(sel.location,0)];
detail in there.
How to get the selected line range of NSTextView?

Simulate arrow keys with 'j' and 'k' in an NSTableView?

I have an NSTableView with a number of rows. The allowsEmptySelection property is NO, so there is always a row selected. I can move up and down the tableview with the arrow keys as expected.
I'd like to also be able to move up and down with the 'j' and 'k' keys. I've looked at the Cocoa Event-Handling Guide, but can't figure out how to make these keys simulate the up and down arrow keys.
For what it's worth, here's what I'm currently doing. I'm not really 'simulating the arrow keys'. Rather, I'm just doing the behavior I want when 'j' and 'k' are pressed. It's fine, but I'm wondering if there is a better way...
- (void)keyDown:(NSEvent *)theEvent {
NSInteger row = [self.tableView selectedRow];
NSInteger numRows = [self.tableView numberOfRows];
switch ([theEvent keyCode]) {
case 38: // 'j'
if (row < numRows - 1) {
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO];
}
break;
case 40: // 'k'
if (row > 0) {
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row-1] byExtendingSelection:NO];
}
break;
default:
[super keyDown:theEvent];
}
}
Create a custom subclass of NSTableView to catch the events. Your subclass should have this method in it:
- (void)keyUp:(NSEvent *)event {
if([event keyCode] == 26) {//J
if([event modifierFlags] & NSShiftKeyMask) [self moveDownAndModifySelection:nil];
else [self moveDown:nil];
} else if([event keyCode] == 28) {//K
if([event modifierFlags] & NSShiftKeyMask) [self moveUpAndModifySelection:nil];
else [self moveUp:nil];
} else [super keyUp:event];
}
This will catch any J or K keys and tell the table view to move up or down, respectively. Also, if the shift key is pressed, this will add to the selection upwards or downwards.
If you choose to use this code, make sure you filter out if any other modifiers are pressed and pass them to super also. I did not do this to make it more readable.
Edit: How to create a false event
unichar theChar = NSUpArrowFunctionKey; //NSDownArrowFunctionKey
NSString *string = [NSString stringWithCharacters:&theChar length:1];
NSEvent *newEvent =[NSEvent keyEventWithType:NSKeyUp location:[event locationInWindow] modifierFlags:[event modifierFlags] timestamp:[event timestamp] windowNumber:[event windowNumber] context:nil/*get graphics context if you want*/ characters:string charactersIgnoringModifiers:string isARepeat:[event isARepeat] keyCode:theChar];
[super keyUp:newEvent];

Cocoa - Trim all leading whitespace from NSString

(have searched, but not been able to find a simple solution to this one either here, or in Cocoa docs)
Q. How can I trim all leading whitespace only from an NSString? (i.e. leaving any other whitespace intact.)
Unfortunately, for my purposes, NSString's stringByTrimmingCharactersInSet method works on both leading and trailing.
Mac OS X 10.4 compatibility needed, manual GC.
This creates an NSString category to do what you need. With this, you can call NSString *newString = [mystring stringByTrimmingLeadingWhitespace]; to get a copy minus leading whitespace. (Code is untested, may require some minor debugging.)
#interface NSString (trimLeadingWhitespace)
-(NSString*)stringByTrimmingLeadingWhitespace;
#end
#implementation NSString (trimLeadingWhitespace)
-(NSString*)stringByTrimmingLeadingWhitespace {
NSInteger i = 0;
while ((i < [self length])
&& [[NSCharacterSet whitespaceCharacterSet] characterIsMember:[self characterAtIndex:i]]) {
i++;
}
return [self substringFromIndex:i];
}
#end
This is another solution using Regular Expressions (requires iOS 3.2):
NSRange range = [string rangeOfString:#"^\\s*" options:NSRegularExpressionSearch];
NSString *result = [string stringByReplacingCharactersInRange:range withString:#""];
And if you want to trim the trailing whitespaces only you can use #"\\s*$" instead.
This code is taking blanks.
NSString *trimmedText = [strResult stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#",trimmedText);
Here is a very efficient (uses CoreFoundation) way of doing it (Taken from kissxml):
- (NSString *)trimWhitespace {
NSMutableString *mStr = [self mutableCopy];
CFStringTrimWhitespace((CFMutableStringRef)mStr);
NSString *result = [mStr copy];
[mStr release];
return [result autorelease];
}
NSString *myText = #" foo ";
NSString *trimmedText = [myText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSLog(#"old = [%#], trimmed = [%#]", myText, trimmedText);
Here's what I would do, and it doesn't involve categories!
NSString* outputString = inputString;
NSRange range = [inputString rangeOfCharacterFromSet: [NSCharacterSet whitespaceCharacterSet]
options:0];
if (range.location == 0)
outputString = [inputString substringFromIndex: range.location + range.length];
This is much less code.
I didn't really have much time to test this, and I'm not sure if 10.4 contains the UTF8String method for NSString, but here's how I'd do it:
NSString+Trimming.h
#import <Foundation/Foundation.h>
#interface NSString (Trimming)
-(NSString *) stringByTrimmingWhitespaceFromFront;
#end
NSString+Trimming.m
#import "NSString+Trimming.h"
#implementation NSString (Trimming)
-(NSString *) stringByTrimmingWhitespaceFromFront
{
const char *cStringValue = [self UTF8String];
int i;
for (i = 0; cStringValue[i] != '\0' && isspace(cStringValue[i]); i++);
return [self substringFromIndex:i];
}
#end
It may not be the most efficient way of doing this but it should work.
str = [str stringByReplacingOccurrencesOfString:#" " withString:#""];

What kind of category methods do you use to make Cocoa programming easier?

I use a collection of category methods for Cocoa's built in classes to make my life easier. I'll post some examples, but I really want to see what other coders have come up with. What kind of handy category methods are you using?
Example #1:
#implementation NSColor (MyCategories)
+ (NSColor *)colorWithCode:(long)code
{
return [NSColor colorWithCalibratedRed:((code & 0xFF000000) >> 24) / 255.0
green:((code & 0x00FF0000) >> 16) / 255.0
blue:((code & 0x0000FF00) >> 8) / 255.0
alpha:((code & 0x000000FF) ) / 255.0];
}
#end
// usage:
NSColor * someColor = [NSColor colorWithCode:0xABCDEFFF];
Example #2:
#implementation NSView (MyCategories)
- (id)addNewSubViewOfType:(Class)viewType inFrame:(NSRect)frame
{
id newView = [[viewType alloc] initWithFrame:frame];
[self addSubview:newView];
return [newView autorelease];
}
#end
// usage:
NSButton * myButton = [someView addNewSubviewOfType:[NSButton class]
inFrame:someRect];
I've really been loving Andy Matuschak's "KVO+Blocks" category on NSObject. (Yes, it adds some new classes internally as implementation details, but the end result is just a category on NSObject). It lets you provide a block to be executed when a KVO-conforming value changes rather than having to handle every KVO observation in the observeValueForKeyPath:ofObject:change:context: method.
Regular Expressions with RegexKitLite. Download # RegexKitLite-3.1.tar.bz2
Category, which adds md5/sha1 hashing to NSString. NSData one is similar.
#define COMMON_DIGEST_FOR_OPENSSL
#import <CommonCrypto/CommonDigest.h>
#implementation NSString(GNExtensions)
- (NSString*)
hashMD5
{
NSData* data = [self dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion: NO];
unsigned char hashingBuffer[16];
char outputBuffer[32];
CC_MD5([data bytes], [data length], hashingBuffer);
for(int index = 0; index < 16; index++)
{
sprintf(&outputBuffer[2 * index], "%02x", hashingBuffer[index]);
}
return([NSString stringWithCString: outputBuffer length: 32]);
}
- (NSString*)
hashSHA1
{
NSData* data = [self dataUsingEncoding: NSUTF8StringEncoding allowLossyConversion: NO];
unsigned char hashingBuffer[20];
char outputBuffer[40];
CC_SHA1([data bytes], [data length], hashingBuffer);
for(int index = 0; index < 20; index++)
{
sprintf(&outputBuffer[2 * index], "%02x", hashingBuffer[index]);
}
return([NSString stringWithCString: outputBuffer length: 40]);
}
#end
I have a few nifty methods on NSDate. This is self-explanatory:
-(BOOL)isOnTheSameDayAsDate:(NSDate *)date {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *selfComponents = [cal components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit
fromDate:self];
NSDateComponents *dateComponents = [cal components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit
fromDate:date];
return (([selfComponents day] == [dateComponents day]) &&
([selfComponents month] == [dateComponents month]) &&
([selfComponents year] == [dateComponents year]));
}
Usage:
if ([aDate isOnTheSameDayAsDate:anotherDate]) { ... }
This provides a method to easily get dates like "9am the day before":
-(NSDate *)dateWithDayDelta:(NSInteger)daysBeforeOrAfter atHour:(NSUInteger)hour minute:(NSUInteger)minute second:(NSUInteger)second {
NSDate *date = [self addTimeInterval:(24 * 60 * 60) * daysBeforeOrAfter];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit |
NSMinuteCalendarUnit | NSSecondCalendarUnit
fromDate:date];
[comps setHour:hour];
[comps setMinute:minute];
[comps setSecond:second];
return [calendar dateFromComponents:comps];
}
Usage:
// We want 9am yesterday
NSDate *nineAmYesterday = [[NSDate date] dateWithDayDelta:-1
atHour:9
minute:0
second:0];

Resources