Apr 27, 2011

Slider class to preview Images or PDF

Finally I was able to find some time to write another post on this blog :)
This time I want to share with you my last github repository in which I put a Xcode4 project of a UISlider subclass that I called PQSliderPreview.
The class and the related demo application (that can be run on iPhone or iPad) wants to show the functionality of the PWSliderPreview which can make a preview of the given PDF document or the array of paths of given images.
The PQSliderPreview can extract the PDF pages or the images at the given path and show it as a preview according to the integer retrieved from the slider.
The snapshot below has been taken from my iPhone and show the preview of the test PDF document present into the demo application.


For the preview image I decided to not use the UIPopoverController to show the preview, but manage manually the position of the UIImageView over the UISlider so to have the same representation for iPHone and iPad.
The UIImageView is positioned in manned that it is always visible inside the space assigned to the slider, so the bottom slider shows the preview over it, while the upper one shows the preview below it.

Feel free to download the source code from github and send me back your comments, opinion and how to improve it. The code is under the Apache 2 License.
Enhanced by Zemanta

Nov 3, 2010

Catgories in Objective-C

Today I want to give a short example on how to use Categories in Objective-C to extend an existing class.
Let's say that you want to access safely to an array containing 'n' objects, but you don't want every time you access it to check if the index is contained into the array count.

A possible solution is to use a Category to extend the NSArray class.

Create a new project and add to it a new .h and .m files. Let call them NSArray+SafeAccess.h and NSArray+SafeAccess.m.
Inside the NSArray+SafeAccess.h put the declaration of the new Category:

@interface NSArray (SafeAccess) 

- (id)objectSafeAtIndex:(NSUInteger)index;

@end

Then in the NSArray+SafeAccess.m file write the implementation of the new method that will extend the NSArray with the safe access without obtaining a crash for out of bounds access:

@implementation NSArray (SafeAccess)

- (id)objectSafeAtIndex:(NSUInteger)index {
    return (index >= [self count]) ? nil : [self objectAtIndex:index];
}

@end

Later on in your code just import the NSArray+SafeAccess.h and you can use the new safe access method.
Try these lines of code:

#import "NSArray+SafeAccess.h"

...

NSMutableArray *arr = [[NSMutableArray alloc] init];
[arr addObject:@"First"];
[arr addObject:@"Second"];
[arr addObject:@"Third"];

id obj = [arr objectSafeAtIndex:3];
assert(obj == nil);
obj = [arr objectSafeAtIndex:2];
assert(obj == @"Third");
[arr release];

Hope you enjoy with this simple example.
Comments and suggestions are welcome :)

Aug 9, 2010

Ecological Footprint

Dear All,
today I wanna present you the new update v1.1 for Eco Footprint, the iPhone application dedicated to the ecology that allows you to calculate in a simple but effective way your footprint on nature.
The updates are some bug fixing that allow the application to run on the new iOS4 and the adoption of the Apple iAd network.
The application make use of Core Data layer to query and store values on sqlite database.

Below you can se a video of the application that show how to use it to calculate the footprint.



The result can be shared with your friends through your Facebook account.
The application can be downloaded for free at the Apple Store.

Please leave your comments on the application to suggest improvements or changes to make to the app even better and usable.

Thanks for reading :)
Enhanced by Zemanta

Apr 17, 2010

Augmented Reality on iPhone

Hi all, I'm back after a long absence from the blog.
Today I wanna share with you the presentation I made for the University of Bologna on the development of Augmented Reality application for the iPhone 3Gs.

Enjoy the show :)


Reblog this post [with Zemanta]

Jan 16, 2010

Locate your position using GPS

For this test application you need to create a new View-Based Application project (I called it TestLocation).
Once created, open the TestLocationViewController.xib file by double clicking on it. drag over it four labels and a button to make start the update location..
After the editing the result should be like in the following image:




Save the xib file and go to the TestLocationViewController.h and add two IBOutlets to be connected to the empty labels and an action

 - (IBAction)startUpdate:(id)sender 

for the button. These labels will show the latitude and the longitude of your GPS position, while the button will start the location manager. Connect the action to the Touch Up Inside event of the button.

Now comes the location code; in your project right click on the TestLocation target and select the 'Get Info'. In the General tab add the CoreLocation.framework as linked library.

Now come back in the TestLocationViewController.h and add the inclusion of the location framework, the protocol CLLocationManagerDelegate and a member variable that define the location manager (of type CLLocationManager).
I defined the location manager as a property, so it will be instantiated only when needed.

Now switch to the .m file and implement the location protocol delegate methods: didUpdateToLocation (called on success of updating GPS position) and didFailWithError (called if an error occours, for example no GPS signal is present).

Inside the method didUpdateToLocation you have to extract the new position and update the label's text using the following code:

    CLLocationCoordinate2D loc = newLocation.coordinate;
    [lblLatitude setText:[NSString stringWithFormat:@"%f", loc.latitude]];
    [lblLongitude setText:[NSString stringWithFormat:@"%f", loc.longitude]];

then stop updating the location manager:

    [locationManager stopUpdatingLocation];

If you implemented the location manager as property, redefine the accessor method to check if it has been already created, otherwise create it, set the desired accuracy and the delegate as follows:

    locationManager = [[CLLocationManager alloc] init];
    locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    locationManager.delegate = self;

Now you are ready; Press the Build and Go button and when you'll press the button, the location manager will start to update the GPS position. The simulator comes with a fake GPS positions, so you'll be able to see something in the labels.
The complete project can be downloaded from here.

Enjoy and thanks for reading!

Dec 10, 2009

Multi-touch interaction

Today we are going to introduce the multi-touch interaction that will extend the previous application's example.
If you haven't done, download the source code of the last version of the TestTouch application and open it with Xcode.

The multi-touch interaction is disabled by default, so in the TouchView.m file we have to enable it by writing the following piece of code (put it where you want between the keywords "@implementation TouchView" and "@end":

- (void)awakeFromNib {
    [self setMultipleTouchEnabled:YES];
}

The source code you will find into the touchesEnded we wrote last time has to be executed only on single touch, so we have to surround it with the following check code:

if (numFingers == 1) {
    // Put here the old code
    ...
}

The 'numFingers' is an NSUInteger variable initialized at the beginning of the touchesEnded method as follows:

NSUInteger numFingers = [touches count];

As multi-touch behavior let's say we want to scale the red square we have inside the main view using the pinch gesture.
First of all let's define in the TouchView.h file a helper function the we will use to calculate the scale factor:

static inline CGFloat calculateScaleFactor(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
    CGFloat dx1 = line1End.x - line1Start.x;
    CGFloat dy1 = line1End.y - line1Start.y;

    CGFloat dx2 = line2End.x - line2Start.x;
    CGFloat dy2 = line2End.y - line2Start.y;
   
    CGFloat line1Length = sqrt((dx1 * dx1) + (dy1 * dy1));
    CGFloat line2Length = sqrt((dx2 * dx2) + (dy2 * dy2));
   
    CGFloat scaleFactor = line1Length != 0 ? (line2Length / line1Length) : 1.0;
   
    return scaleFactor;
}

The scale factor here is defined as ratio between the lengths of the end and the start lines identifying the distances between the two fingers on the screen.

Then in the TouchView.m we have to insert the code to retrieve the positions of the fingers. This code has to be inserted into the touchesMoved method:

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    if ([touches count] == 2) {
        // Retrieve the two fingers touches:
        NSArray *twoTouches = [touches allObjects];
        UITouch *first = [twoTouches objectAtIndex:0];
        UITouch *second = [twoTouches objectAtIndex:1];
       
        // Retrieve their old positions:
        CGPoint startPoint1 = [first previousLocationInView:self];
        CGPoint startPoint2 = [second previousLocationInView:self];
       
        // Retrieve their actual positions:
        CGPoint endPoint1 = [first locationInView:self];
        CGPoint endPoint2 = [second locationInView:self];
       
        // Calculate the scaling factor:
        CGFloat currentScaleFactor = calculateScaleFactor(startPoint1, startPoint2, endPoint1, endPoint2);
       
        // Apply the tranformation to the red square:
        followerView.transform = CGAffineTransformScale(followerView.transform, currentScaleFactor, currentScaleFactor);
    }
}

Now you can press the button 'Build and Go' and enjoy with scaling the red square through the pinch gesture.
You can substitute the simple red view with the UIImageView and load in it an image or a photo and enjoy scaling the photo.
Here you can find the source code of the project.

Thanks for reading and leave your comments.
Reblog this post [with Zemanta]

Dec 7, 2009

Touch the code

XcodeImage via Wikipedia
In this first article I want to give you some information on how to manage touch events and use them to move an object into the main window.

Open Xcode and create a new window-based application's project. Give it a name (I chose TestTouch).
The wizard will create the application's delegate object positioned into the Classes group.

Now we have to add a view over the main window and create a class associated to it that will receive the touch events and will manage them.

Go to File menu and choose "New File"; from the Cocoa Touch Class choose Object-C class and from the Subclass combo choose UIView, then press Next and give a name to the new class. I named it TouchView.

Now in the TouchView.h add an IBOutlet as follow:

IBOutlet UIView *followerView;

Now go to the TouchView.m file and insert the code that will be used to intercepts the touches and manage them:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
}

Leave empty the touchesBegan and touchesMoved (we will use them in the next lesson). Inside the method touchesEnded we have to put the code to catch the touch position and move consequently the 'followerView' view we defined previously.
First we have to get the touch object:

UITouch *touch = [touches anyObject];

and then extract the position related to the screen:

CGPoint pos = [touch locationInView:self];

and then set the new position to the follower view:

[followerView setCenter:pos];

To complete the exercise we have to open the MainWindow.xib. By double clicking on it the InterfaceBuilder will open.
Add a UIView widget over the Window and in the Identity tab as Class choose the TouchView we created before.

Add another UIView widget over the view just added and make it to be a small square (With = height = 37 for example).
Give the two UIView different background colors (I used black for the main view and red for the small one).
The last step is to connect the IBOutlets we defined into the TouchView with the small red view. Do it from the InterfaceBuilder.
Press "Build and Go" in the Xcode and enjoy with the small square that will follow your touches on the device ;)
You can find here the Xcode project with the source code.

Reblog this post [with Zemanta]