What is the best way to remove all subviews from parent view/super view?


While working on project, sometime you encountered a situation where you need to remove all subviews from it superview. To achieve this, you need to follow steps below:

  1. Get all the subviews from its superview by calling subviews method.
  2. Iterator over the all subviews.
  3. Remove subview by calling removeFromSuperview method on it.

In Objective-C:

// Remove all subviews from self.view
    for (UIView *subUIView in self.view.subviews) {
        [subUIView removeFromSuperview];
    }

In Swift:

for subUIView in self.subviews as [UIView] {
    subUIView.removeFromSuperview()
}

Best way to remove all subviews:

If you want to remove all the subviews from its superview, then you can achieve same result as above by writing single line of code.

    [[self.view subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

For UIView, you can safely use makeObjectsPerformSelector: because the subviews property will return a copy of the array of subviews.

Using makeObjectsPerformSelector method you can remove all the subviews but,  not subviews based on conditions. So If you want to remove some specific subviews then you must have to iterate over all the subviews. Then based on your condition remove those specific subviews.

Consider you want to remove all the UIButton from your superview then my code will look like this.

    for (UIView *subView in self.view.subviews) {
        if ([subView isKindOfClass:[UIButton class]]) { // Condition
            [subView removeFromSuperview];
        }
    }
Advertisements

How to add .pch or Prefix.pch file in Xcode 6?


What is .pch file?
PCH is stand for Pre-Compiled Header. Prefix headers will compiled and stored in a
cache during compilation and include in each and every file rather than parsing same file multiple
times. As Prefix header parsed only once it make compilation fast.

Overview:~

As you start using Xcode 6 and created new project you realize that, new version of Xcode is not creating <ProjectName>-Prefix.pch file for your project. But don’t worry about that as you can create .pch file for your project any time.

Steps to add PCH file in our project :~

1.) Open your existing project in Xcode. Select File > New > File > iOS > Other > PCH File and click Next.

.pch file

How to add .pch file in Xcode6

2.) Give the name to your PCH file like projectName-Prefix.pch. For example if your project name is iOSSample then PCH file name will be iOSSample-Prefix.pch and click on create button.

3.) Select the PCH file (in our case its iOSSample-Prefix.pch) and replace its content with following.

//
// Prefix header
//
// The contents of this file are implicitly
// included at the beginning of every source file
//

#import <Availability.h>

#ifndef __IPHONE_5_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif

#ifdef __OBJC__
   #import <UIKit/UIKit.h>
   #import <Foundation/Foundation.h>
#endif

4.) Goto Project > Build Settings > Search for “Prefix Header

5.) Under “Apple LLVM 6.0” you will get the Prefix Header key.

How to add .pch file #2

How to add .pch file #2

6.) Type in: YourProjectName/YourProject-Prefix.pch or $(SRCROOT)/YourProject-Prefix.pch

7.) Clean and build your project.

That’s it. Done. Now you can use your PCH file as you were doing in your old Xcode version.

What are the some useful macros in iOS / Objective-C?


What is Macros?

Macros are preprocessor definitions. It mean that before your code is compiled, the preprocessor scans your code and replace the definition of macros wherever it sees the name of your macro.

Mostly we use macros for defining constants. But, you can not see the value of the variable in the debugger. (I don’t care at all :-P)

I have been writing code for almost 3+ years. During that time, I used so many macros. Few of them I listed below and hoping you will also use same them in your code.

/** Float: Degrees -> Radian **/
#define DEGREES_TO_RADIANS(degrees) ((M_PI * degrees) / 180.0
/** Float: Radians -> Degrees **/
#define RADIANS_TO_DEGREES(radians) ((radians * 180.0)/ M_PI)
/**Navigation - Go back - POP view controller **/
#define GOBACK [self.navigationController popViewControllerAnimated:YES]
// Timer Invalidation
#define UA_INVALIDATE_TIMER(t) [t invalidate]; t = nil;
// Device Info
#define IS_IPAD     (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) /** BOOL: Detect if device is an iPad **/

#define IS_IPHONE   (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) /** BOOL: Detect if device is an iPhone or iPod **/

#define IS_IPHONE5  ([[UIScreen mainScreen] bounds].size.height == 568)?TRUE:FALSE /** BOOL: Detect if device is an iPhone5 or not **/
/** BOOL: Is iOS version is greater than or equal to specified version**/
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) \
            ([[[UIDevice currentDevice] systemVersion] compare:(v) options:NSNumericSearch] != NSOrderedAscending)
/** BOOL: IS_RETINA **/
#define IS_RETINA_DEVICE ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] >= 2) 
/** BOOL: Is multi tasking support by device or not **/
#define IS_MULTI_TASKING_SUPPORTED ([[UIDevice currentDevice] respondsToSelector:@selector(isMultitaskingSupported)] && [[UIDevice currentDevice] isMultitaskingSupported])
// Colors
#define UA_RGBA(r,g,b,a)    [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
#define UA_RGB(r,g,b)       UA_RGBA(r, g, b, 1.0f)
// Return "YES" or "NO" string based on boolean value
#define NSStringFromBool(b) (b ? @"YES" : @"NO")

You can use also write your own macros as per your requirements. Check out list of macros that I used in my application.

iOS Platform Internal Codenames


Unlike Google’s Android, it seems that Apple is also using Internal codenames for its major iOS (iPhone operating system) release.

Google’s Android is well-known for following desert themed for its major release of OS. Turns out Apple is also following resort themed for its iOS release to refer internal code names for each.

Following are the secret code names of iOS.

  • 1.0  =  Alpine (1.0.0 – 1.0.2 = Heavenly)
  • 1.1  =  Little Bear (1.1 and 1.1.1 = Snowbird, 1.1.2 = Oktoberfest, 1.1.3, 1.1.4, and 1.1.5 = Little Bear)
  • 2.0  =  Big Bear
  • 2.1  =  Sugarbowl (2.1.1 = Sugarbowl)
  • 2.2  =  Timberline
  • 3.0  =  Kirkwood
  • 3.1  =  Northstar
  • 3.2  =  Wildcat (iPad only)
  • 4.0  =  Apex
  • 4.1  =  Baker
  • 4.2  =  Jasper (4.2.5 – 4.2.10 = Phoenix)
  • 4.3  =  Durango
  • 5.0  =  Telluride
  • 5.1  =  Hoodoo
  • 6.0  =  Sundance
  • 6.1  =  Brighton
  • 7.0  =  Innsbruck
  • 8.0  =  Okemo
  • 9.0  =  Monarch

Reference:

http://en.wikipedia.org/wiki/List_of_Apple_codenames

How to add custom fonts in iOS app


There are many fonts supported by Apple and we can use that any time. But some times we want to add our own custom fonts in app. So, you have to add those fonts manually in our app.

Custom fonts can make all the difference in the world when you’re trying to convey a specific user experience.

Also, custom fonts can provide a much higher level of customisation in app. As a designer, custom fonts are something that, we love.

Custom fonts are added on a per-application basis. You can not add a font to your iOS device and make it available for all of your applications. Luckily, it’s pretty easy to add your own fonts in your iOS app.

Let’s walk through how to add custom fonts to our iOS application.

  1. Include your fonts in your XCode project
  2. Make sure that they’re included in the target
  3. Include your iOS custom fonts in your application plist file
  4. Find the name of the font
  5. Use UIFont and specify the name of the font

That’s it….Its Done….!!!

Step 1: Include your fonts in your XCode project

There are two ways to include fonts in your Xcode project. Either drag and drop your font file(s) into your XCode file tree or right click and “Add Files To…” to select your fonts.

Step 1: Include your fonts in your XCode project

Step 2: Make sure that they’re included in the target

 The next thing to do is to make sure that fonts are included in your build target.

Goto your project settings > Target > Build Phases > Copy Bundle Resources

Step 2: Make sure that they’re included in the target

Step 3: Include your iOS custom fonts in your application plist file

 The next thing to do is to modify your app’s plist to include these font faces. By default, your plist will be named something like [appname]-Info.plist and will reside in the “Supporting Files” folder if you haven’t moved it.

Open it and add a new row called “Fonts provided by application” which will be an array that you need to add all the filenames of the fonts you want to use.

In my case, it was “cinnamon cake.ttf” font as you can see in the screenshot below. The value for Item name should be exact the font file name.

Screen Shot 2014-03-04 at 1.23.08 pm

Step 4: Find the name of the font

This is a common problem for many people trying to include custom fonts into their iOS app. Here you have to specify actual font name rather then font file name.

So in order to find the name of the font you have following two options.

1) Add following snippet of code to log all the fonts available to your app in the console. Find your font name from the output and use that name for setting font name.

- (void)listAllFornts {

    for (NSString* family in [UIFont familyNames]) {
        NSLog(@"%@", family);

        for (NSString* name in [UIFont fontNamesForFamilyName: family]) {
            NSLog(@"  %@", name);
        }
    }
}

2) Double click on your font file name (in my case its, cinnamon cake.ttf) and install if its not installed already. After that, Scroll down to your font and select that font from the “Font Book” MAC-OS X application. Look at the PostScript name attribute and use that name  for setting font name.

Screen Shot 2014-03-04 at 11.49.48 am

Step 5: Use UIFont and specify the name of the font

 Finally, you can simply display your custom font using UIFont and whatever UILabel or UITextView you want.

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 60)];
label.text = @"Hello World!";
label.font = [UIFont fontWithName:@"cinnamoncake" size:20]

Notes:~

  1. Make sure you have a proper font license for mobile/app embedding.
  2. The best format for the custom font is TTF/OTF
  3. If you can’t get a TTF variation of your font, there’s a number of online font converters that you can use. (E.g. Free Online Font Converter)

Source Code:~

You can find the source code from here.

How to add a Contact to the iPhone Address Book


Adding a contact to the iPhone we need to use AddressBook Framework in the iOS SDK. AddressBook Framework allow us to get access to the people’s contact information including personal information.

In this tutorial we are going to create and save new contact with some personal information and save in address book database.

  1. First create the reference to the ABAddressBookRef by calling ABAddressBookCreate() method.
    • CFErrorRef error = NULL;
    • ABAddressBookRef  iPhoneAddressBook = ABAddressBookCreate();
  2. Create a new person record by calling ABPersonCreate() method.
    • ABRecordRef newPerson = ABPersonCreate();
  3. Now start adding data to person object that we created in step-2. Set person’s first name, last name, nick name, organisation name , title and others by calling relevant property name.
    • ABRecordSetValue(newPerson, kABPersonFirstNameProperty, (__bridge CFTypeRef)(@”Milan”), &error); // First name 
      ABRecordSetValue(newPerson, kABPersonLastNameProperty, (__bridge CFTypeRef)(@”Panchal”), &error); // Last name 
      ABRecordSetValue(newPerson, kABPersonNicknameProperty, (__bridge CFTypeRef)(@”SAM”), &error); // nick name 
  4. To set person’s phone, email, or address properties we need to use ABMutableMultiValueRef field. You can also store Social networks, URLs and image
    • ABMutableMultiValueRef multiEmail = ABMultiValueCreateMutable(kABMultiStringPropertyType);
      ABMultiValueAddValueAndLabel(multiEmail, (__bridge CFTypeRef)(@”example@gmail.com”), kABHomeLabel, NULL);
      ABRecordSetValue(newPerson, kABPersonEmailProperty, multiEmail, &error);
  5. Finally add record in database and save the AddressBook object.
    • ABAddressBookAddRecord(iPhoneAddressBook, newPerson, &error);
    • ABAddressBookSave(iPhoneAddressBook, &error);

Following is the method to save contact information in address book. Method will save person’s first-name, last-name, nick-name, organization, image, email addresses, social networks, and URLs

- (IBAction)saveContactToAddressBook {

    CFErrorRef error = NULL;

    ABAddressBookRef iPhoneAddressBook;

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"6.0")){
        iPhoneAddressBook = ABAddressBookCreateWithOptions(NULL, NULL);
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        ABAddressBookRequestAccessWithCompletion(iPhoneAddressBook,  ^(bool granted, CFErrorRef error){
            dispatch_semaphore_signal(sema);
        });

        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

    } else {
        iPhoneAddressBook = ABAddressBookCreate();
    }

    ABRecordRef newPerson = ABPersonCreate();

    // First Name - Last Name - Nickname - Company Name
    ABRecordSetValue(newPerson, kABPersonFirstNameProperty, @"Milan", &error);
    ABRecordSetValue(newPerson, kABPersonLastNameProperty, @"Panchal", &error);
    ABRecordSetValue(newPerson, kABPersonNicknameProperty, @"SAM", &error);
    ABRecordSetValue(newPerson, kABPersonOrganizationProperty, @"Pantech", &error);

    //  Add Emial addresses
    NSArray *emailAddresses = @[@"example@gmail.com"];
    ABMutableMultiValueRef multiEmail =ABMultiValueCreateMutable(kABMultiStringPropertyType);
    for (NSString *email in emailAddresses) {
        ABMultiValueAddValueAndLabel(multiEmail, email, kABHomeLabel, NULL);
    }
    ABRecordSetValue(newPerson, kABPersonEmailProperty, multiEmail, &error);
    CFRelease(multiEmail);

    //  Adding social and Skype
    ABMultiValueRef social = ABMultiValueCreateMutable(kABMultiDictionaryPropertyType);

    NSDictionary *skype = [NSDictionary dictionaryWithObjectsAndKeys:
                           (NSString *)kABPersonInstantMessageServiceSkype,
                           kABPersonInstantMessageServiceKey,
                           @"milan_panchal24",
                           kABPersonInstantMessageUsernameKey,
                           nil];

    NSDictionary *twitter = [NSDictionary dictionaryWithObjectsAndKeys:
                             (NSString *)kABPersonSocialProfileServiceTwitter,
                             kABPersonSocialProfileServiceKey,
                             @"milan_panchal24",
                             kABPersonSocialProfileUsernameKey,
                             nil];

    NSDictionary *facebook = [NSDictionary dictionaryWithObjectsAndKeys:
                              (NSString *)kABPersonSocialProfileServiceFacebook,
                              kABPersonSocialProfileServiceKey,
                              @"MilanPantech",
                              kABPersonSocialProfileUsernameKey,
                              nil];

    NSDictionary*linkedin = [NSDictionary dictionaryWithObjectsAndKeys:
                             (NSString *)kABPersonSocialProfileServiceLinkedIn,
                             kABPersonSocialProfileServiceKey,
                             @"milanpanchal",
                             kABPersonSocialProfileUsernameKey,
                             nil];

    ABMultiValueAddValueAndLabel(social,
                                 (__bridge CFTypeRef)(skype),
                                 kABPersonInstantMessageServiceSkype, NULL); 

    ABMultiValueAddValueAndLabel(social,
                                 (__bridge CFTypeRef)(twitter),
                                 kABPersonSocialProfileServiceTwitter, NULL); 

    ABMultiValueAddValueAndLabel(social,
                                 (__bridge CFTypeRef)(facebook),
                                 kABPersonSocialProfileServiceFacebook, NULL); 

    ABMultiValueAddValueAndLabel(social,
                                 (__bridge CFTypeRef)(linkedin),
                                 kABPersonSocialProfileServiceLinkedIn, NULL); 

    ABRecordSetValue(newPerson, kABPersonSocialProfileProperty, social, &error);

    // Add an image
    NSData *dataRef = UIImagePNGRepresentation([UIImage imageNamed:@"image.png"]);
    ABPersonSetImageData(newPerson, (__bridge CFDataRef)dataRef, &error);

    // URL
    NSArray * blogUrls = @[@"http://www.techfuzionwithsam.wordpress.com",
                           @"http://www.mypoemswithsam.wordpress.com"];

    ABMutableMultiValueRef urlMultiValue = ABMultiValueCreateMutable(kABStringPropertyType);
    for (NSString *blogUrl in blogUrls) {
        ABMultiValueAddValueAndLabel(urlMultiValue, (__bridge CFTypeRef)(blogUrl), kABPersonHomePageLabel, NULL);
    }

    ABRecordSetValue(newPerson, kABPersonURLProperty, urlMultiValue, &error);
    CFRelease(urlMultiValue);

    ABAddressBookAddRecord(iPhoneAddressBook, newPerson, &error);
    ABAddressBookSave(iPhoneAddressBook, &error);

    if (error != NULL) {

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                        message:@"Could not create unknown user"
                                                       delegate:nil
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:nil];
        [alert show];
    } else {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Added Successfully!"
                                                        message:[NSString stringWithFormat:@"%@ was added to your contact successfully.",@"Milan Panchal"]
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
    }

    CFRelease(newPerson);
    CFRelease(iPhoneAddressBook);
}

Click here to download source code.

List of All the Available Fonts on iPhone


Apple intruduced the UIFont class from iOS 2.0.  The UIFont class provides the interface for getting and setting font information. Till the iOS 7 there are total 235 fonts available. Font objects are immutable and so it is safe to use them from multiple threads in your app.

Following snippet of code will be useful to list down all the available fonts in iOS .

- (void)getAllFonts {

    NSArray *familyNames = [UIFont familyNames];
    NSArray *fontNames;
    int totalAvailableFonts = 0;

    for (NSString *familyName in familyNames) {
        NSLog(@"Family name: %s", [familyName UTF8String]);
        fontNames = [UIFont fontNamesForFamilyName:familyName];
        for (NSString *fontName in fontNames) {
            NSLog(@"\tFont name: %s", [fontName UTF8String]);
            totalAvailableFonts ++;
        }
    }

    NSLog(@"Total Fonts are %d",totalAvailableFonts);
}

Click here to check list of all fonts