TweetFollow Us on Twitter

The Road to Code: More Cocoa Bits

Volume Number: 24 (2008)
Issue Number: 06
Column Tag: The Road to Code

The Road to Code: More Cocoa Bits

Interface Builder UI tweaking and introduction to table view

by Dave Dribin

Customizing the User Interface

Last month in The Road to Code we went over how to customize application behavior using notifications and delegates. This month we're going start off talking about how you can customize the user interface in Interface Builder. There's a lot you can tweak without writing a line of code.

Window Resizing

One important aspect of user interface design is how the window and its views and controls react to resizing. Improper resizing may confuse the user and lead to a bad user experience. You control how resizing affects each and every view and control within Interface Builder. Unfortunately, the defaults are rarely useful. For example, if we resize our Hello World window with the default settings, it will look similar to Figure 1.

Figure 1: Improper window resizing

As you resize, all the controls will be bunched up in the upper-left portion of the window. This isn't really a good use of the extra space. The text fields on the right should expand to the full width of the window, and the Calculate button should also stick to the right side of the window. Thus we want the window to look similar to Figure 2 when resized.

Figure 2: Proper window resizing

I've also kept the Calculate button on the bottom of the window. You could also keep it pinned towards the top, but for demonstration purposes, I'm going to keep it on the bottom. In order to make our window properly resize like this, we need to open Interface Builder.

Select the text field next to the Rectangle Width label. Next, open up the Inspector panel and select the Size tab; it's third from the left with the ruler icon. It should look similar to Figure 3.

Figure 3: Size panel of the Inspector

This panel contains information about the size of the selected view. The Autosizing section is the part that dictates how the control behaves when the window is resized. The left portion of the autosizing section is called the springs and struts. There are six lines you can click on and activate, two on the inside and four on the outside. The two on the inside are called springs and the four on the outside are called struts as noted in Figure 4.

Figure 4: Autosizing springs and struts

When a specific string or strut is activated, it is colored red and has a solid line. When not activated, it is colored light red with a dotted line. An activated spring indicates that the width or height of the view expands and contracts in proportion to its superview. An activated strut indicates that the view maintains a fixed distance between its edge and the same edge of its superview. The right portion of autosizing section is an animated preview showing you how the settings will affect the view. You should see the animation change as you activate and deactivate springs and struts.

The animated preview is handy, but sometimes you need to actually run the application and try resizing the window to verify your settings. While you can go back to Xcode and run the application, Interface Builder allows you to simulate the interface without switching to Xcode. Choose the File > Simulate Interface menu or Command-R to do this. While simulating the interface, you may resize the window and watch how the views react. When you are done, you need to quit the Cocoa Simulator using the menu or Command-Q. Between the animation preview and the simulator, you should be able to find the correct springs and struts settings for your application without ever switching to Xcode.

The default setting, as shown in Figure 4 above, is to have the top and left struts activated and no springs activated. This explains why all of our controls are bunched up in the upper left portion of the window. For our text fields, we want to activate the horizontal spring and the left, right, and top struts. This will cause them to resize horizontally while staying pinned on the left, right, and top. The final settings should look like Figure 5.

Figure 5: Autosizing for text fields

For the Calculate button, we don't want any springs activated. The default settings have only the top and left struts activated, so we need to change this again. We want only the right and bottom struts activated. This will keep the button pinned to the lower right portion of the window. The final settings should look like Figure 6.

Figure 6: Autosizing for button

Try simulating the user interface, and see if it behaves correctly. It should now work as shown in Figure 2. Once it works, save the nib file, switch back to Xcode, and run the application. Again, the controls should resize appropriately.

There's one final aspect of our resizing that's not quite right. While making the window bigger works fine, it is possible to resize the window so small such that not all of our controls will fit in the window. To prevent this, we can specify a minimum size for our window. The window's sizes can be viewed and set in the Size pane of the Inspector window, as well. If you select the window by clicking on its title bar the Size pane should look similar to Figure 7.

Figure 7: Window size

You can see that our window has neither a minimum nor maximum size. Click on the Has Minimum Size checkbox to enable a minimum size. I think the window as currently laid out makes a nice minimum size, so click the Use Current button to set the minimum size to the window's current size. If you now simulate the user interface, you should be able to resize the window larger and smaller, as before, but you should not be allowed to resize it any smaller than the defined size. This is perfect, so save the nib file. If you want, you may provide a maximum size, too. I'm going to keep the maximum size disabled so the user can make the window as large as they want.

Resizing the window in Interface Builder

You can now properly resize the window in a running application, but what about resizing the window in Interface Builder? You can resize the window by dragging the resize corner, just as in a running application. However, the controls inside the window do not resize according to their autosizing settings. This may be fine if you are resizing the window to make room for more views. However, if you just want to make the window larger or smaller, it can be a chore to go through and manually resize each view and control after resizing the window. Fortunately there is a trick. If you hold down the Command key while resizing the window in Interface Builder, the controls will also resize according to their autosizing settings. If, for some reason, you forget to hold down Command while resizing the window, Interface Builder allows you to undo the resize. Then you can redo it while holding down the Command key.

Formatters

By default, text fields can display and accept any text. Sometimes, however, the text fields need stricter formatting. Our rectangle program is a perfect example. The rectangle values are all floating point numbers. Maybe we would like to control how many decimal points are displayed. Also, our user interface doesn't stop the user from entering letters into the width and height fields. Other applications may like to format numbers in text fields as currency or percentages.

Luckily Cocoa has just the solution for us, called formatters. Formatters can be added to any text field to customize how objects are presented to the user. Interface Builder comes with two built-in types of formatters that you will use frequently: number formatters and date formatters. Number formatters take a number, usually a floating point number, and format it better. They are quite flexible and can be used to customize how decimal points are used, as well as allowing you to add comma separators for numbers over a thousand and format numbers as currency and percentages. To apply a formatter to a text field, drag it from the Library panel on top of a text field, as in Figure 8. Date formatters are used to customize the presentation of NSDate objects.

Figure 8: Adding a number formatter

The formatter is now attached to the text field. Interface Builder shows this by adding an icon of the formatter just below the text field as shown in Figure 9.

Figure 9: Text field with an attached formatter

By clicking on the formatter icon, you can change its attributes. Click on the formatter now, and the Attributes pane of the Inspector panel should update as in Figure 10. The Style pull-down menu offers various pre-configured formats. Set the Style to be Decimal.

Figure 10: Number formatter attributes

Now add a formatter with the Decimal style to the other numeric text fields, as well. If you would like, you can customize the decimal field to show one digit after the decimal point by setting the Minimum Fraction Digits to 1. When you run the application with formatters in place, numbers over 1,000 should be formatted appropriately as shown in Figure 11.

Figure 11: An application with formatters

Formatters not only convert from an object to text, but they also convert text back into an object. For number formatters, they are converted to NSNumber objects. The most important benefit we get out of using number formatters for input is that it restricts the user input to numbers only. If the user enters letters, the formatter will remove them from the text field.

With the autosizing properly set up, the minimum window size in place, and formatters on the text fields, our user interface is now nicely polished. And we didn't have to write a single line of code. All the tweaking was done using Interface Builder. The final code for this project may be found on the MacTech website.

Table Views

I'd like to shift gears a bit and get back to code and talk about a popular control called a table view. A table view is a control, like buttons and text fields, and is implemented by the NSTableView class. It displays rows and columns of information, similar to a spreadsheet application. It is a powerful control that is used in many applications.

Because a table view may display large amounts of information, the view class itself does not hold all the data. Instead, the table view requires a separate class that provides the data called a data source. Whenever the table view needs to display data for a specific row and column, it asks the data source for this information.

In last month's article, we talked about notifications and delegates as a way to customize user interface behavior in code, and data sources are very similar to delegates. A data source class must also implement specific methods. A table view may have both a delegate and a data source. The table view's delegate is only used for customizing the behavior of the view itself, just like the window and application delegates from last month. The same class may even implement the table view data source and delegate methods.

Let's go over a simple example of a table view and its data source. We're going to ignore the table view delegate and use the default behavior. Create a new Cocoa Application project in Xcode and open up its MainMenu.nib file in Interface Builder. You should have a blank window. Now, find the table view in the Library panel and drag it to the window. Resize the table view so that there is a small border around all sides. Finally, active all the springs and struts for the table view. This should allow the table view to expand vertically and horizontally as the window is resized.

Next, let's look at the attributes for a table view that are available in Interface Builder. Because a table view is enclosed in a scroll view, it can sometimes be a bit tricky to choose the table view. With the Attributes pane of the Inspector panel selected, click on the table view. Most likely, this will select the outer scroll view, which will have attributes that look like Figure 12. You may customize how the scroll bars, or scrollers, are displayed from this panel. The default is fine for us.

Clicking on the table view again should select the table view itself, and the Attributes pane should look similar to Figure 13. Now you can customize attributes of the table view itself, such as how many columns it has and various selection possibilities. Again, we're going to leave the default settings, but we will be coming back to this shortly.

Figure 12: Scroll view attributes

Oh, and because selecting the scroll view and table view can be a bit tricky, I'm going to let you in on a little secret that may help out. You can customize how Interface Builder shows the components in the nib. If you select list mode from the toolbar, you will be presented with a hierarchical list of components, instead of just icons. From this view, you may open up the disclosure triangles to select the scroll view or table view directly, as in Figure 14. Using list mode is often very helpful in selecting nested views, such as table views, tab views, and split views.

With the table view selected, you can now select individual table columns and change their attributes. After selecting the first table column, set its title and identifier to Column 1 and One, respectively, as shown in Figure 15. Now change the second column to have its title and identifier to be Column 2 and Two, respectively.

Figure 13: Table view attributes

Figure 14: List mode of Interface Builder

Figure 15: Table column attributes

If you save the nib and run the application from Xcode, you should get a window and table view, but the table view should be empty. In order to get data into the table view, we need to implement a data source in code. Create a new Objective-C class and name it MyController. In order for this class to be a table view data source, it must implement at least two methods. Here's the first one:

- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView;
{
    return 3;
}

The purpose of this method is self-explanatory: it sets the number of rows for a given table view. While the number of columns is set in Interface Builder, the number of rows is set in your code. For demonstration purposes we are returning a constant value of 3, which means three rows will be displayed.

Every row and column refers to a particular value in the table called a table cell. The second method that you must implement provides the actual data for each cell:

- (id) tableView: (NSTableView *) tableView
objectValueForTableColumn: (NSTableColumn *) tableColumn
            row: (NSInteger) rowIndex
{
    NSString * identifier = [tableColumn identifier];
    return [NSString stringWithFormat:
            @"%@ %d", identifier, rowIndex];
}

This method gets called for each and every cell in the table. You'll notice that it passes a table column object, NSTableColumn, and a row index. You may be surprised that it does not pass a column index, too. The problem is that the user is free to re-order columns, and this would make the column index pretty useless. From column object, we can get the identifier we setup in Interface Builder. The identifier is a much more reliable value than the column index, thus you can see why using a unique and meaningful identifier is very useful. For testing purposes, we are returning a string using the table column identifier and the row index.

We're almost ready to run our application, but first we need to tell the table view that MyController is its data source. Be sure to save all your files in Xcode and switch to Interface Builder. Find NSObject in the Library panel and drag it to you MainMenu.nib window. Set the class of this new object to be MyController in the Inspector panel. This creates an instance of the MyController class inside the nib.

Hooking this object up to the table view is similar connecting a delegate. You need to control-drag from the table view to the controller object. Be sure you are dragging from the table view and not the scroll view or the table column. Use list mode, if you have trouble selecting the table view. Once you control-drag from the table view to the controller object, Interface Builder should popup a menu allowing you to choose the outlet for connection. Two choices exists for table views: dataSource and delegate. Choose dataSource from the menu, as shown in Figure 16.

Figure 16: Connecting a data source

Now, save the nib, switch back to Xcode, and run the application. If all goes well, you should see a window similar to Figure 17. There should be three rows in the table and the contents of each table cell should be a mix of the table column identifier and the row index. You can even re-order the table columns if you want, and the table cell values should remain the same.

Figure 17: Simple table application

A Useful Table Example

Admittedly, that example is not very useful, so let's spice it up. Let's bring back our trusty Rectangle class and create an application to show a list of rectangles along with their area and perimeters. Add the Rectangle.h and Rectangle.m files to your Xcode project. For reference, the header file is shown in Listing 1.

Listing 1: Rectangle.h header file

#import <Foundation/Foundation.h>
@interface Rectangle : NSObject
{
    float _leftX;
    float _bottomY;
    float _width;
    float _height;
}
@property float leftX;
@property float bottomY;
@property float width;
@property float height;
@property (readonly) float area;
@property (readonly) float perimeter;
- (id) initWithLeftX : (float) leftX
             bottomY: (float) bottomY
              rightX: (float) rightX
                topY: (float) topY;
@end

Go to Interface Builder and select the table view. We need to setup our table with four columns, each with the following header titles: Width, Height, Area, and Perimeter. In the table view's attributes, set the number of columns to 4. Resize the window so that all four columns are available. Then, select each column and change the title and identifiers appropriately. In order to keep things simple, let's keep the identifiers the same as the titles. Finally, make sure each column is not editable. The attributes for the width column are shown in Figure 18. Make sure the other three columns are setup in a similar fashion.

Figure 18: Width column attributes

Just as we can add formatters to text fields, you can also add them to table columns. Add number formatters to each of the table columns by dragging from the Library to the text cells of each table column. Set their style to be Decimal, as we did earlier.

We are finished with the user interface, so save the nib and switch to Xcode. Our controller class will keep an array of rectangles and display them in the table. Let's start out by populating the array in our constructor with a few rectangles:

- (id) init
{
    self = [super init];
    if (self == nil)
        return nil;
    
    _rectangles = [[NSMutableArray alloc] init];
    
    Rectangle * rectangle;
    rectangle = [[Rectangle alloc] initWithLeftX   : 0
                                         bottomY: 0
                                          rightX: 10
                                            topY: 20];
    [_rectangles addObject: rectangle];
    // Without garbage collection you need:
    // [rectangle release];
    
    rectangle = [[Rectangle alloc] initWithLeftX   : 0
                                         bottomY: 0
                                          rightX: 500
                                            topY: 100];
    [_rectangles addObject: rectangle];
    // Without garbage collection you need:
    // [rectangle release];
    
    return self;
}

Be sure to add the _rectangles instance variable to the header file. Now, we're going to enable garbage collection for our project, too. This allows use to avoid releasing the rectangle instances and avoid implementing a destructor. Click on the project name in the Groups & Files list on the left. Then choose the File > Get Info menu to open up the Inspector panel. Select the Build tab, find the Objective-C Garbage Collection build setting and set it to Supported.

If you do not want to enable garbage collection, uncomment the release calls to rectangle and implement the dealloc method to release the _rectangles array. You also need to release the rectangle instances after adding them to the _rectangles array, as described in the comments. Remember the array retains objects, so you need to release them if you no longer need them.

Now we need to modify our data source methods to use the array of rectangles, instead of hard coded values. The numberOfRowsInTableView method is easy. It returns the number of elements in the _rectangles array:

- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView
{
    return [_rectangles count];
}

The tableView:objectValueForTableColumn:row: method is a bit more complex. It needs to return the proper rectangle property based on the identifier. The other tricky part is that the method returns an id type. This means we need to wrap our float values inside an NSNumber instance, as well:

- (id) tableView: (NSTableView *) tableView
objectValueForTableColumn: (NSTableColumn *) tableColumn
            row: (NSInteger) rowIndex
{
    NSString * identifier = [tableColumn identifier];
    Rectangle * rectangle = [_rectangles objectAtIndex: rowIndex];
    float value;
    if ([identifier isEqualToString: @"Width"])
        value = rectangle.width;
    else if ([identifier isEqualToString: @"Height"])
        value = rectangle.height;
    else if ([identifier isEqualToString: @"Area"])
        value = rectangle.area;
    else if ([identifier isEqualToString: @"Perimeter"])
        value = rectangle.perimeter;
    
    return [NSNumber numberWithFloat: value];
}

Running our application now should result in a window similar to Figure 19. It should show our two rectangles, along with their corresponding area and perimeter.

Figure 19: Initial rectangle table

Try resizing the window and see if it works correctly. Also try editing the individual table cells. Because we setup our table columns to be uneditable, it should not be allowed. The full listings for MyController are shown in Listing 2 and Listing 3.

Listing 2: MyController.h header file

#import <Cocoa/Cocoa.h>
@interface MyController : NSObject
{
    NSMutableArray * _rectangles;
}
@end
#import "MyController.h"
#import "Rectangle.h"
@implementation MyController
Listing 3: MyController.m source file
- (id) init
{
    self = [super init];
    if (self == nil)
        return nil;
    
    _rectangles = [[NSMutableArray alloc] init];
    
    Rectangle * rectangle;
    rectangle = [[Rectangle alloc] initWithLeftX   : 0
                                         bottomY: 0
                                          rightX: 10
                                            topY: 20];
    [_rectangles addObject: rectangle];
    // Without garbage collection you need:
    // [rectangle release];
    
    rectangle = [[Rectangle alloc] initWithLeftX   : 0
                                         bottomY: 0
                                          rightX: 500
                                            topY: 100];
    [_rectangles addObject: rectangle];
    // Without garbage collection you need:
    // [rectangle release];
    
    return self;
}
- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView
{
    return [_rectangles count];
}
- (id) tableView: (NSTableView *) tableView
objectValueForTableColumn: (NSTableColumn *) tableColumn
            row: (NSInteger) rowIndex
{
    NSString * identifier = [tableColumn identifier];
    Rectangle * rectangle = [_rectangles objectAtIndex: rowIndex];
    float value;
    if ([identifier isEqualToString: @"Width"])
        value = rectangle.width;
    else if ([identifier isEqualToString: @"Height"])
        value = rectangle.height;
    else if ([identifier isEqualToString: @"Area"])
        value = rectangle.area;
    else if ([identifier isEqualToString: @"Perimeter"])
        value = rectangle.perimeter;
    
    return [NSNumber numberWithFloat: value];
}
@end

Conclusion

Once again, we've covered a lot of ground in just one article. There's a lot more we can do with a table view, too much to cover in a single article. Next month, we'll explore how to add and remove rectangles from the table. That is, if you haven't gone ahead and figured it out on your own.


Dave Dribin has been writing professional software for over eleven years. After five years programming embedded C in the telecom industry and a brief stint riding the Internet bubble, he decided to venture out on his own. Since 2001, he has been providing independent consulting services, and in 2006, he founded Bit Maki, Inc. Find out more at http://www.bitmaki.com/ and http://www.dribin.org/dave/.

 
AAPL
$524.94
Apple Inc.
+5.93
MSFT
$40.01
Microsoft Corpora
-0.39
GOOG
$536.10
Google Inc.
-20.44

MacTech Search:
Community Search:

Software Updates via MacUpdate

Tweetbot 1.5.1 - Popular iOS twitter cli...
Tweetbot is a full-featured OS X Twitter client with a lot of personality. Whether it's the meticulously-crafted interface, sounds and animation, or features like multiple timelines and column views... Read more
Mac DVDRipper Pro 4.1.7 - Copy, backup,...
Mac DVDRipper Pro is the DVD backup solution that lets you protect your DVDs from scratches, save your batteries by reading your movies from your hard disk, manage your collection with just a few... Read more
PDFpenPro 6.2 - Advanced PDF toolkit for...
PDFpenPro allows users to edit PDF's easily. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Create... Read more
PDFpen 6.2 - Edit and annotate PDFs with...
PDFpen allows users to easily edit PDF's. Add text, images and signatures. Fill out PDF forms. Merge or split PDF documents. Reorder and delete pages. Even correct text and edit graphics! Features... Read more
Monolingual 1.5.9 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. It requires a 64-bit capable Intel-based Mac and at least... Read more
Maya 2015 - Professional 3D modeling and...
Maya is an award-winning software and powerful, integrated 3D modeling, animation, visual effects, and rendering solution. Because Maya is based on an open architecture, all your work can be scripted... Read more
Starcraft II: Wings of Liberty 1.1.1.180...
Download the patch by launching the Starcraft II game and downloading it through the Battle.net connection within the app. Starcraft II: Wings of Liberty is a strategy game played in real-time. You... Read more
Sibelius 7.5.0 - Music notation solution...
Sibelius is the world's best-selling music notation software for Mac. It is as intuitive to use as a pen, yet so powerful that it does most things in less than the blink of an eye. The demo includes... Read more
Typinator 5.9 - Speedy and reliable text...
Typinator turbo-charges your typing productivity. Type a little. Typinator does the rest. We've all faced projects that require repetitive typing tasks. With Typinator, you can store commonly used... Read more
MYStuff Pro 2.0.16 - Create inventories...
MYStuff Pro is the most flexible way to create detail-rich inventories for your home or small business. Add items to MYStuff by dragging and dropping existing information, uploading new images, or... Read more

Latest Forum Discussions

See All

Have a Special Dead Trigger 2 Easter Bas...
Have a Special Dead Trigger 2 Easter Basket Full of Goodies, Courtesy of Madfinger Games Posted by Rob Rich on April 18th, 2014 [ permalink ] Dead Trigger 2 | Read more »
Zynga Launches Brand New Farmville Exper...
Zynga Launches Brand New Farmville Experience with Farmville 2: Country Escape Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
David. Review
David. Review By Cata Modorcea on April 18th, 2014 Our Rating: :: MINIMALISTIC IN A DIFFERENT WAYUniversal App - Designed for iPhone and iPad David is a minimalistic game wrapped inside of a soothing atmosphere in which the hero... | Read more »
Eyefi Unveils New Eyefi Cloud Service Th...
Eyefi Unveils New Eyefi Cloud Service That Allows Users to Share Media Across Personal Devices Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
Tales from the Dragon Mountain: The Lair...
Tales from the Dragon Mountain: The Lair Review By Jennifer Allen on April 18th, 2014 Our Rating: :: STEADY ADVENTURINGiPad Only App - Designed for the iPad Treading a safe path, Tales from the Dragon Mountain: The Lair is a... | Read more »
Yahoo Updates Flickr App with Advanced E...
Yahoo Updates Flickr App with Advanced Editing Features and More Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
My Incredible Body - A Kid's App to...
My Incredible Body - A Kid's App to Learn about the Human Body 1.1.00 Device: iOS Universal Category: Education Price: $2.99, Version: 1.1.00 (iTunes) Description: Wouldn’t it be cool to look inside yourself and see what was going on... | Read more »
Trials Frontier Review
Trials Frontier Review By Carter Dotson on April 18th, 2014 Our Rating: :: A ROUGH LANDINGUniversal App - Designed for iPhone and iPad Trials Frontier finally brings the famed stunt racing franchise to mobile, but how much does its... | Read more »
Evernote Business Notebook by Moleskin I...
Evernote Business Notebook by Moleskin Introduced – Support Available in Evernote for iOS Posted by Tre Lawrence on April 18th, 2014 [ permalink ] | Read more »
Sparkle Unleashed Review
Sparkle Unleashed Review By Jennifer Allen on April 18th, 2014 Our Rating: :: CLASSY MARBLE FLINGINGUniversal App - Designed for iPhone and iPad It’s a concept we’ve seen before, but Sparkle Unleashed is a solidly enjoyable orb... | Read more »

Price Scanner via MacPrices.net

iMacs on sale for up to $160 off MSRP this we...
Best Buy has iMacs on sale for up to $160 off MSRP for a limited time. Choose free home shipping or free instant local store pickup (if available). Prices are valid for online orders only, in-store... Read more
iPad Airs on sale this weekend for up to $100...
Best Buy has WiFi iPad Airs on sale for $50 off MSRP and WiFi + Cellular iPad Airs on sale for $100 off MSRP on their online store for a limited time, with prices now starting at $449. Choose free... Read more
Apple restocks refurbished Mac minis starting...
The Apple Store has restocked Apple Certified Refurbished Mac minis for up to $150 off the cost of new models. Apple’s one-year warranty is included with each mini, and shipping is free: - 2.5GHz Mac... Read more
Hyundai Brings Apple CarPlay To The 2015 Sona...
Hyundai Motor America has announced it will bring Apple CarPlay functionality to the 2015 Sonata. CarPlay is pitched as a smarter, safer and easier way to use iPhone in the car and gives iPhone users... Read more
Updated iPads Coming Sooner Than We Had Thoug...
MacRumors, cites KGI securities analyst Ming Chi Kuo, well-respected as an Apple product prognisticator, saying that Apple will introduce an upgraded iPad Air and iPad mini in 2014/Q3, meaning the... Read more
Toshiba Unveils New High And Low End Laptop M...
Toshiba has announced new laptop models covering both the high-end and low-end of the notebook computer spectrum. Toshiba 4K Ultra HD Laptop Toshiba’s new Satellite P55t features one of the world’s... Read more
Save up to $270 with Apple refurbished 13-inc...
The Apple Store has Apple Certified Refurbished October 2013 13″ Retina MacBook Pros available starting at $1099, with models up to $270 off MSRP. Apple’s one-year warranty is standard, and shipping... Read more
Apple now offering refurbished iPad mini with...
The Apple Store has Certified Refurbished 2nd generation iPad minis with Retina Displays now available starting at $339. Apple’s one-year warranty is included with each model, and shipping is free.... Read more
Microsoft Blinks – Drops Microsoft Office 365...
Microsoft has dropped the annual subscription fee for Microsoft Office 365 Personal – which is needed in order to create and edit documents in Microsoft Office for iPad. However, Apple’s iOS and OS X... Read more
New AVG Vault Apps for iOS and Android Help K...
AVG Technologies N.V. an online security company for 177 million active users, has announced the launch of its latest mobile application, AVG Vault. The free app introduces an innovative user... Read more

Jobs Board

*Apple* Automotive Parts Department position...
Apple Automotive is one of the fastest growing dealer…and it shows. Consider making the switch to the Apple Automotive Group today! At Apple Automotive, we Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Retail - Manager - Holyoke - Apple I...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Retail - Manager - Apple (United Sta...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you're a master of them all. In the store's fast-paced, dynamic Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.