Thursday, August 19, 2010

Create custom activity indicator for your iPhone App



Your Ad Here



Have you ever dreamed of your own custom activity indicator within your iPhone App? The class UIImageView provides a very useful and simple way to implement such a thing. The only thing you have to do is to:
  • Provide a number of images that reflect your indicator animation.
  • Create a new UIImageView instance and set images and animation duration.
  • Position your custom activity indicator within your current view.
To demonstrate the whole process I quickly created some images (I am sure you will style them better than me) which will serve for our animation.

status1status2status3.. I think you got it … status8 createscustom status indicator


So the images are prepared and now we can go to the next step and create the animation of our custom activity indicator somewhere i.e. in your current view controller. The code you need should look like the following.
//Create the first status image and the indicator view
UIImage *statusImage = [UIImage imageNamed:@"status1.png"];
UIImageView *activityImageView = [[UIImageView alloc] 
    initWithImage:statusImage];
 
 
//Add more images which will be used for the animation
activityImageView.animationImages = [NSArray arrayWithObjects:
   [UIImage imageNamed:@"status1.png"],
   [UIImage imageNamed:@"status2.png"],
   [UIImage imageNamed:@"status3.png"],
   [UIImage imageNamed:@"status4.png"],
   [UIImage imageNamed:@"status5.png"],
   [UIImage imageNamed:@"status6.png"],
   [UIImage imageNamed:@"status7.png"],
   [UIImage imageNamed:@"status8.png"],
   nil];
 
 
//Set the duration of the animation (play with it
//until it looks nice for you)
activityImageView.animationDuration = 0.8;
 
 
//Position the activity image view somewhere in 
//the middle of your current view
activityImageView.frame = CGRectMake(
   self.view.frame.size.width/2
    -statusImage.size.width/2, 
   self.view.frame.size.height/2
    -statusImage.size.height/2, 
   statusImage.size.width, 
   statusImage.size.height);
 
//Start the animation
[activityImageView startAnimating];
 
 
//Add your custom activity indicator to your current view
[self.view addSubview:activityImageView];
 
As I mentioned within a code annotation, try to play arround with the duration of the animation so it fits for you. Basically thats all you have to do. For more information look at the documentation of UIImageView. There you will find some more useful methods like stopAnimating or isAnimating and you are also able to add images for an animation if the view is highlighted with the property highlightedAnimationImages.

So far thats all I wanna say and I hope it will help you somehow or other,

Safe, threaded design and inter-thread communication




Your Ad Here


This article republished with permission from CocoaWithLove.com. Copyright Matt Gallagher, all rights reserved.


The Foundation framework provides all the tools you need for inter-thread communication — without needing to handling locks and synchronization yourself. I'll show you Cocoa's tools for inter-thread communication, notifications and easy synchronization — including far simpler code for posting NSNotifications on the main thread than the Cocoa documentation suggests.

Introduction

Multi-threaded code has a reputation for being difficult to write and prone to deadlocks, race conditions and unpredictable behaviors.
While this remains true if you are forced to handle locking yourself, Foundation provides all the tools you require to manage typical multi-threaded situations so that you can avoid the risks of locks entirely.
This post comes from my shock at Apple's suggestion (in their Delivering Notifications To Particular Threads) that something as simple as sending an NSNotification from one thread to another should take dozens of lines of code and a dedicated class for the purpose.
It isn't that difficult. Sending data between threads (including notifications) is a one line job.

Rules for safe simple threading

Simple thread safety in Cocoa requires just two rules:
  1. Every variable or object must nominally belong to a thread (although may be completely handed over to a different thread) and must not be used in multiple threads without handover (unless it is on the list of explicity thread-safe classes).
  2. All communication between threads (after thread startup) should use performSelector:onThread:withObject:waitUntilDone: and both the receiver and the "object" should belong (or be handed over) to the target thread.
The only limitation with this approach is that any thread that receives communication must be running an NSRunLoop. Since communication after construction is normally one-way (from worker thread back to the main thread) this is rarely a significant limitation. Other threads can invoke the [NSRunLoop currentRunLoop]'s runMode:beforeDate to process the run loop and receive messages.
A lot of multi-threaded code does not follow these rules. A lot of multi-threaded code uses a careful system of locks, synchronized sections, volatile variables and atomic operations to allow single objects to be accessed simultaneously from multiple threads. This does work but generally speaking: you don't want to design code this way. It's tricky, confusing and prone to errors. To illustrate, you can have a look at how many changes I had to make to my AudioStreamer code between the first and second versions — rock-solid, manually-locked code is annoying and difficult to write.
Instead, as much as possible, you should write your code to keep all objects compartmentalized to individual threads and to restrict communication between threads to method invocations using performSelector:onThread:withObject:waitUntilDone:. To explain how this works, I'll show a simple example of something running in a separate thread and show how it can perform all its inter-thread communication using existing Foundation methods to automatically handle all thread safety issues.

Scenario: writing to a network NSFileHandle in a worker thread

One of the simplest situations where you may want multithreading is writing to a network socket's NSFileHandle. This is a synchronous operation (blocks until complete) so it is a good idea to perform this in a worker thread so that the main thread of your program can remain responsive.
The following class is an NSOperation subclass. If you don't know about NSOperation, it's an object that you can add to an NSOperationQueue to have the object's main method run in a separate thread (see Apple's Threading Programming Guide). While NSThread's detachNewThreadSelector:toTarget:withObject: is the best way to launch a single worker thread, NSOperations are the best way to run a series threaded tasks (or has been since serious bugs in it were fixed in 10.5.7).
This class' init method takes an NSFileHandle and an NSData object on construction and writes the data to the file handle in its main method.
@interface FileWriteOperation : NSOperation
{
    NSFileHandle *fileHandle;
    NSData *data;
}
@end

@implementation FileWriteOperation

- (id)initWithFileHandle:(NSFileHandle *)aFileHandle data:(NSData *)aData
{
    self = [super init];
    if (self != nil)
    {
        fileHandle = [aFileHandle retain];
        data = [aData retain];
    }
    return self;
}

- (void)main
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    @try
    {
        [fileHandle writeData:data];
        // At this point, the write has succeeded
    }
    @catch (NSException *e)
    {
        // At this point, the write has failed
    }
    @finally
    {
        [pool drain];
    }
}

- (void)dealloc
{
    [fileHandle closeFile];
    [fileHandle release];
    [data release];
    [super dealloc];
}

@end
The NSOperation is created and its thread is launched as follows:
// Assume the operationQueue, fileHandle and fileData already exist
[operationQueue
    addOperation:
        [[[FileWriteOperation alloc]
            initWithFileHandle:fileHandle
            data:fileData]
        autorelease]];
To follow the first rule of thread-safety, after the FileWriteOperation is constructed, the fileHandle value passed into its initWithFileHandle:data: method cannot be used again outside the NSOperationQueue's worker thread.

Communicating success or failure

The above class works but doesn't have any way of communicating the result. What would be good is if we could send a writeFinishedWithSuccess:YES at the "write has succeeded" line and a writeFinishedWithSuccess:NO at the "write has failed" line.
The unsafe way of doing this is to invoke a method on another object sending the result:
[responseHandler writeFinishedWithSuccess:YES]; // BAD!!
If responseHandle belongs to another thread, then this method could cause any number of race conditions and other multi-threading issues.
The solution though is exceptionally simple:
[responseHandler
        performSelectorOnMainThread:@selector(writeFinishedWithSuccess:)
        withObject:[NSNumber numberWithBool:YES]
        waitUntilDone:NO];
This assumes that responseHandler is a nominally "main thread" object. You can use the performSelector:onThread:withObject:waitUntilDone: method and specify a different thread if you need to send the response elsewhere.
You'll notice that the parameter has to be an object in this case ([NSNumber numberWithBool:YES] instead of simply YES) and any parameter that you pass to another thread should not be used again in the current thread.

Delivering Notifications To Particular Threads

Of course, the FileWriteOperation class shown above doesn't have a responseHandle object that it can notify when it is done, so I'd rather use an NSNotification sent to the NSNotificationCenter and if any object wants to receive the notification, it can.
The NSNotificationCenter itself is thread-safe but it delivers the notifications on the thread in which you invoke postNotification: so if you expect the observers of that notification to belong to a different thread, you've just broken those objects' thread safety.
Normally it is a good idea to deliver all notifications on the main thread. We can do this as follows:
// Line of code in some method of some class...
[[self class]
    performSelectorOnMainThread:@selector(postNotification:)
    withObject:
        [NSNotification
            notificationWithName:@"FileWriteOperationSucceeded"
            object:self]];

+ (void)postNotification:(NSNotification *)aNotification
{
    [[NSNotificationCenter defaultCenter] postNofication:aNotification];
}
Notice that we don't call +[NSNotificationCenter defaultCenter] until we're on the main thread. If we call it on the other thread, it will return the notification center for that other thread.
Some classes follow a different behavior of delivering notifications to the thread on which they were constructed (not necessarily the main thread). To follow this behavior, simply save the [NSThread currentThread] on construction and perform the postNotification: selector on that thread.
You may have noticed that the notification is passing "self" from one thread to another — breaking the thread ownership of "self". This is only really safe in one of the following cases:
  • Handover — the parameter will never be used on this thread again.
    In this case, if "self" is complete on the worker thread (for example at the bottom of the main method shown above). In this case, the object is passing itself back to the other thread.
  • Thread-safe — if the class or specific methods are guaranteed to be thread-safe.
    In this case, if the only methods invoked on self are retain, release and the default pointer comparison isEqual: method (these are the methods invoked when removing from an NSMutableArray). These are guaranteed thread-safe methods.
If neither of these are true then you can't pass self (or any other parameter) safely between threads.

Conclusion

The purpose of this article is to communicate two ideas:
  • Carefully locking and synchronizing makes programming hard but if you design your objects to be used on only one thread at a time, then they are thread-safe without the need for locks or synchronzation (if needed, split your objects into components for separate threads).
  • Use inter-thread communication to keep objects in separate threads up-to-date with each other. In Cocoa, this is very simple but you do need to ensure that all parameters you pass are either thread-safe objects or handover objects.
Apple's Delivering Notifications To Particular Threads code is woefully out of date. I would be happy to see it completely changed — you should never need to implement something so complex just to deliver notifications to another thread.
Of couse, there are always situations where you can't run an NSRunLoop to process performSelector:onThread:withObject:waitUntilDone: messages. There are also situations where you feel that one of your object s must be multi-threaded (rather than single thread exclusive). Either of these cases requires will require a synchronized or locked solution but my recommendation is to try to find an NSRunLoop and thread exclusive solution first as these are significantly easier to manage and prone to fewer potential problems.


Adding shadow effects to UITableView using CAGradientLayer




Your Ad Here



Shadows can be a useful effect, drawing attention to the content of your view by separating the view from the background. They also look cool. In this post, I'll show you how to add shadows to a UITableView using three CAGradientLayers — one above the first row, one after the last row and one for under the navigation bar.

ShadowedTableView app

In this post, I'll present the following sample app:
shadowedtableview.png In this screenshot, the rows are dragged downwards to reveal the three different shadows: under the navigation bar, above the first row and under the last row.
Download the sample project ShadowedTableView.zip (26kB). Last updated 2009-08-23.

CAGradientLayer

The CAGradientLayer was a handy addition in iPhone SDK 3.0 — it allows you to create an efficient, linear gradient in just a couple lines. In this sample app, is it used to draw the opaque gradients on the table rows as well as the transparent gradients of the shadows.
While not as flexible as CGContextSetShadow (which can draw shadows around multiple shapes simultaneously or curved edges), CAGradientLayer is very fast, so it shouldn't have a noticeable effect on the speed of your application.
Since CAGradientLayer requires iPhone SDK 3.0, if you need a similar effect on earlier versions of iPhone OS, you'll need to use CGGradientCreateWithColorComponents to draw the contents of a CALayer yourself or perhaps use a UIImageView (an image view is another alternative if you need non-straight edges).

Required steps

Adding the shadows can be done using a UITableView subclass. In this subclass, we need to perform the following steps:
  • Create the three CAGradientLayers
  • Place them and make sure they stay underneath the table's rows
  • Update the positions of the gradients when the table scrolls or grows
We can perform all these steps by overriding the layoutSubviews method.

Constructing the gradients

The construction of the CAGradientLayers is done lazily (i.e. as needed) in layoutSubviews (removing the need to override any constructors.
The three gradients are all constructed using the following method. The inverse parameter is used to generate the smaller gradient that fades-out upwards (for the shadow above the first table row).
- (CAGradientLayer *)shadowAsInverse:(BOOL)inverse
{
    CAGradientLayer *newShadow = [[[CAGradientLayer alloc] init] autorelease];
    CGRect newShadowFrame =
        CGRectMake(0, 0, self.frame.size.width,
            inverse ? SHADOW_INVERSE_HEIGHT : SHADOW_HEIGHT);
    newShadow.frame = newShadowFrame;
    CGColorRef darkColor =
        [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:
            inverse ? (SHADOW_INVERSE_HEIGHT / SHADOW_HEIGHT) * 0.5 : 0.5].CGColor;
    CGColorRef lightColor =
        [self.backgroundColor colorWithAlphaComponent:0.0].CGColor;
    newShadow.colors =
        [NSArray arrayWithObjects:
            (id)(inverse ? lightColor : darkColor),
            (id)(inverse ? darkColor : lightColor),
        nil];
    return newShadow;
}
Notice that the gradient goes from 50% black to 0% of the table's background color. It is important to use the table's actual background color, even though it may seem as though the 0% opacity on it would make it invisible. The mathematics of the gradient will cause the middle color to be 12.5% black + 12.5% background color, so the background color does have an effect on the gradient.

Placing the gradients

The simplest gradient to place is the one under the navigation bar — we just put it at the top of the UITableView.
The only tricky part is that the view, as a child of the UITableView will scroll downwards when the view scrolls (we want it to stay still and not scroll). To fix this issue, we'll offset the view by the same amount as the scroll offset (to keep it in place) and perform this frame adjustment inside a CATransaction with animation disabled (so that these offsets are not visible).
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];

//
// Stretch and place the origin shadow
//
CGRect originShadowFrame = originShadow.frame;
originShadowFrame.size.width = self.frame.size.width;
originShadowFrame.origin.y = self.contentOffset.y;
originShadow.frame = originShadowFrame;

[CATransaction commit];
The gradients on the rows are a little trickier. First, we only want to add them if the rows are visible. Second, we want to make them child layers of their respective rows so that if the rows animate, the shadows will follow them.
Update 2009-08-23: adding the shadows as children of the cells themselves is a new addition to improve performance during animation from the original post (which arranged the rows directly in the UITableView.
NSIndexPath *firstRow = [indexPathsForVisibleRows objectAtIndex:0];
if ([firstRow section] == 0 && [firstRow row] == 0)
{
    UIView *cell = [self cellForRowAtIndexPath:firstRow];
    if (!topShadow)
    {
        topShadow = [[self shadowAsInverse:YES] retain];
        [cell.layer insertSublayer:topShadow atIndex:0];
    }
    else if ([cell.layer.sublayers indexOfObjectIdenticalTo:topShadow] != 0)
    {
        [cell.layer insertSublayer:topShadow atIndex:0];
    }

    CGRect shadowFrame = topShadow.frame;
    shadowFrame.size.width = cell.frame.size.width;
    shadowFrame.origin.y = -SHADOW_INVERSE_HEIGHT;
    topShadow.frame = shadowFrame;
}
else
{
    // Remove the shadow if it isn't visible
    [topShadow removeFromSuperlayer];
    [topShadow release];
    topShadow = nil;
}
This is the placement of the top shadow (the one above the first row). We only attend to it if the first row is visible and when we do, we always ensure that it is the 0-th sublayer of the appropriate cell.

Other tidbits

The sample project also contains the GradientView class which is a very simple subclass of UIView that sets the UIView's layerClass to CAGradientLayer and uses that to draw a gradient across the view. This is the view that is set as the UITableViewCell's backgroundView to draw the views in this sample project.
The project also contains the ClearLabelsCellView which is a UITableViewCell subclass that overrides setSelected:animate: to fix the fact that this method always sets the default textLabel and detailTextLabel backgroundColor to white — instead setting it to clearColor so you can combine the default text labels with non-white cell backgrounds.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    self.textLabel.backgroundColor = [UIColor clearColor];
    self.detailTextLabel.backgroundColor = [UIColor clearColor];
}

Conclusion

Download the sample project ShadowedTableView.zip (26kB). Last updated 2009-08-23.
The ShadowedTableView is self-contained so you can drop it easily into a project.
In its current form, it only works well for full-width, rectangular, contiguous tables — so it works well for "plain" tables but is not suited to "grouped" tables. It also looks best if the table row separator is set to "none".


Synthesizing a touch event on the iPhone



Your Ad Here


Detecting Touches
Before you learn how to detect touches in your application, you first need to acquaint yourself with a few events that handle the detection of touches. You will then be able to know whether the user has single-tapped or double-tapped on your application and react accordingly.
Time to get the engine rolling! Make sure you download the code indicated here so you can work through the following Try It Out activity.
This project [MultiTouch.zip] is available for download at Wrox.com.

Try It Out Detecting for Taps
1. Using Xcode, create a new View-based Application project and name it MultiTouch.
2. Drag and drop an image into the Resources folder. Figure 14-1 shows an image named apple.jpeg located in the Resources folder.
Figure 14-1
3. Double-click the MultiTouchViewController.xib file to edit it in Interface Builder.
4. Populate the View window with the ImageView view. Ensure that the ImageView covers the entire View window.
5. Select the ImageView view and view its Attributes window (see Figure 14-2). Set its Image property to apple.jpeg.
Figure 14-2
6. In the MultiTouchViewController.h file, add the following statements that appear in bold:
#import

@interface MultiTouchViewController : UIViewController {

IBOutlet UIImageView *imageView;

}

@property (nonatomic, retain) UIImageView *imageView; 
@end
7. Back in Interface Builder, Control-click and drag the File’s Owner item to the ImageView view. Select ImageView.
8. In the MultiTouchViewController.m file, add the following statements that appear in bold:
#import "MultiTouchViewController.h"

@implementation MultiTouchViewController

@synthesize imageView; 
//---fired when the user finger(s) touches the screen---
-(void) touchesBegan: (NSSet *) touches withEvent: (UIEvent *) event {

    //---get all touches on the screen---
    NSSet *allTouches = [event allTouches];

    //---compare the number of touches on the screen---
    switch ([allTouches count])
    {
        //---single touch---
        case 1: {
            //---get info of the touch---
            UITouch *touch = [[allTouches allObjects] objectAtIndex:0];

            //---compare the touches---
            switch ([touch tapCount])
            {
                //---single tap---
                case 1: {
                    imageView.contentMode = UIViewContentModeScaleAspectFit;
                } break;

                //---double tap---
                case 2: {
                    imageView.contentMode = UIViewContentModeCenter;
                } break;
            }
        }  break;
    }
- (void)dealloc {
    [imageView release];
    [super dealloc];
}
9. Press Command-R to test the application on the iPhone Simulator.
10. Single-tap the apple icon to enlarge it. Double-tap it to return it to its original size (see Figure 14-3).
Figure 14-3
How It Works
The preceding application works by sensing the user’s touch on the screen of the iPhone or iPod Touch. When the user touches the screen, the View or View Controller fires a series of events that you can handle. There are four such events:
  • touchesBegan:withEvent:
  • touchesEnded:withEvent:
  • touchesMoved:withEvent:
  • touchesCancelled:withEvent:
Take a closer look at the first event. First, the touchesBegan:withEvent: event is fired when at least one touch is sensed on the screen. In this event, you can know how many fingers are on the screen by calling the allTouches method of the UIEvent object (event):
    //---get all touches on the screen---
    NSSet *allTouches = [event allTouches];
The allTouches method returns an NSSet object containing a set of UITouch objects. To know how many fingers are on the screen, simply count the number of UITouch objects in the NSSet object using the count method. In this case, you are (at this moment) interested only in a single touch, therefore you implement only the case for one touch:
    //---compare the number of touches on the screen---
    switch ([allTouches count])
    {
        //---single touch---
        case 1: {
            //---get info of the touch---
            UITouch *touch = [[allTouches allObjects] objectAtIndex:0];

            //---compare the touches---
            switch ([touch tapCount])
            {
                //---single tap---
                case 1: {
                    imageView.contentMode = UIViewContentModeScaleAspectFit;
                } break;

                //---double tap---
                case 2: {
                    imageView.contentMode = UIViewContentModeCenter;
                } break;
            }
        }  break;
    }
You extract details of the first touch by using the allObjects method of the NSSet object to return an NSArray object. You then use the objectAtIndex: method to obtain the first array item.
The UITouch object (touch) contains the tapCount property, which tells you whether the user has single-tapped the screen or performed a double tap (or more). If the use single-tapped the screen, you resize the image to fit the entire ImageView view using the UIViewContentModeScaleAspectFit constant. If it is a double-tap, you restore it to its original size using the UIViewContentModeCenter constant.
The other three events, which are not discussed in this section, are touchesEnded:withEvent:, touchesMoved:withEvent:, and touchesCancelled:withEvent:.
The touchesEnded:withEvent: event is fired when the user’s finger(s) is lifted from the screen. The touchesMoved:withEvent: event is fired continuously when the user’s finger or fingers are touching and moving on the screen. Finally, if the application is interrupted while the user’s finger is on the screen, the touchesCancelled:withEvent: event is fired.
NOTE: In addition to detecting taps in the touchesBegan:withEvent: event, you can detect them in the touchesEnded:withEvent: event. 


Sliding UITextFields around to avoid the keyboard



Your Ad Here


It seems like the iPhone SDK should have given developers a more convenient way to scroll a view when the keyboard covers parts of the screen that should be visible for editing. If you are using a UIScrollView there are some relatively easy techniques to use but what if you are not using a scroll view?  In fact, there is a simple way to do this.
The short answer to the question is: Move (translate) the view the required amount when the keyboard appears and translate it back down when the keyboard is dismissed.
In our case we are using a standard UIView which contains a UITextView.  When the UITextView is selected the keyboard pops up to cover most of the text entry area.  We need to scroll the text entry area to the top of the screen to maximize the amount of text visible for user.
To solve this problem we will implement a delegate method of the UITextView called  textViewDidBeginEditing.  Since the UITextView “return” key doesn’t behave the same way as a UITextField we will also include a “Done” button in a toolbar just above the keyboard to dismiss the keyboard when text entry is complete.  To support the “Done” button we will also create our own “done”method.
xib with additional toolbar for above the keyboard
You’ll notice that the toolbar is sitting midway up the xib and not at the bottom. This was necessary to make it appear at the top of the keyboard rather than at some place under it. After creating the toolbar we set it’s opacity to 0 so that it was not visible until the keyboard appeared.
From here, it is a matter of translating the view and making the toolbar visible when editing then translating the view back and hiding the toolbar when we were done.
MakeUseOf Add Comment View
MakeUseOf Add Comment View with Keyboard
This was done with the following code:
Translate up and unhide the toolbar

self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, -85);
self.toolbar.alpha = 1;
Translate back and hide the toolbar
 
self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, 85);
self.toolbar.alpha = 0;
 
The CGAffineTransformTranslate method was used to translate the view’s transform by 0 pixels in the x-direction and 85 pixels in the y-direction. Translating by a negative value for x or y moves an object left or up respectively, and translating by a positive value moves an object right or down.
But, it’s no good to have the view jump to it’s new location while the keyboard slides up. So, we wrapped everything in some animation with a duration equal to the duration of the keyboard sliding into view. Here is the final code along with a line to release the keyboard when the Done button is tapped.
 

- (void)textViewDidBeginEditing:(UITextView *)textView {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.3];
self.toolbar.alpha = 1;
self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, -85);
[UIView commitAnimations];
}
- (IBAction)done {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:.3];
self.toolbar.alpha = 0;
self.view.transform = CGAffineTransformTranslate(self.view.transform, 0, 85);
[UIView commitAnimations];

[self.userComment resignFirstResponder];
}
 
In practice, you will need to experiment with the location of the  toolbar in the xib and the number of pixels to translate in the  y-direction to move the text you are editing into view.
We’ve glossed over some things such as wiring up the toolbar in the xib so that its opacity will change when we tell it to and so that our “done” method gets called when we tap the Done button. We also don’t have the toolbar moving exactly with the keyboard, but this could easily be done by adjusting it’s position in the xib and translating it up and down along with the view. But, hopefully, what we have shown here helps you out with your own project. If so, let us know in the comments and tell us the name of the app you are working on so we can look for it when it hits the store.

Wednesday, August 18, 2010

Discovering Blender : Applying UV Mapping




Your Ad Here



In this tutorial I will show you how to apply UV mapping, mark seams, export UV layout that will help you in creating your texture.
Open blender, if you don’t have a cube create one (spacebar Add-mesh-Cube)
Start Cube
Toggle to edit mode (Tab) then in edge mode (ctrl + tab + 2)
Edit Edges
We are going to mark seam in order to be able to unfold the mesh without too much distortions, to do that we are going to mark the edge that will represent the cuts. Select the highlighted seven highlighted edges as shown in the image below.(shift + Rightclick) and hit Ctrl + E to bring the Edge Specials Menu and choose mark seam. Once done the selected edge are now orange. If you want to remove a seam choose clear seam from previous menu.
Mark Seams
Now split your screen (see this tutorial) and open an Image editor window.
Image Editor Selection
Then select all the faces by hitting A once (or twice!) (face mode in editmode Ctrl +tab +3) and press U which brings the UV Calculation menu, select Unwrap.
UV Calculation
You should then see something like this in the image editor, if not check if all seams have been marked.
Unwrap result
Now we can rescale and move the vertices. You can use shortcuts in the editor like S (scale), G (Move/Grab), R (Rotate), B (Box selection), falloff selection (O) will work too.
Reloc UV
Now we can export the layout that will serve as a base for our texture. Go to UVs->Scripts->Save UV Face Layout. Define the export resolution and press OK.
Layout Resolution
You should then end with something like this.
Layout Export Result
This will serve you as a template to paint your texture. Once we’ve created our texture in our favorite painting application (Photoshop, Gimp or Paint..) we can apply it to the object. For this tutorial I used an image made by Moony, that you can get HERE which was really well suited for this example. Once rotated scaled and cleaned of useless parts I obtained this:
Color Texture
Now back to Blender Add a material to the object in the material tab (F5) if it doesn’t have one already and add a texture if it doesn’t have one too.
Then go in the Map Input tab and press UV button
Color Texture
In the texture panel (F6) select image type : image and load the newly created texture.
Now toggle the model into edit mode and go back in the Image/UV editor here we will set the previously loaded texture as the active texture for the object.
Set Active Texture
Which should show you something like this
Adjusting UVs
You can tweak the uv here a little more precisely to match every lines. In the 3D port you can switch display mode to display the active texture.
Display Texture Mode
This is one way to apply a texture to an object, there are several others which all have their advantages and limitations. This one is very flexible, you can have variations on every faces of the cube and you can bake ambient occlusion and shadows with this kind of coordinate, the downside is that it waste some texture space and would need a high resolution texture to show details without becoming to blurry, the seams will also need special attention to make them the least visible possible.
The following picture was rendered with baked AO in 1sec 77
Baked  raytrace AO
The next one with raytraced AO in 1 min 9 sec
Raytrace AO
Another method would have been to mark every edge as a seam, unwrap and stack all the faces in the same space (You can rotate them by 90° increment). This would make a much better use of the texture space and solve the seams junction problem. But this kind of UV is not suited for baking shadow or ambient occlusion since all the faces of the mesh refers to the same part of the image.
You can apply several UV Coordinate sets to one object in Blender by clicking the new button next to UV Texture Label.
New UV
And you can use this to achieve several things, like displacement (Displacement Modifier).
Displacement Modifier
the displacement map
Displacement Map
With subdivision and displacement
Displacement render
Next time we will see how to generate a normal map from a high resolution mesh.

Monday, December 14, 2009

iPhone Coding Tutorial – Inserting A UITextField In A UIAlertView




Your Ad Here




Screen shot 2009-11-09 at 8.12.11 AM copyThis will be a simple tutorial showing you how to put a UITextField in a UIAlertView. This is simple and just a couple lines if code. You will learn CGAffineTransform and coding UITextField programmatically.
Heres a screenshots of what we should get.
Screen shot 2009-11-09 at 8.12.11 AM
So lets go ahead and get started…
1. Create A New View Based Application
You can name it whatever you want, I am gonna name it TextFieldInAlert.

2. Implementing The Code
Jump in the viewcontroller.m or if you called it TextFieldInAlert then TextFieldInAlert.m Now find the -(void)viewDidLoad method. Uncomment it and put this code in there.
- (void)viewDidLoad {
[super viewDidLoad];

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Enter Name Here” message:@”this gets covered!”
delegate:self cancelButtonTitle:@”Dismiss” otherButtonTitles:@”OK!”, nil];
UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
[myTextField setBackgroundColor:[UIColor whiteColor]];
[alert addSubview:myTextField];
[alert show];
[alert release];
[myTextField release];

}
So we are basically calling a UIAlertView and then we are adding the UITextField programmatically. You might have noticed in the message part of the UIAlertView we put “this gets covered!”, if we didn’t put that sentence then the alerts buttons would go up more and the UITextField will be messed. You can try taking that line out and see what happens. Now Build and Run the app. Now you got the UITextField to be inside the UIAlertView. Now try tapping the UITextField. Uh oh, why is the Keyboard covering the UIAlertView? Well there is just a simple fix to this. We just add two more lines of code and it will fix that. Add this to your code
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alert setTransform:myTransform];
So now your full code should be looking like this.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@”Enter Name Here” message:@”this gets covered!” delegate:self cancelButtonTitle:@”Dismiss” otherButtonTitles:@”OK!”, nil];
UITextField *myTextField = [[UITextField alloc] initWithFrame:CGRectMake(12, 45, 260, 25)];
CGAffineTransform myTransform = CGAffineTransformMakeTranslation(0, 60);
[alert setTransform:myTransform];
[myTextField setBackgroundColor:[UIColor whiteColor]];
[alert addSubview:myTextField];
[alert show];
[alert release];
[myTextField release];
Now if you Build and Run, you will notice the UITextField is a little higher and when you tap the UITextField the Keyboard doesn’t cover it up anymore. That is what the CGAffineTransform was for. So that is basically it! There is a video tutorial also available and if you like video tutorial more then written ones you can check it out out by clicking HERE. You can download the source code below. Happy iCoding!
iPhone Tutorial – UITextField In A UIAlertView

 
Submit Express Inc.Search Engine Optimization Services