Tag: kranthi

IP address-independent access to Mac virtual hosts from Parallels virtual machines

Like many other Mac-using web developers I use Parallels Desktop for testing in various versions of Internet Explorer. It works well, including accessing local development sites set up as virtual hosts in Apache on my Mac.

One thing that’s been bothering me for a long time, though, was that whenever my Mac got a new IP address I had to open the hosts file in all my virtual machines and enter that address to access my sites. Pretty tedious. Well, I recently found out that this can be avoided. In case there are others who didn’t know this and wasted their time editing hosts files, here’s how.

Read full post

Posted in , .

Copyright © Roger Johansson


A Guide To iOS SDK For Web Designers // App development


  

As a designer looking to broaden your skill set, you’ve decided that learning to make native apps for Apple’s iOS platform is an attractive and potentially lucrative prospect. With a frisson of excitement, you start to do some research. The euphoria is short-lived however, as you quickly discover that unless you are an experienced programmer, the task is far from easy.

The documentation provided by Apple is aimed at those with a degree in computer science. Books on iOS development ask that you have a good grasp of Objective-C from the opening page. Online tutorials vary in quality, with many appearing out of date or contradictory.

This post will help you get to know the iOS SDK a little better. It leads you through some choreographed steps of iOS app development, even if you have little or no programming knowledge. It covers some key principles and applies these directly to something useful and relevant: the creation of a simple but functioning portfolio app for the iPhone.

The result will look like this:

iOS Portfolio App

Going Native?

By “native� iOS development, we mean using Apple’s software development kit (SDK) and the programming language Objective-C to author apps for the iPhone, iPod Touch and iPad. Before we learn how to do this, it is worth mentioning why we would want to make an app this way, and what the alternatives might be.

In relaxing the App Store’s submission review guidelines in September 2010, Apple made it easier for developers to use third-party frameworks and more familiar languages, such as HTML, CSS and JavaScript, to create apps. Examples of such tools are Appcelerator’s Titanium Mobile, Nitobi’s PhoneGap (acquired by Adobe in 2011) and appMobi’s XDK, among others. In addition to the benefit of using the more familiar Web languages of HTML, CSS and JavaScript to author apps, these methods enable developers to output to other mobile platforms, such as Android and BlackBerry, with minimal rewriting of the source code.

The disadvantage of using third-party tools is that the resulting app will not be quite as efficient as one that is natively authored, and the newest features of the operating system and hardware will not be available, at least until the framework catches up. Each framework also has its own fairly extensive library of functions that have to be learned, along with its own idiosyncrasies, bugs and workarounds. Plus, to publish your app to the App Store, you need to use Apple’s Xcode, the application used to work with the iOS SDK, so limited familiarity with native processes is still necessary.

A few “third way� solutions, such as Cocos 2D for iPhone and PugPig, are also available, allowing you to connect framework files to an Objective-C project for a particular aim, such as to create a game or magazine app. To make use of these and any others that come along in future, you will need a basic understanding of the SDK.

Therefore, if you are interested in developing for the iPhone, iPod and iPad and you accept that whatever authoring method you choose means having to find your way around Xcode, then getting to grips with the native SDK is a recommended first step.

Getting Started

You will need two things to be able to start working with the iOS SDK:

  • A Mac, running the latest version of OS X (there is currently no way to author natively for iOS on Windows or Linux, although apparently there is a workaround);
  • Apple’s Xcode application.

To get Xcode, download it from the Mac App Store. It’s free but weighs in at nearly 1.5 GB and can take about half an hour to install, so you’ll need to put aside a bit of time to get it up and running.

Preparing Graphics

While waiting for that download to complete, we can look at how you might prepare and export graphics for iOS using Photoshop.

Because all iOS applications have one of two possible pixel densities (standard or Retina), you should aim to work in Photoshop using non-destructive techniques to reduce the need to design twice. This means creating buttons and interface elements using vector shapes and layer styles, and using smart objects for images, where possible. The recommended approach is to work at a Retina-display resolution first, and then scale down to standard resolution once the design is complete. Sometimes you will find that scaling down produces poor results, and you will have to tweak your smaller designs.

Plenty of templates with pre-built iOS system elements are available on the Web. Teehan + Lax has one that is pretty good and widely used. Apart from saving you from having to draw iOS system components from scratch, they also demonstrate how much space is left for content, once elements such as the status, navigation and tool bars are in place.

To set up a new blank iPhone document in an image editor, these are the settings you will need:

  • 640 × 960 pixels,
  • 72 DPI,
  • RGB color mode.

The above is for a Retina display (iPhone 4+ and iPod Touch fourth generation and up). Older devices are 320 × 480 pixels, exactly half the size!

See Marc Edwards’ “Designing for iPhone 4 Retina Display� for more information on iOS design techniques and workflows.

Some Quick Image Exporting Tips

  • iOS accepts a number of image formats, but PNG is recommended because of its support for alpha-transparency and its lossless compression.
  • Graphics for buttons should, in most cases, be exported just as background images, without accompanying text, because this allows for localization (in different languages), accessibility and text resizing between the Retina- and standard-display resolutions.
  • If exporting a button graphic, ensure that the pixels of the actual button are centered in the frame of the exported image, because Interface Builder doesn’t give you precise control over the positioning of button background images or foreground text. You might need to manually compensate for a drop shadow on the opposite sides, for instance.
  • Where possible, flatten design elements made from multiple layers into a single image file. Rebuilding layered UI components in Interface Builder can be a pain; plus, reducing the number of resources that your app uses will make it run quicker and take up less memory. Only interface components that need to respond to user interaction should be animated, and only interface components that will be controlled by the application should be exported as separate image files.
  • You will need to produce Retina and standard versions of every exported image and give them identical names, with a @2x suffix for the Retina version, like so:

    • image.png
    • image@2x.png
  • You can use my SuperSlicr Photoshop action (included in the package) to automate the scaling and exporting of elements from your PSD file.
  • Every pair of images that you make will need a unique and descriptive file name, because they are all stored in the same directory in the app bundle. File names should have only alphanumeric characters (no symbols), and underscores or hyphens instead of spaces. You may use capitalization.
  • Photoshop isn’t very good at compressing PNGs, so run them through porneL’s ImageOptim to reduce their size before importing into Xcode. Xcode will also try to apply its own compression to imported images, which can sometimes increase file size, but this can be disabled.

Xcode Overview

You’ve successfully installed Xcode? Great!

Next, you will need to download and unzip these template files. The package includes a source PSD, some exported PNGs and the required starter code.

In the package, navigate to the folder named Begin Here. Locate the Xcode project document named Portfolio.xcodeproj. Double-click on this file to open it in Xcode.

Once the document has loaded, click on the blue project icon on the left named Portfolio, 1 target, iOS SDK, and you should see a project summary screen in the main Xcode interface, as shown below. We will look at the contents of the summary screen in detail later.

Xcode Overview

The “Navigator� area on the left lists all of the files already associated with your project. These can be expanded out from the blue project icon. We will be mostly interested in those contained in the yellow Portfolio folder, or “group.� Three types of files are here:

  • .h
    A “header� (or interface) file.
  • .m
    A “message� (or implementation) file.
  • .xib
    An “XML interface builder� file, sometimes referred to as a NIB.

The “Editor� area will change depending on what task you are performing. Because we currently have the blue project file selected in the navigator, we are given the “Target Summary� screen. This gives us some basic options for our app, including which device types, iOS version and display orientation we want our app to support. We can also specify images to use for our app’s icon and launch image, which we will look at in detail later.

Single-click on TestAppDelegate.m. The editor area will now turn into a code editor and display the code contained in this file.

Now single-click on MainWindow.xib in the navigator area. The editor area will display Interface Builder, an integrated graphical user interface (GUI) for putting together the front-end of your application.

Interface Builder Overview

The “Inspector� has some tabbed controls at the top that you will need to be familiar with. The last four are the most important:

Inspector Bar

The other important control is the big “Run� button in the top-left corner of Xcode. Pressing this will compile your project code into an app and then run it in an iOS simulator so that you can see whether it works without having to load it onto an actual device. If you press it now, it should launch the simulator and present you with a big virtual iPhone on your desktop.

The iOS Simulator

The simulator works similar to an actual device. Have a play to see how it behaves. Under the “Hardware� menu, you can select different devices and iOS versions and simulate rotating and shaking the device. Holding alt allows you to pinch and zoom. The home button works, taking you to the springboard where there is even a functioning version of mobile Safari (which, incidentally, is great for testing locally hosted websites).

A more detailed guide to the interface is available in Apple’s “Xcode 4 User Guide.�

Importing Graphics Into Xcode

The template package that you downloaded earlier contains some sample image files. You can either use these or use your own for the next section.

To import images into your project, Control-click on the “Images� group in the project navigator and select “Add Files to ‘Portfolio.’�

Adding Images

Browse to the “PNGs� folder in the downloaded package and select all of the images. Check the “Copy items into destination group’s folder� box, and then click “Add.�

The images have now been imported into your project and are available to Xcode and Interface Builder. You can add more graphics to the “Images� group at any time by following this same process.

Editing The Template Without Writing Any Code

There is a debate in the iOS development community about whether one should build an app purely in code or with XIB files generated by Interface Builder and its GUI. Both methods seem to be supported by Apple, and each project necessitates its own approach. Developers who frown on the use of Interface Builder perhaps overlook the power of this tool, which enables us to establish the structure and outward appearance of our app efficiently and visually. For designers used to working with Adobe’s Creative Suite, this will be (almost) familiar territory. For this reason and because our app will be very “view-based,� we will use Interface Builder to begin with.

First, we will look at setting up some different screens, or “views,� that can be switched using some Tab Bar controls. Click on MainWindow.xib in the project navigator to bring up Interface Builder. In the library, select the “Show the Object Library� tab icon (the one that looks like a cube), and scroll through the list of objects until you find “View Controller.�

View Controller Object

Expand the dock using the circular “Expand document outline� button at the bottom, then drag an instance of the View Controller object from the library onto the “Tab Bar Controller� in the dock. The Tab Bar Controller should expand, showing the View Controller nested inside.

Repeat this process twice more, until you have three View Controllers nested inside the Tab Bar Controller. The canvas area should also show the Tab Bar as having three unnamed tabs.

View Controllers Added To Tab Bar

View Controllers?

If you are wondering what a “View� and a “Controller� are, they are part of something called the “Model View Controller� (MVC) paradigm. This is an approach to programming that separates application data, logic and presentation to make things easier to work with. “Model� refers to the back-end aspect that manages data. “View� refers to the front-end user interface. “Controllers� bridge the front and back ends and enable things to happen in your app. We won’t be working with any stored data in this article, so we will only be encountering Views and their corresponding Controllers.

Creating Classes

We need to create some “classes� to generate each of our views; and because we are new to programming, this requires a bit of explanation first.

In object-oriented programming languages such as Objective-C, classes are used as a way to define elements within the application called “objects.� A class defines the qualities (or properties) that an object may have and what it can do (methods). It can then be asked to generate one or more “instances� of an object based on this definition, and these instances are used to make your application work.

Each of the three views that we want to make are objects, so we need to create some classes to be able to conjure them into existence.

To add a new View Controller class, Control-click on the yellow “Portfolio� folder in the navigator, and select “New File� from the contextual menu. In the sidebar of the options sheet that follows, select “Cocoa Touch,� then “Objective-C class.�

New Objective-C Class

Click “Next.� Then, in the sheet that follows, enter “HomeViewController� in the “Class� field, select “UIViewController� in the “Subclass of� drop-down menu, and ensure that the “With XIB for user interface� box is checked.

Naming New View Controller

Clicking “Next� will give you a save dialogue box. Select the “Begin Here > Portfolio� folder, and then hit “Create.�

Repeat this process for the other two views, naming each class “PortfolioViewController� and “ContactViewController,� respectively.

You can rearrange the order of the files in the navigator by dragging and dropping if you want. It should now look something like this:

View Controllers Added To Project Navigator

Configuring Tabs and Views

Return to MainWindow.xib. Select the first View Controller icon in the dock, then the Identity inspector. Select “HomeViewController� from the “Class� drop-down menu.

Connecting HomeViewController Class

Now go to the Attributes inspector. Type “Home� in the “Title� field, and select “HomeViewController� as the NIB name.

Connecting HomeViewController XIB

Expand the View Controller in the dock and select its “Tab Bar Item.� In the Attributes inspector, set the title as “Home,� and select tab-icon-home.png from the Image drop-down menu. You don’t need to specify the @2x Retina version when selecting images in Xcode because they are called automatically when the application is running.

Customizing Tab Name And Icon

Repeat the above process for the Portfolio and Contact views, choosing the relevant classes, titles and image files.

The color of the tab bar highlight can be changed by selecting the main “Tab Bar� object in the dock, then “Image Tint� in the Attributes inspector. Although custom tints will only show up in devices running iOS 5 or higher, iOS 4 and below will safely fall back to showing the default blue highlight color.

Our views within tabs are now all set up! To check that they are working properly, we’ll need to add some dummy content to each view.

Select HomeViewController.xib in the navigator, then drag a “Label� from the library (at the top of the list) onto the view represented in the canvas. Double-clicking on the label in the canvas will allow you to edit its text. Change it to “Home.�

Adding A Label To The Home View

Repeat this for PortfolioViewController.xib and ContactViewController.xib, naming the labels appropriately.

Now hit the “Run� button, and check out your already functioning tabbed app in the simulator!

App Test With Labels

Adding Graphics And Text To The Views

As with desktop publishing applications, inserting images and text in Interface Builder requires you to make a containing element first. These can be dragged onto the canvas from the library, and they are called “Image View� and “Text View,� respectively. They can be repositioned and resized visually with the cursor, or you can type pixel measurements into the Size inspector for more precise control.

The Attributes inspector allows us to specify an image to place in the Image view. We may only choose from images that have been imported into the project.

The Attributes inspector also lets us set text for the Text view, and it gives us typography controls, a background color-picker and scrollbar options.

Arrange the graphics for HomeViewController.xib. Delete the label, and drag on an Image view from the library, setting its image’s name to home-bg.png and its mode to “Top Left� using the Attributes inspector.

Attributes Inspector Select Image

In the Size inspector, check that the Image view has an X value of 0, a Y value of -20, a width of 320 and a height of 480.

The Size Inspector

Next, position a Text view over top. Editing its content, center-align the text, set the text’s color to white, set a custom font (Snell Roundhand, Regular, 24 pixels), and set the background color to “Clear.�

Attributes Inspector Text View Controls

The result should look like this:

Adding Graphics To Home

Because our views are being placed inside a tab bar interface, we also need to simulate the black strip at the bottom of each view so that we can arrange items with this in mind. To do this, select the main “View� object in the dock. Then, in the Attribute inspector, under “Simulated Metrics,� choose “Tab Bar� from the “Bottom Bar� drop-down menu:

Simulated Metrics

This won’t actually add a tab bar to our view. It simply provides a visual reference to help us position the layout.

Now, have a go at arranging the graphics and text for the Portfolio and Contact views. Either use the sample images at the top of this article, or refer to the source PSD provided in the template package.

When creating the thumbnail images in the Portfolio view and the social media buttons in the Contact view, use the “Round Rect Buttons� from the library instead of Image views. If you set the button type to “Custom� in the Attributes inspector, you can then set the button’s image in the same way as you would for an Image view. Set the button size in the Size inspector based on the image’s original dimensions. Using a “Round Rect Button� instead of an Image view allows us to add interactivity to them later.

Now, build and run to check that everything works OK in the simulator.

Extra Finesse

If you press the simulator’s home button, you will notice that your app has an uninspiring white icon on the springboard and a blank screen when it relaunches. Let’s fix that now.

Clicking on the blue “Portfolio� project icon in the navigator will take you back to the summary screen. Scrolling to the bottom of this screen will reveal empty wells awaiting custom images. Adding images is simply a case of dragging them from the Finder to the relevant well.

App Icon And Launch Image Wells

You will find the images you need for this project in the “App Icons� directory in the downloaded package.

If you want to make your own app icon, the images need to conform to the following sizes:

  • Standard: 57 × 57 pixels,
  • Retina: 114 × 114 pixels.

The launch images need to be the same as the display’s overall dimensions:

  • Standard: 480 × 320 pixels,
  • Retina: 960 × 640 pixels.

You will at a later date need some more sizes to display your app correctly in various contexts. An excellent resource detailing the required sizes has been produced by Neven Mrgan. Apple’s “iOS Human Interface Guidelines� also give a good breakdown and include icon and launch image sizes for the new iPad.

iOS automatically rounds the corners of your app’s icon and overlays the standard glossy sheen on it, too, so you don’t need to include these elements in your design.

If, however, you want to create your own non-standard glossy effect or you don’t want gloss on your icon at all, then check the “Prerendered� box to the right of the App Icon wells.

Icon Prerendered Example

To change the name that appears below the icon, select the “Info� tab next to the “Summary� tab at the top of the editor. This will reveal an editor for the app’s .plist (property list) file, which is an XML document containing the main settings for your app:

App Info Plist

Some of the information here, such as “Main nib file base name,� points to resources required by the app when it first launches. Other information, such as “Bundle Identifier,� is used in the black art of provisioning and uploading to iTunes Connect for distribution on the App Store.

To change the name below the icon, change the “Bundle display name� value from ${PRODUCT_NAME} to whatever you want.

The Minor Miracles Of The Xcode Assistant Editor

When we test our app, the custom buttons will respond to being tapped but won’t actually do anything. To make them work, we’ll need to write some code. Luckily, something called the Assistant Editor can help us with the first part of this process.

Select ContactViewController.xib from the navigator. Then, press the “Assistant Editor“ button in the top right of the Xcode window.

Assistant Editor Toggle

This will display an Interface Builder window detailing ContactViewController.xib, alongside a Code Editor window, which shows the associated ContactViewController.h interface document. In the example below, the dock has been minimized, and the Utility area hidden to give the two editors more room. The Code Editor is also using the “Duskâ€� theme, which can be found under “Fonts and Colorsâ€� in Xcode → Preferences.

The Assistant Editor In Action

Miracle 1: Declaring Properties and Methods

Features of a class generally fall into two main types: a “property,� which is a characteristic that the class might possess, and a “method,� which is something that it can do. When adding a button to ContactViewController, we need to declare the button as a property of the class and create a method for what happens when the button is tapped by the user.

The .h document should contain the following code:

#import <UIKit/UIKit.h>
@interface ContactViewController : UIViewController
@end

The #import statement at the top gives the class access to the required iOS user interface classes stored within the UIKit framework.

The @interface declaration starts by defining ContactViewController and stating that it is a subclass (meaning that it inherits all the features) of the UIViewController class, which is defined within UIKit.

We can add in extra items between the opening @interface declaration and its @end, to build on the foundation provided by the UIViewController class.

To do this, Control-click on our orange “WWW� button on the canvas in Interface Builder, drag the cursor to be just above @end in the code editor, and then release. A little dialogue box will pop up with some settings:

Outlet Dialogue

Check that the “Connection� is set to “Outlet,� type in the name websiteButton, and then press “Connect.� Xcode will insert a line of code into the .h document for you.

Repeat the process, this time changing “Connection� to “Action� and providing the name openWebsite.

Action Dialogue

The code in your .h document should now look like this:

#import <UIKit/UIKit.h>
@interface ContactViewController : UIViewController
@property (retain, nonatomic) IBOutlet UIButton *websiteButton;
- (IBAction) openWebsite:(id)sender;
@end

So, what does this all mean?

The @property declaration states that the ContactViewController class has a property. It begins with some parameters: retain, which has to do with memory management (more on this later), and nonatomic, which means that it is not “multithreaded,� something that is common to all iOS properties. Next, there is a definition for the property return type, IBOutlet, which allows us to bind our code to the button we created in Interface Builder. UIButton states that the property will inherit from the UIButton class, defined within UIKit, and then the name of our property is given, which is websiteButton.

The second line of code is a method declaration. It starts by saying that it is an IBAction, which again lets us bind the code to the button object in the XIB. Then it is given a name, in this case, openWebsite. The (id)sender parameter tells us which object called the method. This is handy in certain situations, although we don’t need it right now.

You might have noticed that when we created our View Controller classes, their names began with an uppercase letter, whereas the names we gave our property and method didn’t. This is an Objective-C naming convention and should be adhered to.

Hand-coding those two lines is possible, but using the Assistant Editor to do it saves a bit of time and ensures that the syntax is correct. It also performs a whole series of other tasks for us as well. Let’s look at what else it does.

Miracle 2: Property Synthesis and Memory Management

Return to “Standard Editor� mode, and select ContactViewController.m. Around line 12, you should see this directive that the assistant has put in for us:

@synthesize websiteButton;

This will ask the compiler to “synthesize� some extra methods for us when the app is built, for setting and getting variables for our property. This all happens behind the scenes and saves us from having to deal with even more code, so it really is useful.

Lower down, we find the following:

- (IBAction)openWebsite:(id)sender {
}

This is the method implementation for our button action. In a minute, we will put some code in there to make our button work.

You should also find another method implementation that looks like this:

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

This method has to do with memory management and is defined within the Cocoa framework, which is why we haven’t needed to mention it in our interface.

Managing memory is very important when programming because a mobile device doesn’t have much to play with. When the websiteButton property is defined, a chunk of memory is allocated to it using the retain command. This command asks iOS to reserve a bit of memory for the button until we tell it to let it go. The dealloc method is activated only when the View instance is destroyed; so, by putting websiteButton release in there, we are asking iOS to free up the memory set aside for the button when this event occurs. If we don’t do this, then the memory keeps getting allocated, even when the button object isn’t in use anymore. This is called a “memory leak.� If left unchecked, these leaks will add up, affecting the app’s responsiveness and the device’s battery life and causing all sorts of other horrors!

Thankfully, once again, the assistant editor has set this all up for us, so we don’t need to remember to do it. Hooray!

It is probably worth mentioning that version 5 of the iOS SDK comes with “Automatic Reference Counting� (ARC), which seeks to further automate memory management for iOS developers. When creating a new project, you have the option to turn ARC on and off. We are not using ARC in this project, so we can learn a bit about how memory management works. Integrating freely available components found on the Internet (many of which are written using manual reference counting) with an ARC-enabled project can also be difficult. With each subsequent release of the SDK, however, Apple is pushing more and more for developers to embrace ARC, and there are many advantages in doing so. ManiacDev has compiled some useful resources to make this transition smoother.

Miracle 3: Code Binding

The Assistant Editor has also connected our code to the button object in the XIB. Select ContactViewController.xib, expand the dock, and under “Placeholders� select “File’s Owner.� This represents the ContactViewController class. Now, select the Connections inspector. It should look like this:

Connections Inspector

Under “Outlets,� we can see the websiteButton property linked to the Button XIB object.

Under “Received Actions,� we can see that the openWebsite method is also connected to the Button.

Under it, there is also an associated event, “Touch Up Inside.� This means that the method will be called when the user touches and then releases their finger while still inside the button. This is the default touch event.

Handwriting Your First Bit Of Objective-C

Lets make that button do something!

Change the openWebsite method implementation in ContactViewController.m so that it looks like the following:

- (IBAction)openWebsite:(id)sender {
NSURL *webAddress = [NSURL URLWithString:@"http:www.mightymeta.co.uk"];
[[UIApplication sharedApplication] openURL:webAddress];
}

The syntax for a method is fairly straightforward. Simply provide the name of the method, and then put what you want to happen when the method is called between the pair of curly braces.

In this case, we are doing two things. First, we are creating a temporary variable named webAddress and assigning it a string of text that contains our email URL.

It is worth noting that this is something called a “convenience method.� It creates an instance of the NSURL class and automatically allocates some memory to it. It also sorts out the memory deallocation for you, so you don’t have to worry about releasing the webAddress variable.

The second line asks the OS to open the URL in a relevant application, which in this case would be the default Web browser.

Build and run to test whether it works.

To make the other buttons work, simply repeat the steps that we went through to create this button. Any mailto: URLs will work and will launch the default mail client. To make a phone call, put tel:, followed by the number you want to dial in place of the URL. You can change the name of the temporary variable to suit the purpose for each button.

Making a View Appear Modally

The portfolio section currently has some thumbnail images. Wouldn’t it be great if the user could tap on these to get bigger versions?

This can be achieved by creating what is called a “Modal View.� This is essentially a new view that is placed over top the previous one, and it comes with a range of animated transitions into view.

Create the Modal View

Modals are easy to create. First, generate a new class called BigImageViewController (Control-click on the “Test� folder in the project navigator, select “New File� and then the UIViewController subclass).

Open the corresponding XIB in Interface Builder, add an Image view that fills the entire view, and set its image as portfolio-modal-bg.png. Add a custom Round Rect button, give it a background of button-close.png, set the color of the “Close� title to white, and place it in the top-left corner.

Next, place another image view over top the first. Fit it to near the edges of the paper background, but don’t assign an image to it:

Creating A Modal View

Use the Assistant Editor to declare the empty Image view as an outlet named imageFrame, and connect the button to an action named closeView in BigImageViewController.h (you can select which file the right-hand window will display from the bar at its top):

@property (retain, nonatomic) IBOutlet UIImageView *imageFrame;
- (IBAction)closeView:(id)sender;

Then type the following into the closeView method in BigImageViewController.m:

- (IBAction)closeView:(id)sender {
[self dismissModalViewControllerAnimated:YES];
}

This code will close the modal view when the button is tapped.

Code for Launching the Modal

Now, using the Standard Editor, type in PortfolioViewController.h so that it looks like the following example:

#import <UIKit/UIKit.h>
#import "BigImageViewController.h"
@interface PortfolioViewController : UIViewController
@property (nonatomic, retain) UIImage *bigImage;
- (IBAction) selectImage1;
- (void) openBigImageView;
@end

Make sure to include the #import statement for the BigImageViewController header file. This is required so that we can send a message to this class and ask it to create an instance of itself.

A property and two method declarations are there. The second, openBigImage, doesn’t need to be connected to any objects in the XIB; so, it has a return type of (void), meaning… well, a big black hole of nothingness.

We haven’t used the Assistant Editor here because we are doing something a little different from before. Because of this, we need to manually synthesize and release the bigImage property at the start of PortfolioView.m, like so:

@implementation PortfolioViewController
@synthesize bigImage;
- (void) dealloc {
[bigImage release];
[super dealloc];
}

Underneath the dealloc method, implement the two methods that we declared in the header:

- (IBAction) selectImage1 {
self.bigImage = [UIImage imageNamed: @"image1-big.png"];
[self openBigImageView];
}
- (void) openBigImageView {
BigImageViewController *bigImageView = [[[BigImageViewController alloc] initWithNibName:@BigImageViewController bundle:nil] autorelease];
bigImageView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:bigImageView animated:YES];
[bigImageView.imageFrame setImage:bigImage];
}

Wow, that’s a lot to take in. Lets go through it.

The selectImage1 method sets the bigImage property to the image file that we want to use, and then calls the openBigImageView method.

The openBigImageView creates an instance of the BigImageViewController class named bigImageView, presents it as a modal using the “flip� transition style, and then sends its imageFrame the image file held by the bigImage property.

Because we have manually allocated memory to the instance of BigImageViewController, we need to release it at some point, but we don’t know how long the object will be needed for because it depends on how long the user keeps the modal active. The autorelease command helps us with this problem because it asks iOS to hold on to the memory for a bit and then release it later on, when it is deemed safe to do so.

Manual Code Binding

Now we need to connect our code to the objects in the XIB. Select PortfolioViewController.xib, and then the “File’s Owner� object in the dock, and then the Connections inspector.

Under “Received Actions,� you will find the selectImage1 method, and an empty circle to the right of it. Click and drag a connection from this circle over to the relevant thumbnail button:

Binding A Button To Code Manually

Select “Touch Up Inside� from the list of button events that appears.

Build and run to see whether it works. If everything is in place, you should be able to tap the thumbnail to reveal the bigger image.

See if you can work out how to do the same for the other images on the portfolio page. You will need to create selectImage2, selectImage3 and selectImage4 methods, but you won’t need another openBigImage. You could also try using different transition styles; you have four to choose from:

  • UIModalTransitionStyleCoverVertical
  • UIModalTransitionStyleCrossDissolve
  • UIModalTransitionStyleFlipHorizontal
  • UIModalTransitionStylePartialCurl

If you get really stuck, have a look at the completed project in the “End Result� folder of your downloaded template package.

In Conclusion

We’ve covered quite a lot of ground, having looked at the basics of the Xcode interface and how to arrange visual elements in Interface Builder. We’ve also been introduced to the key concepts of classes, properties, methods and memory management in Objective-C.

In the process, we have built a functioning, albeit limited, app. Making it ready for submission to the App Store would require a unique design and some additional functionality, such as adding Tweets to that empty speech bubble on the home page. Now that you have a grasp of the basics, take advantage of the great resources out there to help you with this next step.

Further Reading And Resources

App Design

App Development

  • “Learn Objective-C,â€� Cocoa Dev Central
    A summary of the basics of Objective-C.
  • Cocoa Controls
    Open-source UI components, such as carousels, maps and Twitter aggregators, to integrate in your project.
  • ManiacDev.com
    iOS libraries, controls, tutorials, examples and tools, many of which are open source.
  • Baker Ebook Framework and PugPig
    These enable you to build an interactive book or magazine using HTML5 and then wrap it into an app using Xcode.
  • Creator, GameSalad
    Want to make a promotional iPhone game using drag-and-drop behaviors and your new-found Xcode skills? Then GameSalad’s Creator is for you.

(al)


© James Brocklehurst for Smashing Magazine, 2012.


Batch Resizing Using Command Line and ImageMagick // Free Bash Script


  

If you deal with images, sooner or later you will want to automate the repeating process of saving different sizes from one source image. If you own Adobe Photoshop and do not save too many output sizes, Photoshop actions are probably quite enough for your needs. However, keeping a Photoshop action up-to-date is quite painful — change a source folder, and you’re screwed.

As you probably noticed in Smashing Magazine’s monthly desktop wallpaper series, especially if you work on wallpapers, preparing them for a plethora of desktop resolutions is quite a task. On my own wallpapers website (Vladstudio), I generate more than 300 JPEG files for each wallpaper! I want my art to reach as many devices as possible, which means I need to publish my wallpapers in as many sizes as I can support. On the other hand, I do not want to spend the rest of my life resizing my artworks — I’d rather draw new ones!

Long ago, I used Photoshop actions to save multiple sizes from a source file, but it quickly became a nightmare to maintain. Photoshop provides a more powerful tool — scripting language (it’s not the same as “actions”, though the concept is similar). When writing a script, you use a programming language to tell Photoshop what to do (compared to actions, where Photoshop records what you do with mouse and keyboard). However, it’s not easy to learn at all, and I also wanted to completely remove Photoshop from process.

The solution I found is ImageMagick — a command-line image manipulation program, available for Windows, Mac and Linux. Unless you are a server administrator, you probably never thought of resizing images using command line. However, after switching to command line, I never looked back at Photoshop for batch resizing.

Using command line is:

  • Easy to expand — adding new sizes takes only one line of code.
  • Easy to maintain — changing folders is as easy as changing one variable.
  • Portable — I can save images on my server as well as my main computer.

Terminal in Python
The bash script in use in Terminal. Large view.

If you have never worked with command line before, it all might look scary at first. However, with a bit of patience, you will find that it’s actually a very powerful tool.

Below is the bash script I wrote, simplified for more universal usage. It takes the following parameters (from either you or from default values):

  • Set of output sizes.
  • Source file.
  • Destination path (path must include the % symbol, which will be replaced by output size, i.e. “800×600”).
  • Optional signature image.

Batch Resize Script
The result after the script was applied. Large view.

Then it resizes source image into every output size, applying a signature. For a better understanding, please look through the comments in source code.

The script requires:

  • imagemagick — to install. Follow instructions for your OS.
  • python — I’m sure your PC already has it installed!

Tested in Ubuntu and Mac OS X. How to use:

  • Save resize.sh to any folder on your computer.
  • Edit the file and set default values for variables (optional).
  • Open Terminal, navigate to this folder, and execute the following command: bash resize.sh.
  • Follow instructions, sit back and enjoy!

The Bash Script

Here is the full bash script. Of course, you can also download it from GitHub.

#!/bin/bash

# Edit the settings below:

# Output sizes - 
# Please note the format: each size is wrapped with quotes, width and height are separated with space.
output=("800 600" "1024 768" "1152 864" "1280 960" "1280 1024" "1400 1050" "1440 960" "1600 1200" "1920 1440" "1024 600" "1366 768" "1440 900" "1600 900" "1680 1050" "1280 800" "1920 1080" "1920 1200" "2560 1440" "2560 1600" "2880 1800")

# If you frequently use the same source file (e.g. "~/Desktop/src.jpg"), 
# set it in "default_src"
default_src="src.jpg";

# If you frequently use the same destination
# (e.g. "~/Desktop/Some_folder/%.jpg"), set it in "default_dst"
# Destination must include "%", it will be replaced by output size, e.g. "800x600"
default_dst="%.jpg";

# Add signature? 
default_sign='y'

# If you frequently use the same signature file (e.g. "~/Desktop/sig.png"), 
# set it in "default_sig"
default_sig="sig.png";

# Gravity is for cropping left/right edges for different proportions (center, east, west)
default_gravity="center"

# Output JPG quality: maximum is 100 (recommended)
quality=100

# ======
# Do not edit below.
# ======
# Welcome to Smashing resizer!
# Written by Vlad Gerasimov from http://www.vladstudio.com
# 
# This script takes one "source" image and saves it in different sizes.
# 
# Requires:
# * imagemagick - http://www.imagemagick.org/
# * python - I'm sure your PC already has it!

# Unfortunately, bash is awful at math operations.
# We'll create a simple function that handles math for us.
# Example: $(math 2 * 2)

function math(){
  echo $(python -c "from __future__ import division; print $@")
}

# To make our script short and nice, here is the "save()" function.
# We'll use it to save each size.

function save(){

  # read target width and height from function parameters
  local dst_w=${1}
  local dst_h=${2}

  # calculate ratio 
  local ratio=$(math $dst_w/$dst_h);

  # calculate "intermediate" width and height
  local inter_w=$(math "int(round($src_h*$ratio))")
  local inter_h=${src_h}

  # calculate best sharpness
  local sharp=$(math "round((1/$ratio)/4, 2)")

  # which size we're saving now
  local size="${dst_w}x${dst_h}"
  echo "Saving ${size}..."

  #crop intermediate image (with target ratio)
  convert ${src} -gravity ${gravity} -crop ${inter_w}x${inter_h}+0+0 +repage temp.psd

  # apply signature
  if [ "${sign}" == "y" ]; then
  convert temp.psd ${sig} -gravity southeast -geometry ${sig_w}x${sig_h}+24+48 -composite temp.psd
  fi

  # final convert! resize, sharpen, save
  convert temp.psd -interpolate bicubic -filter Lagrange -resize ${dst_w}x${dst_h} -unsharp 0x${sharp} +repage -density 72x72 +repage -quality ${quality} ${dst/\%/${size}}

}

# Ask for source image, or use default value
echo "Enter path to source image, or hit Enter to keep default value (${default_src}): "
read src
src=${src:-${default_src}}

# ask for destination path, or use default value
echo "Enter destination path, or hit Enter to keep default value (${default_dst})."
echo "must include % symbol, it will be replaced by output size, e.g. '800x600'"
read dst
dst=${dst:-${default_dst}}

# Ask for signature image, or use default value
echo "Apply signature? (hit Enter for 'yes' or type 'n' for 'no') "
read sign
sign=${sign:-${default_sign}}

# Ask for signature image, or use default value
echo "Enter path to signature image, or hit Enter to keep default value (${default_sig}): "
read sig
sig=${sig:-${default_sig}}

# ask for gravity, or use default value
echo "Enter gravity for cropping left/right edges (center, east, west), or hit Enter to keep default value (${default_gravity}): "
read gravity
gravity=${gravity:-${default_gravity}}


# detect source image width and height
src_w=$(identify -format "%w" "${src}")
src_h=$(identify -format "%h" "${src}")

# detect signature width and height
sig_w=$(identify -format "%w" "${sig}")
sig_h=$(identify -format "%h" "${sig}")


# loop throught output sizes and save each size
for i in "${output[@]}"
do
	save ${i}
done

# Delete temporary file
rm temp.psd

# Done!
echo "Done!"

Please let me know if you have any suggestions for improvements. Or perhaps you use a different technique to batch resize your images? Please share your thoughts, opinions and ideas in the comments section below!

(jvb) (vf)


© Vlad Gerasimov for Smashing Magazine, 2012.


The Creative Way To Maximize Design Ideas With Type // Drawing And Mark-Making


  

As with most designers, being sure that we explore and select the most successful, memorable and stimulating designs is a vital aspect that underpins every project we undertake. For us, the beginning of a new challenge has never been as simple as asking ourselves what might be the best avenue to take and then sitting down at a computer and attempting to fulfill that idea.

After researching the subject matter, we will almost always begin with a sheet of paper and pencil and draw out a variety of design options to help bring together and develop the breadth of ideas that are maturing in our minds. In this article, we will explore the use of drawing and mark-making as an integral part of the creative process.

First Example of Hand Rendered Type
An example of mark-making that helps to formulate design ideas for working with type and image. Note the changes in mark-making that indicate different levels of type.

We have found that exploring design options on paper using drawing and mark-making is a great way to ensure that we are moving in the right direction with a project; plus, we don’t think this working process can be beaten for stimulating unexpected solutions that would otherwise have been very unlikely to see the daylight. We‘ll focus on different types of drawing and mark-making as problem-solving tools and skills; they form a vital part of visualizing and exploring design alternatives that involve quantities of type, with or without images.

Why Textural And Tonal Qualities Of Type Should Be Addressed In Drawing

Letterforms, lines of type and words come together with different tonal values as well as varying characteristics of patterning; depending on the darkness of tone generated, together with the scale and nature of texture, a viewer is attracted to a greater or lesser degree. Some great examples of this can be found by looking at the newspaper and magazine designs of Jacek Utko. Looking at all of the sample pages below, we are struck by the number of dynamic levels of text created by different typefaces, point sizes, weights and measures, as well as the imagery. The changing tonal values especially tempt and guide the reader through the pages in a particular sequence.

Jacek Utko
Working with art direction from Liudas Parulskis and Vilmas Narecionis, Jacek Utko has designed some captivating pages for the weekend section of Lithuanias Verslo Zinios. The layouts make dramatic use of textural and tonal diversity and also contrast of scale.

The textural and tonal qualities in layouts are used as much to help guide the audience in a particular order as for aesthetics. These qualities should be effectively captured through drawing and mark-making if the visual of a concept is to be sufficiently realistic to enable adequate design judgments to be made. This can be fairly easily achieved by using a relatively speedy design shorthand practiced by and familiar to many designers. Larger type is lettered in, capturing the stylistic essence, weight and proportions of the desired letterforms; text can be lined, or “greeked,� in using a mix of mark-making techniques, pens, pencils and/or varied pressure to indicate textural and tonal differences.

The examples featured in this article go only some of the way to demonstrating and capturing the infinite rhythms and varieties of typographic alternatives and combinations, but they do still demonstrate that even during early-stage drawing of visuals, capturing subtleties and changes of pace is essential. Drawing and mark-making styles can be developed to indicate and capture the textural and tonal difference that are present when working, for example, with all-caps sans-serif letterforms, as opposed to the very different visual “beat� that comes from uppercase and lowercase characters.

Finding The Right Marking Tools And Paper

In highlighting the refinement of this type of design drawing, we should also briefly comment on the tools that can be used to express these subtle typographic nuances. We work with a smooth lightweight paper that in the UK is called layout paper; the semi-transparent properties of this inexpensive material are great for tracing through from one sheet to another, making for speedy refinement of drawings. Many of the designers we speak to use a mix of mark-making tools, depending on the characteristics they wish to create; some work with marker pens, others prefer fiber-tipped fine-line pens, and some draw with soft pencils. The one aspect that these choices seem to have in common is that they enable the designer to vary the quality of the mark simply by varying the pressure: press hard to create a thicker, darker mark, and press more gently to create a lighter, finer tone.

Developing Your Own Design Shorthand

Returning to the description of this style of visualizing as being “relatively speedy,� in reality, this process can be time-consuming, and while the results are not necessarily great in detail, this is thoughtful work that we certainly find to be the most time-efficient and creative way to work, particularly when confronted by completely new design challenges.

The drawing and mark-making in visuals that we are discussing here function on a number of levels. They capture alternatives of the textural and tonal details of layout; they are also a great way to explore different compositional alternatives; and they can be really helpful when used as templates or patterns to help streamline the process from marking to final design.

Typographic texture and tone will make different facets of a design more or less prominent. Choices of face, color, type size, tint, weight, inter-character spacing, line spacing and overall spatial distribution will affect the density of type and, consequently, the lightness or dark of the work. All of these aspects can be captured well with drawings and mark-making, affecting not only tonal values, but also the subtle textural qualities of type. Too often, visuals capture only the scale and position of type, without showing more detailed characteristics.

Aleksandrs Golubovs
Aleksandrs Golubovs’ layout deals with composition and does not show hierarchy or changes in typeface, point size, weight or leading. Minimal additional work with more varied mark-making would easily capture all of these missing elements.

The examples below demonstrate that we are not suggesting hugely time-consuming mark-making, but rather merely sufficient variety to convey a realistic and satisfying impression.

Mark Making 1

Mark Making 2
The visuals above are examples of different mark-making styles that demonstrate changes in weight, scale, leading and case. A mixture of marker, pen and pencil have been used here, but any tools may be used; ideally, though, tools that create marks of different quality in response to varied pressure are best.

Why Is Visualizing So Helpful To Designing With Type?

We take the view that using drawing and mark-making to produce visuals is an excellent way to develop ideas and extend design in order to explore creative possibilities. Drawing often pushes us into unexpected and exciting avenues of design that we might not have otherwise considered. An amazing link is forged between the brain and hand, effectively enabling the translation and visualization of even the most subtle design ideas, including textural and tonal variations. The act of drawing is an expression of this link. There are plenty of well-known quotes about the connections between the head, the heart and the hand. John Ruskin, the British artist and writer, said in the late-19th century, “The education of a young artist should always be a matter of the head and heart and the hand.� Art and design, Ruskin said, “must be produced by the subtlest of all machines, which is the human hand.�

In 1950, Richard Guyatt, the British designer and academic, described the three interrelated elements of design as the combined action of head, heart and hand. The head provides logic; the heart, emotional stimuli; and the skill that gives form to design concepts is executed by the hand.

As part of our work with students and in our own design practice, we often use two levels of drawing to visualize. These two forms we describe as micro and macro. Micro-visualizing within more complex design challenges explores the alternatives of detail “close in�; for example, how a heading, subheading and paragraph of text come together or how an image and caption unite.

When the most effective combination is decided upon, the relationships and combinations can then be developed and applied across other micro aspects of the design challenge. Taking a number of these effectively resolved micro-visuals, we would progress to our second level of visualization: macro-visualizing. By using the semi-transparent properties of layout paper, we would speedily trace through and bring together a group of micro-visuals to form an entire “page� grouping. It is at this stage that we would draw in the page’s parameters and try out different relationships of scale and varied compositional possibilities.

Jones and Smith

Sticky Graphics Thumbnail 1

Sticky Graphics Thumbnail 2

Sticky Graphics Thumbnail 3

Sticky Graphics Type Visuals
These images show some of the micro-thumbnails for our book design for “Sticky Graphics.� Given that the book is about memory devices, we wanted to be sure to create a lasting impression with type. In our design drawings, shown above, we indicate possible textural and tonal variations and hierarchy for the design credits and captioning; also, we have noted the compositional aspects needed for these micro-elements of the design. The final image shows some primary digital interpretations of these drawings.

Abigale Macro 1

Abigale Macro 2

Abigale Macro 3
These three images are by graphic designer Abigail Urwin, who has kindly shared some of her macro design drawing and visuals. In these examples, Abigail is developing designs with type for a news spread in a magazine. These pages will ultimately contain five separate smaller articles that come together under a common theme. In the first two images, she is exploring alternative ways to design these articles. In the third image, Abigail has started to show how she might bring these five articles together in the one spread.

Layout Making It Fit Drawn Micro Visuals

Layout Digital Visual 1

Layout Digital Visual 2
These examples show some of the initial micro-visuals for our first book, “Layout: Making It Fit.� The drawings explore textural, tonal, hierarchical and compositional options, and the two double-page spreads show some of our digital interpretations of aspects of these design drawings.

Starting a new design in this way, we would always begin by searching out the most complex aspect of the project. Figuring out a design system to tackle the most difficult scenario first makes it easier to apply the resulting design systems and relationships to simpler aspects of the project. There are no hard and fast rules to sequencing the various aspects of visualization. We have found that the order in which we draw by hand and work on the computer varies, and the two methods are sometimes merged. However done, using these two methods of development in partnership is an excellent way to maximize design ideas.

If You’re An Experienced Designer, Is Visualizing Really Necessary?

In a completely new design project, the methodology outlined above helps to ensure that our result is not in any way restricted by the starting point on the computer or by the relatively simple manipulations that are often tempting to pursue but not necessarily the most appropriate or stimulating. Drawing helps to put our most effective design concepts squarely at center stage and forces us to then find the best way to achieve the desired result. If we start with a blank sheet of layout paper and pencil and, of course, undertake research to get inspiration, then design-wise, the sky’s the limit.

Were ever inclined to simply reuse a palette of typographic styles that worked in a previous project, simply for ease and speed? We know we were, but taking the time and effort to try out alternatives and to develop completely different options would have improved the result and, for that matter, increased our satisfaction. We had our eyes on the clock and produced solutions that were satisfactory but definitely not the most effective, stimulating or satisfying.

Translating Drawing Into Design

A vital aspect of this process is being able to translate the nuances of mark-making into the final work. This requires making a detailed and precise evaluation of the drawings. The subtle contrasts of tone and texture in your visuals should help to build a valuable picture of the type and imagery and, for that matter, every other aspect of the design. Look carefully at the subtleties in the visuals, and use them as a starting point in selecting the nuances of typeface, weight, tracking, kerning and even leading.

Making the transition from smaller paper visuals to Web or print design can be difficult, and we discuss this issue often with our students. One system that seems to work well for now — albeit, one that relies totally on the visuals being proportional in size to the final design — is to scan or carefully photograph the visuals and then drop them into the background of a digital file to be used as a template for the final artwork. When the design is sufficiently rendered, the template can be deleted.

Translating Designs 1

Translating Designs 2
The three images here show the process described in the preceding paragraph. The first step shows a simple drawing of the front page of a newsletter. The next two images show stages leading to the finished version. The digital rendering, including of the type, is shown in magenta to distinguish between the layers for the purpose of this article.

Another Reason To Draw: As Inspiration For Working With Type And Image

Another reason to do mark-making is to develop ideas for type, which we have done very effectively and included as an exercise in our book Create Impact with Type Image and Color. The method involves finding samples of type and then cutting and pasting them to form new layouts. The copy does not have to make sense, but the abstract results can be a surprising and inspiring way into a design project that involves type.

Layout 1

Layout 2

Layout 3
This exercise has been very popular with our students, who have been inspired by the design options captured by their abstract layouts. In the examples shown here, students have brought together found samples of type to create textural and tonal contrast and dynamic composition, without the pressure of designing for sense.

The ease and instant gratification of rapidly generating a design right on the computer screen is very tempting. Acceptable concepts can be and are generated this way. But if a designer aspires to a wider spectrum of interesting and usable visual concepts, then achieving this by working solely on the computer is unlikely.

In no way are we belittling the computer; the asset is invaluable to the designer. But we firmly believe that it should not replace the intuitive pathways between the head, heart and hand. Drawing by hand first and then by computer is not set in stone; either may come first if we use them in tandem to explore and develop the most effective solutions for audiences and designers alike.

Paper and pencil concepts must be a part of the design process if ideas are to be maximized. There are no rules or precise styles that designers need to follow, although sufficient accuracy and detail is needed in order to be able to make informed judgments. Our cut-and-paste way of working with found samples of type and putting together unusual combinations can also be an inspiring starting point. While there are no set do’s and don’ts in the design process, an appropriate amount of drawing, mark-making and experimentation is bound to improve the final result.

This article has been a wonderful opportunity to examine the role that drawing and mark-making can play when generating ideas with type. Previously, we had only briefly touched on this topic when writing more extensively about the textural and tonal qualities of designing with type and imagery in a number of our books, including Create Impact with Type Image and Color and The Graphic Design Exercise Book. Both of these practical guides are useful reminders of the fundamentals of graphics and of designing with type.

Useful Ressources

(al)


© C. Knight, J. Glaser for Smashing Magazine, 2012.


Anniversary Special: Printed Books 30% Off! // Reminder


  

You’ve probably already heard: we’ve turned six years old! One thing is for sure: the past six years have been special – we’ve learned a lot! Much of this would not have been possible without your help. We are very grateful for your support and your feedback that keeps us going, and constantly inspires us to come up with new ideas and ways to improve Smashing Magazine.

Looking back at our work over the years, we feel grateful and proud of what we have achieved, and this celebration calls for an exceptional surprise. We’d like to share a special offer with you today: 30% discount on all printed Smashing books! For you, your friends, colleagues, or perhaps even your clients! Please note that this discount is only valid until Saturday midnight CET.

Overall, we have released four printed books in the past. Each book has a story of its own, but in all cases, we made sure to pack the books full with useful and valuable content. Along with each printed book, you get an eBook version for free (in PDF, ePUB and Kindle formats). This is the chance to add the books to your office reference library, or surprise a fellow colleague with a great set of Smashing books!

The Full Smashing Books Anthology
(4 printed books + 4 eBooks)
$69.30 $99.00
Smashing Book 3 + 3â…“ Bundle
(2 printed books + 2 eBooks)
$34.85 $49.80
Smashing Books 1 + 2 Bundle
(2 printed books + 2 eBooks)
$34.85 $49.80
Smashing Book 3
(Printed + eBook)
$27.90 $39.90
Smashing Book 3â…“
(Printed + eBook)
$10.40 $14.90
The Smashing Book 2
(Printed + eBook)
$27.90 $39.90
The Smashing Book 1
(Printed + eBook)
$16.00 $22.90

Acknowledgements

We thank each and every one of you for reading, listening, leaving a comment, and for even mentioning us during your coffee breaks. We take it to heart, respect your time and sincerely appreciate your love and support. We promise to keeping doing our best and keep on smashing!

Have fun exploring, reading and designing!

Yours sincerely,
The Smashing Team


© Smashing Editorial for Smashing Magazine, 2012.


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress