iPhone Development

Just another iPhone Blog

Category Archives: iPhone

Porting to Swift from Objective-C

Finally its time to take swift language on a serious note. All the examples in the blogs have been converted to swift language. With me having worked with a bit of Java(Android), Python and javascript, I thought i could speed up my learning by porting one of the existing Objective-C project where I can touch upon all most often used elements

Note: This is not a Introduction to Swift programming post. I would suggest you read this, if you are an seasoned Objective-C developer and want to see a sneak peak of what Swift has to offer you.

In this post, I will be walking you through the differences/modifications I found when porting from Objective-C to Swift ( Don’t mistake this with Convert-to-swift feature in Xcode). The differences would be more of a design / semantical in nature and not one-to-one mapping of syntax. Fo e.g. I will not say that to declare a class, you use class keyword  in swift instead of @interface in Objective-C. These differences are nothing new in any object oriented languages. However, Objective-C being dynamic typed language, It need a perspective change to program in swift, especially if you have been coding in Objective-C for a long time. 

 

#1 You don’t have to subclass all your classes from NSObject

“NSObject is root of all the classes. It provides methods for things like alloc, init and release. Objective-C is all about sending messages to other objects – so NSObject exists to provide this basic functionality” – from http://stackoverflow.com/a/12991946/623569

#2 Immutability is let, Mutability is var. Always start with ‘let’

Its takes time to get used to using let or var keywords to declare a variable, and it takes more time to know that mentioning Data type is not mandatory. But the key thing, is swift compiler does not complain if you declare a variable using var and does not modify it. This means, that you will end up with swift compiler generating a lot of code to support mutability of these variables which directly affect overall performance.

@iDeekshi got me a nice tip – Start with declaring a variable as let and let the compiler complain when it is mutated.

#3 Yet another block syntax 

It took a lot of time for me to practice the block syntax in Objective-C. In swift, it looks like I am back to square one. Flower braces ‘{‘ starting before the parameter declaration, and writing the function definition after ‘in’ keyword is something I am still getting used to.  Here is it how it looks:

{

[capture list] (parameters) -> Return Type  in

<code>

..

..

#4 Use === to compare two object pointers

Comparing two object pointers studentObj == otherStudentObject will now need to be studentObject === otherStudentObject. Its a good move.

#5 You no longer need NSDictionary to send more than one value. Swift introduces Tuples to return multiple values

This has been a long time ask from me. I am glad we finally have it. You can create a type with just defining all the values and its types in a parenthesis as show below

func getMinAndMax( numbers : [Int] ) -> (min : Int, max : Int ){ 

   var max = numbers[0] , min = numbers[0] 

 ..

 ..

return (min,max)

}

 

#6 Initialize all your variables in the class before calling super init.

class Person{

var name : “”

init() {

name = “<unknown>”

}

}

class Teacher : Person{

var subjects : [String]

init() {

 //we have to initialize the subjects before calling super init

subjects = [“English” , “Kannada”]

super.init()

}

}

This is not the complete list. I have only picked those which I thought had a striking difference from what we are used to while programming in Objective-C. 

Let me know your experiences while porting Objective-C to swift code through comments.

Happy Coding 🙂

Distributing iOS Static Library via CocoaPods

I was new to cocoa pods and looked at their documentation on how to create a pod and distribute. They mainly focused on examples that involved distributing source files rather than a pre-built iOS static library. Hence I want to make a short post on how the pod spec looks like if you are shipping an iOS static library via Cocoapods. 

 

This post does not list steps on creating pod spec and uploading it to the master repo. I will rather provide links which helped me doing that. Please read through if you already know what is cocoa pods and you have an iOS static library which you need to distribute through Cocoa pods.

 

If you ended up this page as a newbie to cocoa pods, don’t worry.  Refer the following links and come back.

 

For information on how to consume cocoa pods as well as how to create one, I found this blog very helpful – http://nshipster.com/cocoapods/

 

I strongly recommend to test your pods locally before pushing things to master cocoa pods repo: here is how you do that http://www.cocoanetics.com/2013/05/8130/

 

Assuming you are all setup with your pod specs, below are the attributes of pod spec which is vital in distributing iOS Static library

 

s.source_files : Specify which files need to be copied. In our case, we need to copy the the Calculator.h header file. The value of the source_file attribute is the relative path of the location of header file from the Podspec location.

 

s.public_header_files = Specifies the header files to include and search for. Value is the relative path of the header files and the path will be added to User Header file search path in the Xcode build settings.

 

s.library = the Libraries to link with in order for the static library to compile successfully. In our example, the library requires the stdc++ library. The value is the library name without appending lib as prefix. For e.g., stdc++. If you have multiple libraries as dependency, provide them as a comma separated values. 

 

s.framework = List of frameworks that the library is dependent upon. As every project by default is linked with UIKit, Foundation, You can specify any other frameworks as a comma separated values.

 

 

s.preserve_paths = We need to specify the files to be copied during the installation. In our example we need to explicitly copy our libCalculator.a file after installation onto the clients system. The value of this attribute would be the relative path ( from the PodSpec)  of the files to be copied. 

 

s.requires_arc = The value is either true or false. Since our example project supports ARC, we set it as true

 

s.ios.vendored_library = Specify the library, libCalculator.a to be copied while installing the pod

 

Additional attributes that might come in handy

s.dependency = Reference to another pods, where the library is dependent upon. For the simplicity of the example, I have not included any libraries as dependents.

 

s.xcconfig = There would be other build settings, for which there are no corresponding  attributes in Podspec. In such cases, you can use xcconfig to specify the build settings directly.

For example, to set the HEADER_SEARCH_PATH build settings you can specify them in a json style like

{ “HEADER_SEARCH_PATH” => “$(SDKROOT)/usr/include/libxml2“}

 

 

Here is the final PodSpec

 

Pod::Spec.new do |s|

s.name = “CalcLib”
s.version = “1.0”
s.summary = “Example iOS Static Library – Calculator. “

s.description = <<-DESC
This iOS Static library is used to explain how to distribute iOS Static library via cocoapods
DESC

s.homepage = “https://github.com/bharath2020/CalcLibrary/blob/master/README.md&#8221;
s.license = { :type => “BSD”, :file => “LICENSE” }

s.author = { “Bharath Booshan” => “bharath2020@gmail.com” }
s.social_media_url = “http://twitter.com/bharath2020&#8221;

s.platform = :ios, “6.0”
s.source = { :git => “https://github.com/bharath2020/CalcLibrary.git&#8221;, :tag => s.version.to_s}
s.source_files = “include/*.h”
s.public_header_files = “include/*.h”

s.preserve_paths = “libCalculator.a”
s.ios.vendored_library = “libCalculator.a”

s.libraries = “stdc++”, “Calculator”
s.requires_arc = true
end

 

Test this Sample

I have created a test library named Calculator which calculates a^2 + b^2 + 2ab for a given values a and b. For demonstration purposes, i have internally used c++ class to perform addition and multiplication. This is to demonstrate how to supply additional dependent libraries in the pod spec file.

 

Here is the github link : https://github.com/bharath2020/CalcLibrary

 

To test the library with an example project, add below line to your pod file


pod ‘CalcLib’

 

and execute pod install or pod update


You can insert the following code in your example project for verification

 

Calculator *calci = [[Calculator alloc] init]

int result = [calci APlusBWholeSquare:2 andB:3]

 

Here are few references who distributes iOS Static library via cocoa pods:

https://developers.helpshift.com/ios/cocoapods/

https://github.com/Ancestry/CocoaPod-Specs/blob/master/AdamSDK/2.1.0.1/AdamSDK.podspec

 

Hope this Helps.

UITableView Tricks

 

 

 

 

Recently we came across innovative UI controls like Path and Clear controls. I am pretty amazed to see a simple UITableView and its cells in iOS, can be tweaked to get a eye-catching effects as in Clear app.  After that there came a series of controls using UITableView, but this one from raw engineering was quiet nice.

 

After playing with it, I revisited the nuances of UITableView and came up with this simple UI Layoout which is our topic now. Take at look at this demo

 

 

You can find the Circle View Source in GitHub

 

I drew this sketch quickly.

 

 

IMG 4359

  

 

I laid down some rules before I started implementing.

 

1. I made clear that this control will not built ground up from scratch

2. Want to leverage the full power of Dequeue in UITableView 

3. Above two rules, means I should be concentrating only on how the content is laid out to present the data in different manner to the user and make it fun.

 

The main task that revolves around this control is how do we lay out the table cells. I used some basic trigonometry function which find out the point in circumference of the circle.

 

So the heart of this control resides in this method where on the while we find out the YPosition of each cell and adding yOffset of the Scrollview’s content offset. This means that the cell would move relatively as the tableview is scrolled.

 

The goal is to find out the X Position which is obtained by using Circle / Ellipse Equation

 

y = vertical_radius * sin ( angle )


x = horizontal_radius * cos (angle)

 

-(void)setupShapeFormationInVisibleCells

{

    NSArray *indexpaths = [mTableViewindexPathsForVisibleRows];

    float shift = ((int)mTableView.contentOffset.y % (int)mTableView.rowHeight);  

    int totalVisibleCells =[indexpaths count];

   

    float y = 0.0;

    float radius = mTableView.frame.size.height/2.0f;

    float xRadius = radius;

    

    for( NSUInteger index =0; index < totalVisibleCells; index++ )

    {

        BBCell *cell = (BBCell*)[mTableView cellForRowAtIndexPath:[ indexpaths objectAtIndex:index]];

        CGRect frame = cell.frame;

        //we get the yPoint on the circle of this Cell

        y = (radius-(index*mTableView.rowHeight) );//ideal yPoint if the scroll offset is zero

        y+=shift;//add the scroll offset

        

        

        //We can find the x Point by finding the Angle from the Ellipse Equation of finding y

        //i.e. Y= vertical_radius * sin(t )

        // t= asin(Y / vertical_radius) or asin = sin inverse

        float angle = asinf(y/(radius));

        

        //Apply Angle in X point of Ellipse equation

        //i.e. X = horizontal_radius * cos( t )

        //here horizontal_radius would be some percentage off the vertical radius.

        //percentage is defined by HORIZONTAL_RADIUS_RATIO

        //HORIZONTAL_RADIUS_RATIO of 1 is equal to circle

        float x = (floorf(xRadius*HORIZONTAL_RADIUS_RATIO)) * cosf(angle );

        x = x + HORIZONTAL_TRANSLATION;

        

        frame.origin.x = x ;

        if( !isnan(x))

        {

            cell.frame = frame;

        }

    }

}

 

 

Couple Macros found in source code which you could control”

  • HORIZONTAL_RADIUS_RATIO – defines the ratio between Vertiacl and horizontal radius. HORIZONTAL_RADIUS_RATIO of value 1 is equal to circle
  • HORIZONTAL_TRANSLATION – Helps translate the position of whole Circle / Ellipse i.e the position of the cells 

You can find the Circle View Source in GitHub

 

 

IMPORTANT UPDATE: 

 

A major improvement has been made to this project. Please read UITableView Tricks – Infinite Scrolling  to know about the new features and improvements.

 

 

——————————————————————————————-

UPDATE #1: 

This Post has been featured in 

 

 ——————————————————————————————–

UPDATE #2:

Have modified the source code to support the inverse form of the circle i.e the circle can be turned toward right as shown in figure by setting the CIRCLE_RIGHT_DIRECTION macro to 1

 

Screen Shot 2012 07 19 at 11 03 55 PM

———————————————————————————————- 

 

 

 

Hope you enjoyed this. Let me know your comments.

Happy Coding 🙂

Thoughts on iOS UDID

There is a lot of buzz with Apple’s rejection of apps accessing UDID API . Let us analyze it.

 

 

What is UDID?

 

UDID is the unique identifier to identify an iOS device uniquely. Apple had exposed an API to access this unique identifier from the start of iOS 2.0 SDK. This made interesting things possible and eventually became a critical API for some of the application’s core functionality. For example. Flurry Analytics, depend on this UDID for reporting number of devices an application is activated. Although, I cannot go through all the list of application using this API, let us do some Impact Analysis and possible problems and their solutions from this move by Apple.

 

When would you use the uniqueIdentifier?

 

I would typically use it in the context where I need to uniquely identify the device in a pool of iOS devices, where this info is send to a centralized place and is used for various purposes. Standalone applications more often does not need this info, unless they have integrated with third party SDK like Flurry, to support non-core features of an application, such as gathering statistics. Therefore, we would not keep this category of applications as these does not have major dependency on UDID.

 

 

What would you do with uniqueIdentifier with a pool of device?

 

Scenario 1:

 

“A scenario could be where the application could act as client and all the instances of the application across the devices are writing some data into the centralized place, could be a Mac or a Centralized Server. In this case the unique identifier would be able to identify the application instance uniquely to resolve the conflicts, say while writing the data to same location.”

 

Syncing

Fig: Scenario 1 showing Application installed in multiple iOS devices syncs with Mac / Server sharing and updating the data

Example: A Simple Notes application where notes are recorded in various iOS devices and then are synchronized with the Mac Application, where the Mac Application acting as a centralized unit.

 

Scenario 2:

 

“Another scenario would be to individually track the number of devices in which the application is activated which helps the sales people to pitch up their sales or we can find them in many of the third party ads which aid in gaining statistics of the application”

 

Example: Analytics SDK like Flurry, InMobi and so on.

 

While the first scenario helps the application in its core functionality, the second scenario is matter of statistics that helps drive the sales. However, accessing a unique identifier of a device without knowledge is a breach of privacy which i believe the motive behind apple deprecating this API.

 

Before digging deep, Let us look at the alternative solution from Apple?

 

Special Considerations:

 

Do not use the uniqueIdentifier property. To create a unique identifier specific to your app, you can call the CFUUIDCreate function to create a UUID, and write it to the defaults database using the NSUserDefaults class.

 

Well, CFUUIDCreate does create the unique identifier, but will that be sufficient to identify the Device uniquely?? Wait, am I sounding wrong! Your read it right.

Although Apple recommend to create unique identifier and store it in defaults, it works fine as long as the app isn’t deleted and re-installed by the user. Since, doing that would delete the defaults database and upon re-installing a fresh unique identifier would be created which defeats our purpose.

 

Let us track back and see what exactly we need

“We need to find a way where an application would identify uniquely against its clone across multiple devices.”

The critical requirement here is not creating a unique identifier, but persisting it from the time application is installed on a device till literally the lifetime of the device and not the application. Uh!!

There are many solutions floating around like the one from crashlytics, where they achieve the persistence by storing the custom unique identifier in the UIPasteboard. However, there are couple of cons here

  • Apple does not guarantee that the Pasteboard data persists permanently across OS upgrades or reboot
  • Any other application can access this data or override them and one need to ensure that this would be in un-readable form for other that the application which created it.

 

My Solution (Intermediate):

The solution is to change the way we modelled our application behavior. For you to understand, let me divide the iOS era into two.

Pre-iCloud & Post-iCloud.

In Pre-iCloud we used to treat each iOS device as a separate one even though they are owned by ( literally under same apple id) single person. This means that an app in iPhone would have different state than the one in iPad, and probably a External Sync would be required to get them into single state.

In Post-iCloud era, as a developer, one should not distinguish between an application installed in two iOS device grouped under single Apple ID, which is strong point behind the Apple’s iCloud – “It Just Works”. i.e the iCloud make sure that all the data and state information would be consisted across the iOS devices grouped under single Apple ID.

With that differentiation, the solution would be:

“Create a unique identifier as suggested by the Apple and  store them in defaults as wells as in iCloud. Check NSUbiquitousKeyValueStore or using this short piece of library from Mugunth Kumar which I liked, for storing into iCloud. So Even if the App is deleted, the same ID would be retrieved back from iCloud, unless your iCloud is reset which accom”

NOTE: We could use a same approach for tracking the number of apps installed with the difference being the count would be number of users installed the application rather than the number of devices using it.

 

What are your thoughts on this?

Pattern Drawing with CGPattern in iOS or Mac

If you are looking for help on how to stroke or fill up a pattern in iOS or Mac OS X, then You have landed at the right place.

NOTE: A reader of this post is assumed to have prior knowledge of custom drawing in iOS’s UIView, CGContext, and Quartz 2D basics

You can find the Code sample from Github

The Sample code demonstrates the following things:

  • Creation of 3 Different kinds of patterns using CGPattern
  • In the Sample, tap “Change Pattern” to switch to next pattern
  • Use the slider, to increase the size of pattern cell

pattern is an image, usually small, used for filling regions by tiling, that is, by placing copies of the pattern side by side like ceramic tiles. Here we see how we can achieve pattern filling in iOS or Mac using CGPattern.

A step by step explanation on usage of CGPatterns

Quartz draw the patterns using cell based drawing technique, where it would provide us the option to draw a single pattern cell in a context, and uses the context to tile across the remaining area evenly.

STEP 1 : Create a CGPattern instance as below

//Pattern Callback methods

// drawPatternCell – callback to draw a single cell

//PatternReleaseInfoCallback – invoked when a pattern is released

CGPatternCallbacks callBack;

callBack.drawPattern = &drawPatternCell;

callBack.releaseInfo = &PatternReleaseInfoCallback;

callBack.version = 0;

 

// param1 – &patters_types[patternCount] – a context info, here which defines which pattern to be drawn


// param2 – rect of a single pattern cell

 

// param3 – transformation matrix

 

// offsetX – a offset or horizontal gap between each cell.. minimum should be width of the cell

 

// offsetY – a offset of vertical gap between each cell. minimum should be heigh of the cell

 

// Style of – how the pattern cell are to be placed where are drawn on a region bigger than the single pattern cell

 

// shouldColor –   a pattern can also be used as a mask, where the color is applied during the actual context where the pattern is drawn. So, literally you have to say true, if the pattern cell can chose its color, or no if the color at its main context is to be chosen

 

// callback – 2 callbacks encapsulated in a struct CGPatterCallbacks

 

_patterns[patternCount] = CGPatternCreate(&patters_types[patternCount], CGRectMake(0.0, 0.0, PATTERN_CELL_WIDTH, PATTERN_CELL_HEIGHT), CGAffineTransformIdentity, PATTERN_CELL_WIDTH, PATTERN_CELL_HEIGHT, kCGPatternTilingConstantSpacing, true, &callBack);

 

 

STEP 2:  (Important) define the drawPattern callback as below. This is the place where you are allowed to draw a single cell of a pattern. The drawing technique of pattern cell is same as one would draw in View’s drawRect method or drawing with any CGBitmapContext.

 

Pattern 1 – Chequered flag –

Chequered Flag Pattern

//Chequered Flag

//Fill the entire background with white color

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth, cellHeight));

 

CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

//Fill the top left quarter of the cell with black

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth/2.0, cellHeight/2.0));

 

//Fill the bottom right quarter of the cell with black

CGContextFillRect(context, CGRectMake(cellWidth/2.0, cellHeight/2.0, cellWidth/2.0, cellHeight/2.0));

 

Pattern 2

pattern_2

//http://www.kitchenbeforeandafter.com/wp-content/uploads/2009/05/kitchen-backsplash-tile-patterns2-300×216.gif

//\       /

// \     /

//  \ _ /

//   |_|

//  /   \

// /     \

///       \

 

 

//stroke middle square

CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor);

CGContextFillRect(context, CGRectMake(0.0, 0.0, cellWidth, cellHeight));

 

 

//stroke diagonal

CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);

CGPoint points [] = {{0.0,0.0}, {cellWidth,cellHeight }, {cellWidth,0.0}, {0.0,cellHeight}};

CGContextStrokeLineSegments(context, points, 4);

 

CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);

int num_of_parts = 8;

float partWitdth = cellWidth / num_of_parts;

CGRect middleSpot = CGRectMake(partWitdth * 3, partWitdth*3, 2* partWitdth, 2*partWitdth);

 

CGContextFillRect(context, middleSpot);


Pattern 3

Circular_pattern

The Elements involve in this pattern are a circle drawn with various transformations

  • Circle
  • Semi-Circle
    • Circle shifted towards left by half the width of the cell
    • Circle shifted towards right by half the width of the cell
    • Circle shifted towards top by half the height of the cell
    • Circle shifted towards bottom by half the height of the cell
  • Arc
    • Circle shifted towards left & top by half the width and half the height of the cell respectively
    • Circle shifted towards left & bottom by half the width and half the height of the cell respectively
    • Circle shifted towards right & top by half the width and half the height of the cell respectively
    • Circle shifted towards right & bottom by half the width and half the height of the cell respectively

You can clone a copy of this Sample project from GitHub

STEP 3: Applying the Pattern.

Finally we would be applying the pattern in drawRect method of BBQuartzView in this sample.

// Drawing code

float alpha = 1;

 

//choose the pattern to be filled based on the currentPattern selected

CGContextRef context = UIGraphicsGetCurrentContext();

CGColorSpaceRef patternSpace = CGColorSpaceCreatePattern (NULL);// 6

CGContextSetFillColorSpace (context, patternSpace);// 7

CGColorSpaceRelease (patternSpace);

 

//set the pattern as the Current Context’s fill pattern

 

//we dont need to set any color, as the pattern cell itself has chosen its own color

CGContextSetFillPattern(context, _patterns[_currentPattern],   &alpha);


//We would be filling the entire portion of this view

CGContextFillRect(context, [self bounds]);

  • Choose the pattern that needs to be applied. In this sample, the pattern is chosen based on the _currentPattern variable value (0- Chequered pattern, 1- Pattern2, 3- Pattern3)
  • Patterns are created at the time of initializing the view. In sample, it is in initWithCoder method of BBQuartzView
  • The drawPattern callback is invoked only when the pattern is all set to be drawn. In my case, it is invoked when CGContextFillRect in the above drawing code snippet. You can use this pattern to fill any shape. The selected pattern would also be reflected while using CGContext drawing API like, CGContextFill variants, CGContextFillPath variants
  • The drawPattern Callback is called only once in its lifetime and for subsequent drawing, the pattern cell buffer would be re-used. So resize the single pattern cell, the patterns are re-created

Here is are the pics how the patterns would look like(captured from sample code).

patterns.png

 

You can clone a copy of this Sample project from GitHub

Hope, you find this piece of info useful. Fill in your comments or queries in below comment’s section. Waiting for you comments.

Happy Coding 🙂

iOS Open Folder Animation

As I was fiddling with my iPad,  Open Folder Animation in iOS caught my attention. After giving it a serious though on how to achieve it, It looked Trivial.

iOS Folder View

 

Let us get together to write a piece of code which does this cool animation.

 

1. Plan

iOS_Folder_View_Plan.png

We can achieve this using 3 Main Layers

1. Layer -1 (Main View) : The Lowest layer contains the main screen which stores the main content

2. Layer -2  (Folder View): The Folder View, which hosts the Folder Icons. Once the Folder Opens, This is the only view which is active accepting the Touch Event. This layer resides above Layer-1

3. Layer-2.1 (Arrow ) : The Arrow, which points to the selected folder. This is movable on x-Axis.

4. Layer-3 (Layer to host Bottom part of Main Content View) : This layer hosts the bottom part of the Main Content View (Layer -1) i.e from point where Folder View ( Layer-2) occupies to the end of the Main Content View. This Layer is place above the Folder View (Layer-2 ) in terms of Level. In Terms of position on screen, this layer is placed just below the Folder View(Layer-2)

 

2. Execution

We can achieve Open Folder Animation effect in 3 Simple Steps

STEP 1: Capture the Main View Content into an image

  • Capturing Main View Content Image can be achieve using renderInContext: API. as shown in code snippet below
  • Clip the Main View into two parts, One part is the visible portion above the Folder view and rest of the image would be hosted in Layer -3. The Trick used in sample code below to avoid the cutting of the image into two parts, is by setting the Layer-3 bounds, such that it should hide the top portion (Part-1) of the Main Content view.

-(void)captureImageFromPointAndSetupMaskView:(CGPoint)selectedFolderPoint

{

UIGraphicsBeginImageContext(mMainBackgroundView.frame.size);

//capture the main content view

[mMainBackgroundView.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();

[mBottomPartOfMainBackgroundView setImage:backgroundImage];

//set the bounds such that the we hide the part of the main content image, which is visible just above the Folder View.

//This gets the continuation effect on the image once the folder view appears on screen

[mBottomPartOfMainBackgroundView.superview setBounds:CGRectMake(0.0, selectedFolderPoint.y + mSelectedArrowTipView.frame.size.height, mMainBackgroundView.frame.size.width, mMainBackgroundView.frame.size.height)];


}

 

STEP 2: Layout the Folder View(Layer 2 & 2.1) and Bottom Part Of Main Content View (Layer -3)

  • Folder View and Arrow View are grouped in Single View.
  • Place The Arrow View such that it is right below and to the Center of the Tapped Folder Icon Tapped
  • Place the Folder View Just below Arrow View

-(void)layoutBottomPartOfMainViewRelativeToPointInMainView:(CGPoint)selectedFolderPoint

{

//Place the Folder View Just below Arrow View

CGRect folderViewFrame = [mFolderView frame];

folderViewFrame.origin.y = floorf(selectedFolderPoint.y);

[mFolderView setFrame:folderViewFrame];

//making sure the View which displays bottom part of Main Backgorund View is just below  the Folder View

CGRect maskFrame = mBottomPartOfMainBackgroundView.superview.frame;

maskFrame.origin.y = folderViewFrame.origin.y + mSelectedArrowTipView.frame.size.height;

mBottomPartOfMainBackgroundView.superview.frame = maskFrame;

//Place The Arrow View such that it is right below and to the Center of the Tapped Folder Icon Tapped

[UIView setAnimationsEnabled:NO];

mSelectedArrowTipView.center = CGPointMake(selectedFolderPoint.x, 0.0);

CGRect arrowFrame = mSelectedArrowTipView.frame;

arrowFrame.origin.y = 0.0;

mSelectedArrowTipView.frame = arrowFrame;

 

[UIView setAnimationsEnabled:YES];

}


 

STEP 3- Push The Layer-3 which hosts the other part of the Main Content View

-(void)layoutFinalFrameOfBottomPartOfMainContentView

{

//Push The Layer-3 which hosts the other part of the Main Content View

CGRect maskFrame = mBottomPartOfMainBackgroundView.superview.frame;

maskFrame.origin.y = mFolderView.frame.origin.y + mFolderView.frame.size.height;

mBottomPartOfMainBackgroundView.superview.frame = maskFrame;

}

 

Thats it !! The above 3 steps would be called upon tapping a Folder  Icon as show in below code snippet

-(IBAction)openFolder:(id)sender

{

//get the center point of the tapped folder

CGPoint selectedFolderPoint = CGPointMake([sender center].x, [sender frame].origin.y + [sender frame].size.height);

if( mFolderView.hidden )//if folder is not opened

{

//open folder animation

//STEP 1: Capture the Main View Content into an image

[self captureImageFromPointAndSetupMaskView:selectedFolderPoint];

//STEP 2: Layout the Folder View(Layer 2 & 2.1) and Bottom Part Of Main Content View (Layer -3)

[self layoutBottomPartOfMainViewRelativeToPointInMainView:selectedFolderPoint];

[UIView beginAnimations:@”FolderOpen” context:NULL];

[UIView setAnimationDuration:0.5];

[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

//captures the main background view’s image

mFolderView.hidden=NO;

mBottomPartOfMainBackgroundView.superview.hidden=NO;

//STEP 3- Push The Layer-3 which hosts the other part of the Main Content View

[self layoutFinalFrameOfBottomPartOfMainContentView];

[UIView commitAnimations];

}

else {

//close folder animation

[UIView beginAnimations:@”FolderClose” context:NULL];

[UIView setAnimationDuration:0.5];

[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];

[UIView setAnimationDidStopSelector:@selector(animation:didFinish:context:)];

[UIView setAnimationDelegate:self];

//restore the layout and hide the folder view after animation

[self closeFolder:selectedFolderPoint];

[UIView commitAnimations];

}

}

 

3. Result

Download the Full Source Code Here : iOS Open Folder Animation.zip

A Video of the Sample Code can be found here: iOS Open Folder Animation Video

If you like this post, Please leave your feedback / comment and Share this (See below for sharing options) to spread to all others who might be interested 🙂

Happy Coding 🙂

Tools helpful in Creating Universal iOS Apps

This post is about Tools [Code Snippets] which I prepared in the process of creating Universal iOS Apps

 

1. Identifying the Device

 

#device DEVICE_IS_IPAD (UIUserInterfaceIdiomiPad == [BBUtilities getUserInterfaceIdiom])

#device DEVICE_IS_IPHONE (UIUserInterfaceIdiomiPhone == [BBUtilities getUserInterfaceIdiom])

 

/*snippet to get user interface idiom*/

static UIUserInterfaceIdiom sDeviceUIIdiom = -1; -(UIUserInterfaceIdiom)getUserInterfaceIdiom

{

 

//We make sure that this method is invoked only once throughout the application lifetime

if( sDeviceUIIdiom == -1)

{

if([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])

{

sDeviceUIIdiom = [[UIDevice currentDevice] userInterfaceIdiom];

}

}

return sDeviceUIIdiom;

}

 

2. Identifying iPhone 4 Device

 

#define DEVIS_IS_IPHONE4 ([BBUtilities isiPhone4])

 

/*snippet to get whether current device is iPhone 4 or not*/

static UIUserInterfaceIdiom sIsiPhone4 = -1;

 

-(BOOL) isiPhone4

{

//We make sure that this method is invoked only once throughout the application lifetime     i

if( sIsiPhone4 == -1)

{

if([[UIScreen mainScreen] respondsToSelector:@selector(scale)])

{

sIsiPhone4 = [[UIScreen mainScreen] scale] ==2.0 ;

}

else

{

sIsiPhone4=0;

}

}

return sIsiPhone4;

}

Quick Tip : Initializing static variables of a class in Objective C

Initializes the receiver before it’s used (before it receives its first message).

 

+ (void)initialize


Discussion The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.


[Reference : NSObject Class Reference]

You can place all your static member variable initialization code in this method as it guarantees it would be called only once BEFORE any method in that Class is invoked through any of its objects.

Happy Coding 🙂

Search 4 Twitter xAuth and OAuth Samples ENDS here

Hello,

This post is place where you will be re-directed to places where you learn about xAuth and OAuth w.r.t Twitter, Take away Sample code of Twitter Engine supporting xAuth and OAuth both for i[Phone] OS and Mac OS Platforms

  1. Official Twitter API Documentation
  2. xAuth Explained
  3. xAuth for Browserless Token Exchange
  4. OS X 10.5 Demo With Sample Code [See References section in that site]
  5. iPhone xAuth Explained with Sample Code
  6. MGTwitterEngine xAuth Support
  7. Testing TwitPIC OAUTH

 

 

Others

  • iPhone Dev SDK – Twitter Agent
  • SlideShow Presentation
  •  

    Hope this Helps!!

    Have Fun 🙂

    Efficient Memory Handling in UIViewController-Part 2

    In the last post we discussed about the skeleton of a typical UIViewController which handles memory warning efficiently.

    In this post, I will provide you Xcode Templates of a UIViewController, which takes care of all these things we have discussed earlier here, thus making our Lives easier.

    Following steps explain How to add these templates:

  • Navigate to Developer->Platforms->iPhoneOS.platform->Developer->Library->Xcode->File Templates->Cocoa Touch Class Folder
  • KEEP A BACKUP OF "UIViewController subclass" folder
  • Download the zip filehere
  • Unzip the file and replace the “UIViewController subclass” folder with the new one
  •  

    Please note that these templates works for UIViewControllers created with File->New File option

    Thats it, there should be no more hassles with Memory now!!

    Happy Coding!! 🙂

    %d bloggers like this: