How to define private methods … sort of

There is no private or protected methods concept in Objective-C. I think it is related to the architecture of invoking method in Objective-C. Each method is invoked like [self method] style or [self performSelector:@selector(method)]. Internally, Objective-C runtime resolves method implementation by searching method name. This architecture gives flexibility to call method and also allows to have “category” but it is hard to support private method.

Apple still can enhance around this area to bring access control but until that time I think unnamed category is the simplest and easiest way to implement private method like declaration.

ClassA.h file

@interface ClassA {
}
- (void) publicMethod;
@end

ClassA.m file

@interface ClassA()
- (void) privateMethod;
@end

@implementation ClassA
- (void) publicMethod {
}

#pragma mark -
#pragma mark Private methods
- (void) privateMethod {
}
@end

Interesting discussions are going on at Stackoverflow.com

How to remember the setting (user defaults) easily

NSUserDefautls object automatically loads and saves small information. Along with primitive value like BOOL, integer or float, NSUserDefaults can handle objects like NSArray, NSData, NSDictionary, NSString.

// Save a default
[[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"ShowWarning"];

// Read  BOOL warning value from NSUserDefaults
BOOL showWarning = [[NSUserDefaults standardUserDefaults] boolForKey:@"ShowWarning"];

setObject: method is for setting class object and boolForKey: method is specifically used for getting BOOL value.

Capture view contents into an UIImage object

By combining UIGraphicsBeginImageContext() and -renderInContext in CALayer, you can draw contents into a image (UIImage) object. It is like screen capture.

UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGContextTranslateCTM() modifies the x- and y- coordinates (otherwise it starts from (0,0)). By using CGContextTranslateCTM(), you can change the start capturing point so that it can capture limited area in the UIScrollView content.

CGSize pageSize = CGSizeMake(320, 480);
int currentPage = 2;
UIGraphicsBeginImageContext(pageSize);
CGContextRef resizedContext = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(resizedContext, 320 * currentPage, 0);
[scrollView.layer renderInContext:resizedContext];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Ref:
Capture UIImage with offset into UIScrollView

Set border around the view

There is no border property in UIView…. classes but we can access CALayer class to set border. Since layer property is defined in the UIView class, all of UIView inherited class can use this property to set border. It needs to have #import <QuartzCore/QuartzCore.h> to access CALayer.

view.layer.borderWidth = 1;
view.layer.borderColor = [[UIColor grayColor] CGColor];

Calling selectors with multiple arguments – Stack Overflow

In Objective-C, a selector’s signature consists of:

  1. The name of the method (in this case it would be ‘myTest’) (required)
  2. A ‘;’ (colon) following the method name if the method has an input.
  3. A name and ‘:’ for every additional input.

Selectors have no knowledge of:

  1. The input types
  2. The method’s return type.

Here’s a class implementation where performMethodsViaSelectors method performs the other class methods by way of selectors:

@implementation ClassForSelectors

- (void) fooNoInputs {
  NSLog(@"Does nothing");
}

- (void) fooOneIput:(NSString*) first {
  NSLog(@"Logs %@", first);
}

- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
  NSLog(@"Logs %@ then %@", first, second);
}

- (void) performMethodsViaSelectors {
  [self performSelector:@selector(fooNoInputs)];
  [self performSelector:@selector(fooOneInput:) withObject:@"first"];
  [self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
}

@end

The method you want to create a selector for has a single input, so you would create a selector for it like so:

SEL myTestSelector = @selector(myTest:);

via Objective-C: Calling selectors with multiple arguments – Stack Overflow.

Accessing AppDelegate instance

AppDelegate object can access from any class in the same application like below. Methods or properties shared between controllers can be defined under application delegates.

SomeAppDelegate *appDelegate
  = (SomeAppDelegate *)[[UIApplication sharedApplication] delegate];

How to access special directory on the iphone device

Use NSSearchPathForDirectoriesInDomains(). First argument “NSDocumentDirecotry” is the key to specify special directory, in this case Document directory under the application. The method returns absolute path expression.

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                               NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSLog(@"NSDocumentDirectory is %@", documentsDirectory);

Following is the list of the special directory key and result. Some keys are defined in the header file but actually they return nothing.

NSApplicationDirectory: /var/mobile/Applications/{APPID}/Applications
NSDemoApplicationDirectory: /var/mobile/Applications/{APPID}/Applications/Demos
NSDeveloperApplicationDirectory: /var/mobile/Applications/{APPID}/Developer/Applications
NSAdminApplicationDirectory: /var/mobile/Applications{APPID}/Applications/Utilities
NSLibraryDirectory: /var/mobile/Applications/{APPID}/Library
NSDeveloperDirectory: /var/mobile/Applications/{APPID}/Developer
NSUserDirectory: Not found
NSDocumentationDirectory: /var/mobile/Applications{APPID}/Library/Documentation
NSDocumentDirectory: /var/mobile/Applications{APPID}/Documents
NSCoreServiceDirectory: Not found
NSDesktopDirectory: /var/mobile/Applications/{APPID}/Desktop
NSCachesDirectory: /var/mobile/Applications/{APPID}/Library/Caches
NSApplicationSupportDirectory: /var/mobile/Applications/{APPID}/Library/Application Support
NSDownloadsDirectory: /var/mobile/Applications/{APPID}/Downloads
NSAllApplicationsDirectory: /var/mobile/Applications/{APPID}/Applications
NSAllLibrariesDirectory: /var/mobile/Applications{APPID}/Library

Repeating background image in native iPhone app – Stack Overflow

Apparently a UIColor is not necessarily a single color, but can be a pattern as well. Confusingly, this is not supported in Interface Builder.

Instead you set the backgroundColor of the view (say, in -viewDidLoad) with the convenience method +colorWithPatternImage: and pass it a UI Image. For Instance:

- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor =
    [UIColor colorWithPatternImage:
       [UIImage imageNamed:@"gingham.png"]];
}

Of course, don’t forget to add the image file to your application bundle.

via Repeating background image in native iPhone app – Stack Overflow.

Applying animation while resizing or moving the view

Animation can be applied while its frame, bounds, center, transform, alpha… is being changed.  The key is set start and end values between beginAnimations and commitAnimations, so called animation block.


[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration: 1.0];

// set original position
[view setFrame:CGRectMake(0, 0, 100, 100)];

// move and grow
[view setFrame:CGRectMake(100, 100, 200, 200)];

[UIView commitAnimations];

Create alert dialog

UIAlertView takes care of this


UIAlertView *alert = [[UIAlertView alloc]
                       initWithTitle:@"Alert View"
                       message:@"Here is an alert message"
                       delegate:nil
                       cancelButtonTitle:@"Cancel"
                       otherButtonTitles:@"OK", nil];
[alert show];

// Since alert object is allocated above, it must  be released here
[alert release];