Tuesday, October 29, 2013

Category Concepts Using Portrait to Landscape ViewController Pushing



Considering: View A: Portrait only - View B: Landscape only
I couldn't do it in the navigation controller. Instead what I did was to open a modal view from view A to view B and force a new navigation controller into this view.
This is working for me in iOS5+.
You need to create a category for the navigation controller like this:


UINavigationController+Rotation_IOS.h


#import <UIKit/UIKit.h>

@interface UINavigationController (Rotation_IOS)

- (BOOL)shouldAutorotate;
- (NSUInteger)supportedInterfaceOrientations;
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation;

@end


UINavigationController+Rotation_IOS.m


#import "UINavigationController+Rotation_IOS.h"

@implementation UINavigationController (Rotation_IOS)

- (BOOL)shouldAutorotate
{
return [self.topViewController shouldAutorotate];
}

- (NSUInteger)supportedInterfaceOrientations
{
return [self.topViewController supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [self.topViewController preferredInterfaceOrientationForPresentation];
}

@end

AppDelegate.m


  • (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
    {
return UIInterfaceOrientationMaskAll;
}




VIEW A Portrait


- (BOOL)shouldAutorotate
{
return YES;
}


-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationPortrait;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown);
}


VIEW A to VIEW B while Pushing

SignatureViewController *signatureVC=[[SignatureViewController alloc] initWithNibName:@"SignatureViewController" bundle:Nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:signatureVC];
[self presentViewController:navigationController animated:YES completion:nil];



VIEW B Landscape

#pragma mark -
#pragma mark InterfaceOrientationMethods

- (BOOL)shouldAutorotate
{
return YES;
}


-(NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeRight | UIInterfaceOrientationMaskLandscapeLeft;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight || interfaceOrientation == UIInterfaceOrientationLandscapeLeft);
}


Monday, August 19, 2013

Objective-C: Delegate Protocols



To create your own custom delegate protocol, modify the header file for the selected class to add the @protocol declaration, a delegate @property, and declare the methods that delegates can implement:
// MyViewController.h:

#import <UIKit/UIKit.h>

@protocol MyProtocolName

@interface MyViewController: UIViewController

@property (nonatomic, weak) id<MyProtocolName> delegate;

@end

@protocol MyProtocolName <NSObject>
@required
-(void)requiredDelegateMethod;

@optional
-(void)optionalDelegateMethodOne;
-(void)optionalDelegateMethodTwo:(NSString *)withArgument;

@end // end of delegate protocol
In the implementation file, anytime you want to call a delegate method, first check to see if the delegate is set, and if it responds to the selector. Then call the method:
if (self.delegate && [self.delegate respondsToSelector:@selector(optionalDelegateMethodOne)]) {
    [self.delegate optionalDelegateMethodOne];
}
Now for classes you want to conform to your new protocol, include the header file and delegate protocol in the @interface:
#include "MyViewController.h"  // needed to include the @delegate protocol info

@interface FavoritesViewController : UIViewController <MyProtocolName> 
Any required delegate methods must then be implemented in your class's @implementation file.

Objective-C: Singletons



A singleton is a special kind of class where only one instance of the class exists for the current process. (In the case of an iPhone app, the one instance is shared across the entire app.) Some examples in UIKit are [UIApplication sharedApplication] (which returns the sole instance of the application itself), and [NSFileManager defaultManager] (which returns the file manager instance). Singletons can be an easy way to share data and common methods across your entire app.
Rather than create instances of the singleton class using alloc/init, you'll call a class method that will return the singleton object. You can name the class method anything, but common practice is to call it sharedName or defaultName.
@interface AwardCenter : NSObject {
    // whatever instance vars you want
}

+ (AwardCenter *)sharedCenter;   // class method to return the singleton object

- (void)customMethod; // add optional methods to customize the singleton class

@end
In the implementation (.m) file, you should create a static variable to point to the current instance. There are also a few inherited methods you should customize:
#import "AwardCenter.h"

@implementation AwardCenter

static AwardCenter *sharedAwardCenter = nil;    // static instance variable

+ (AwardCenter *)sharedCenter {    
    if (sharedAwardCenter == nil) {
        sharedAwardCenter = [[super allocWithZone:NULL] init];
    }
    return sharedAwardCenter;    
}

- (id)init {
    if ( (self = [super init]) ) {
        // your custom initialization
    }
    return self;
}

- (void)customMethod {
    // implement your custom code here
}   

// singleton methods
+ (id)allocWithZone:(NSZone *)zone {
    return [[self sharedCenter] retain];
}

- (id)copyWithZone:(NSZone *)zone {    
    return self;    
}

- (id)retain {    
    return self;
}

- (NSUInteger)retainCount {
    return NSUIntegerMax;  // denotes an object that cannot be released
}

- (void)release {
    // do nothing - we aren't releasing the singleton object.
}

- (id)autorelease {
    return self;
}

-(void)dealloc {
    [super dealloc];
}

@end
To use the singleton in your code, you'll need to #import the singleton's class header file. Then just call the sharedName class method just as you would any other object:
[[AwardCenter sharedCenter] customMethod];