WebCode Workflow with Adobe Illustrator and Photoshop

webCodeIconImage256I’ve posted the content and slides from this week’s presentation on WebCode and Adobe tools.

As far as feedback from the group, there was considerable interest in the ability to convert PSDs to raster layers. I clearly didn’t give this feature the attention it deserved in my initial review. I’m a bit fixated on vectors right now. Many in my group are very much in the raster world, and they loved what WebCode was doing with PSD.

Why is this so cool?

If you consider that you can separately animate layers of raster content on a web page, it’s a very big deal. The support of Photoshop effects is shockingly good, far more than I reasonably expected. The exports from WebCode are outstanding by any measure. Some people like animating in Javascript, some like CSS animations. These exports make it very easy to do. Even the SVG export, with rasters, is easy to animate (although I would’t recommend ever scaling rasters up).

At $49.99, WebCode is worth every penny. It can be used by itself, and produce great stuff. That fact that it also plays so very well with Adobe products is miraculous. Love those PixelCut guys!

Posted in Adobe Tagged , , , ,

Software Review: PixelCut’s WebCode Is A Winner

webCodeIconImage256Pixel Cut has released a new tool called WebCode for creating your web images into code — web code, as in HTML, SVG, JavaScript+Canvas and CSS. Yes, very cool.

The Advantage of Vector Imaging on Your Website

Every webmaster and web designer knows that making great web images for sites, especially supporting retina screens (for iOS devices and Macs) or hi-res monitors is a major challenge. Vector is a great answer to breeding raster images on your site. Drawing vector through code is the same great answer. Getting this solution has required something like SVG (scaled vector graphic) generation with a tool like Adobe Illustrator or Inkscape. The more radical solution? A web programmer doing canvas drawing. That was it, and it can be intimidating. But solving the retina issue is a very big deal. It simply has to be done.

Enter PixelCut

Last year, software maker PixelCut made a name for itself with the spectacular PaintCode, which created Objective-C from vector tools or SVG import. I’ve used it on every single iOS project since its release. It’s that good.

I was pleasantly surprised to see the announcement of WebCode, which is a sister product doing the same thing, only the output code is a web variation of SVG, JavaScript+Canvas and CSS.

The question was: Does this product live up the the other? The answer is YES.

Familiar UI and Drawing Tools

The UI is the same familiar one, and looks identical. The way it handles attributes like colors, shadows, and gradients is the same. The vector drawing tools, booleans, use of dynamic frames, again, all the same. If you know PaintCode, you already know WebCode. The difference is in the output.

WebCodeScreenshot

Output Code

Let’s face it, this is what you really care about. Does it do what it says it does, and is it usable and easy? Yes, it is. The sample files available on the site tell a great story, These are files of pure vector drawn goodness.

But I decided to do one of my favorite things, and pull in a complex vector tree SVG I’ve used in previous presentations. To my amazement, the SVG import (a simple drag-and-drop onto a blank canvas) worked! It’s an SVG, so I wanted to see what Canvas could do. The export was fantastic!

One note for those who use the HTML+CSS conversion, CSS does not support bezier curves. WebCode is very kind to let you know with the handy warnings drop-down just about the converted code.

The Samples

The sample downloads are wonderful. They are the basic drawings. However, the demo code that was added on the main page of the site is absolutely extraordinary. You must have a look at this stuff. It’s brilliant.

The Others

I’m not a big Inkscape fan, never will be. Yes, Adobe always has things going, I know, and I love that. They can all do SVG. But we have to look at here and now, and the pricing factor.

Conclusion

What can I say, they’ve done it again! If you are creating images for web, and they can be vector, like menu buttons, tabs, sliders, and icons, moving to vector is a major step forward in quality and performance. This is what HTML 5 is all about. (Sorry IE fans, you need more help than any of us can give you right now.)

WebCode is, without question, the best choice for easy JavaScript+Canvas and CSS drawing available today. At $49.99, WebCode is a bargain, and a real value I highly recommend it. You’d better buy one before the price goes up. It’s worth every penney.

I’m going to be presenting on this product soon, so stay tuned for more extensive info and samples.

Posted in CSS, HTML5, Mac, Technology

Adding Animations to WordPress with Adobe Edge Animate

ea_wpThis is really part one of more posts to come on Edge Animate and WordPress integration. Here is a link to the slides for tonight’s SLCAdobeUG meeting. It includes the vital links to get you up and running animating your WordPress site.

The first phase is to get animation going. The second phase will be to extend to responsive variations of animations. Stay tuned.

 

Posted in Adobe Tagged , , , ,

The Problem With iOS GitHub Component Examples Lately

blog-githubI’ve started to notice a disturbing trend lately, iOS Github examples that flat out don’t work nicely outside the example code.  Here are the typical problems:

  1. Non-ARC code
  2. No Storyboards
  3. Sample project megalomanic focus
  4. README.md inaccuracies and generalities

Non-ARC code

Seriously. Some people are not paying attention. If you have some C code flying around, great, that makes sense. But a plain vanilla component that doesn’t, where the sample code or component does it’s own (usually flawed) memory management, is just asking for trouble. Stop it.

No Storyboards

Again, not paying attention to what Apple is recommending and promoting. If you’re going to share, most developers, especially new ones, will be doing storyboard projects nowadays. Figuring out out how to get something out of a storyboard is a lot easier than how to get it in.

Sample project megalomanic focus

I actually resent having to deep dive into a spaghetti AppDelegate. It is common that the example is complex hyjinx designed to avoid ARC and storyboards. Is it so hard to show a real world implementation? I don’t think so. To offending developers: How many posts do you need to yourself and on StackOverflow asking for some rational context? Your component will be a part of an app, not the focus. Take a look:

When a real world sample is posted, with obvious and useful implementation, it’s great. It also makes you look like a complete jerk.

README.md inaccuracies and generalities

If you’ve run into one of the previous three, you are very likely to get this as a bonus. My favorite is the commentary of how you would generally do this in storyboards, which are pretty much always completely wrong. Many also stress compiler settings to turn off ARC compiling for the sacred component class. People really read this stuff, and follow your directions, in sone vain hope that they can get it to work. Don’t write about stuff you haven’t actually done.

The Point

These things waste time. When I’m trying to help someone, and they give me a link to a hot mess of a component, it makes me very cranky. When I see something cool I may want to experiment with myself, and I see this stuff, I want to ask what their problem is.

I’ve reached the point where I don’t remotely respect anyone’s code in these samples. 90% of it is just crap. (Steve Jobs would not hesitate to agree) I just dive into the real meat of the class alone. From there I can get down to the real essence, and see if it’s even a good idea what’s going on or not. That’s fine for me, because I can figure it out. So…

Why am I blogging about this? The newbies are attracted to these components like a moth to the flame, and they are left hanging, and give up. What a shame. It shouldn’t be that way. Here’s my message:

If you’re going to post components, and encourage people to use them, have the courtesy to make them usable!

 

Posted in Apple, iOS Tagged

PaintCode 1.2.1 – What’s New

PaintCodeUPDATE: Version 1.3 has just been released, with new features. My GitHub is working again, so you can pull the sample project.

I know I did a post and presentation at BYU CocoaHeads on PixelCut’s excellent PaintCode Mac app last spring, but a lot has been updated, and the new features are very exciting. I’m doing a revised version for SLC CocoaHeads tomorrow night, and I’ve posted the slides and source. Feel free, no license.

SVG Importing

This is huge. I’m a big fan of Adobe Illustrator, and nothing tops it for vector creation. Nothing. For those Inkscape fans, please put your hands (and mice) down about the cost and open source. Spare me. Thank you for your cooperation. PaintCode has some very good basic tools, especially for the typically vector-challenged iOS/OS X developer. These tools have gotten better. Illustrator is insanely great.

I’ll be showing how to take great vector content in Illustrator, export it to a PaintCode-friendly SVG. Simply drag the SVG onto the PaintCode icon or work area, and it just imports! Once it’s there, all the beliers are available for more editing (but probably only for frames). Below is beautiful Objective-C code for your Quartz drawing.

Frames

Frames are a way to create resizable vector objects where some areas are fixed, and do not scale. The action resembles the slice-9 techniques most commonly used in web programming. While my sample project uses code from frames, I have to say the PaintCode file sample and tutorial of a resizable bubble from the site is very cool.

Conclusion

As anyone can guess from my posts, I think vector is the smart way to go on graphics, where you can. There is nothing more annoying that seeing fuzzy, bloated raster pixels. Vector is the best shortcut to retina display goodness. For iOS/OS X development, PaintCode is an incredible tool. Try it, you’ll like it!

Posted in Adobe, iOS, Mac Tagged , , ,

Solution: Apple TV 3 and the spinner, plus the failure of AirPlay Screen Mirroring

apple_tv-q410-angled-lgI got an new Apple TV (3rd generation hockey puck), and I was watching a movie downloaded from iTunes. An hour and a half in, WHAMO, seized up. After going through reading an encyclopedia of posts, I took the extreme of shutting down my Macbook Pro AND my Apple TV. That worked for the next hour.

In addition, my Airplay screen mirroring did not work either. I have all new hardware, all new software….what gives? I had three clues: 1) 1 hour, 2) AirPlay mirroring never worked, 3) a router that gets hammered by the neighbors.

More reading, until I found a comment about connections and the ATV going to sleep.

So, I decided to go to the Apple TV Settings -> General, and changed Sleep After from 1 hour to Never. All of a sudden, restarting the movie went perfect, noticeably quicker. For fun, I tried AirPlay mirroring, and it also worked perfectly.

I’m not planning on leaving the Apple TV on all the time. I’m not saying this is a “fix.” I’m just posting that this was a simple solution that worked. If this fails me later, I’ll post again. Otherwise, if you find this post, and no update, give it a shot, it takes 10 seconds, no rebooting.

Posted in Apple Tagged , ,

Xcode – Renaming Repository Bug Using Git, Pull From Project

I’m using xCode 4.5.2, and was checking out some of my projects from Git, as I now have a new Retina Macbook Pro. I was beset by two problems.

When I went to check out a repository, the Folder names were right, but the name in the Organizer list was wrong. It picked a previous project name/repository name. Very frustrating, rebooting does not help.

I figured out a way to trick it, and got it to work. Here are the steps:

1) Go to the Organizer, and when you add, choose Add Repository

2) Now you do as you would the Checkout, only now you control the name.

3) Now you’ll have a repository with the right name, but no project. On the bottom left you can now do a Pull.

4) Once the Pull completes, Xcode make a new repository name, with the correct name this time. You can now just delete the generic repository if you’d like.

Note: I know some people just do the repository and start pulling, especially with the command line, and they don’t care if they pull every project down. That takes up a lot of disk space, so that’s why I’m pulling one repo/project set at a time.

My second issue was that committing only commits to the local Git, not the master. When in Organizer, there is no indicator to push. The only way I can get back to the master (as of this version) is to have the project open, and use the menus. File -> Source Control -> Commit and File -> Source Control -> Pull. That actually works.

I hope these things get tightened up in future version of Xcode.

 

Posted in Apple, iOS, Mac

iOS Tutorial: Editing TableViews

This tutorial picks up where our last tutorial on TableView Basics left off. Now that we have one, it’s time to start editing, deleting and moving things around. Again, we’ll have our starter project and our completed project downloads. For additional reading, you can check out the Apple guides on this.

First off, we can lose the button off the cell. Go to the storyboard and delete it. Move our label to the right a little bit, because we will need room for editing buttons later. Delete the button code we had in the delegate method in RootViewController.m:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath {UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];

UILabel *lblName = (UILabel *)[cell viewWithTag:100];

[lblName setText:[maTheData objectAtIndex: [indexPath row]]];

return cell;

}

 

Editing Mode

To do editing, you place the table view in editing mode, which is done through another UITableView delegate method:

– (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {[tableView setEditing:YES animated:YES];

}

 

Run the project, and select any row. You should see delete buttons for each row. We can try to delete all we want, but nothing will happen until we use another delegate method

Deleting

The default editing style of any cell is deleting, so we’ll start with that. Let’s add a new UITableView delegate method.

– (void)tableView: (UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath: (NSIndexPath *)indexPath {if (editingStyle == UITableViewCellEditingStyleDelete) {

// Delete the row from the data source

[maTheData removeObjectAtIndex:[indexPath row]];

// Delete row using the cool literal version of [NSArray arrayWithObject:indexPath]

[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

}

}

 

There are three important steps, identify the edit type, update the datasource array, then update the table view. Run the project, and delete away!

Inserting

Inserting is just doing the opposite, and of course, we need another delegate method. Alter RootViewController.m to the following:

– (UITableViewCellEditingStyle)tableView: (UITableView *)tableView editingStyleForRowAtIndexPath: (NSIndexPath *)indexPath {
// conditional for inserting
return UITableViewCellEditingStyleInsert;// conditional for deleting

//return UITableViewCellEditingStyleDelete;

}

 

– (void)tableView: (UITableView *)tableView commitEditingStyle: (UITableViewCellEditingStyle)editingStyle forRowAtIndexPath: (NSIndexPath *)indexPath

{

if (editingStyle == UITableViewCellEditingStyleDelete) {

// Delete the row from the data source

[maTheData removeObjectAtIndex:[indexPath row]];

// Delete row using the cool literal version of [NSArray arrayWithObject:indexPath]

[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

}

else if (editingStyle == UITableViewCellEditingStyleInsert) {

//

Insert something into the array, and you can just add a populated NSIndexPath of data or simplr reload data

[maTheData addObject:@”I’m a new item!”];

[tableView reloadData];

}

}

 

Run the project and start adding. Real world projects typical use an add button and some kind of modal to add whatever you want to add to the data. Usually it’s a simple append, or it may get resorted. The best use of UITableViewCellEditingStyleInsert is if you want to insert data in between two particular rows. The point here is just to show the insert edit mode in action. To change it back to delete, simply comment out the entire

editingStyleForRowAtIndexPath method.

Moving

Another typical editing type is moving data around the list to reorder the items. To enable moving, we’ll add two more UITableView delegate methods.  Here’s the code:

– (BOOL)tableView: (UITableView *)tableView canMoveRowAtIndexPath: (NSIndexPath *)indexPath {
return YES;}

 

First, we end up in edit mode by selecting the cell. The default for moving is NO, so we want to return YES instead. The moving of the items in the table view will happen on its own. However, we must update our datasource to show the reorder.

 

– (void)tableView: (UITableView *)tableView moveRowAtIndexPath: (NSIndexPath *)fromIndexPath toIndexPath: (NSIndexPath *)toIndexPath{
NSString *mover = [maTheData objectAtIndex:[fromIndexPath row]];[maTheData removeObjectAtIndex:[fromIndexPath row]];

[maTheData insertObject:mover atIndex:[toIndexPath row]];

 

[tableView setEditing:NO animated:YES];

 

}

 

Notice we get a copy of the data in our array being moved, delete the object from the array, and insert the copy back into the array. Again we take ourselves out of editing mode at the end of the move. It is common to instead just stay in an edit mode and do many steps and have a “Done” button to stop editing. This method usually has a table view reload. It’s your choice. In our example, if you want to see the data changes, simply put a breakpoint in the

moveRowAtIndexPath method and observe the array.

Run the project. Once a cell is selected, the cell will show the drag handle on the far right of the cell. Hold this handle, and in a moment it will pop up slightly.

Conclusion

In order to edit a table view, simply put the table in editing mode. Then use the appropriate combination or UITableView delegate methods to control the editing.

Posted in Apple, iOS

iOS Tutorial: Basics of Table Views and Prototype Cells in Storyboards

In this tutorial, we’ll go over the basics of populating tableviews with data, and using the prototype cells introduced in iOS 5. Many of the samples online have very complicated navigation controller code. Instead, we want to just do the very basics of a UITableView and UITableViewCell. No nav bar, no master/detail navigation. We’re also not going to try to tackle Core Data here. We’re also not worried about saving our changes. We’re just trying to understand tables and cells.

First, we have two projects to download, the starter project, and the completed project. In the starter project, we’ve made a new project, added a Table View Controller in our storyboard, and deleted the View Controller. We also have deleted the ViewController.h/.m set that is made automatically, and created a new file, calling it RootViewController, which is a UITableViewController. We’ve also hooked this new file set to our Table View Controller in our storyboard.

Becoming a Delegate

The first step is to work with the UITableViewController, so that when the table view is being created, we populate it with data. We also want to keep the data in sync with what’s in the table. This means we sign up for two protocols in RootViewController.h:

@interface RootViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>

 

Creating Data

For this tutorial, we’re just going to use an array. In a real project, it’s typical that you would connect to a web service and grab a data structure, like XML or JSON. Declare an array in RootViewController.h:

@property (strong, nonatomic) NSMutableArray *maTheData;

 

Now let’s implement it in RootViewController.m, we’ll synthesis our array, and build it when we load:

@implementation RootViewController@synthesize maTheData;

– (void)viewDidLoad
{
[super viewDidLoad];
if (!maTheData) {
maTheData = [[NSMutableArray alloc] initWithObjects:@”Comets”, @”Asteroids”, @”Moons”, nil];
}
}

 

Implementing Table View Delegate Methods

Now we have some work to do to populate our table. The way we do this is by setting data at different parts of the table as it is built row by row. First, we need to identify the number of sections the table needs. If this is zero, nothing will ever appear. In our case, it’s just one.

– (NSInteger)numberOfSectionsInTableView: (UITableView *)tableView
{
return 1;
}

 

Next, we need to identify the number of rows we need in the section, which is the number of items in the array.

– (NSInteger)tableView: (UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
return [maTheData count];
}

 

Storyboard Connections

Time to go to the storyboard, and select the Table View. Ctrl-drag back to the RootViewController. We want to connect it back to the controller to ensure both the delegate AND the datasource are connected to the controller class. This ensures the delegate calls will fire, and the data will we synced. If you skip this step, you won’t see anything in your cells.

Prototype Cells

Cell designs that are reused, are very performant, as opposed to cells that are completely different, row to row. Many apps use the standard cell types, basic, right detail, left detail, subtitle. But you may have an app with custom cells with more information or purpose. This is where prototype cells have make the process a lot easier than in the past. Prototype cells in a storyboard allow you to create custom cells quickly. Just drag the components you want on your cell.

It is incredibly important to set your identifier for the cells, because when you get to the delegate methods, you need to indicate the cells’ class. This provides the access to put the data on the cell itself. From the storyboard, select the one table view cell, which is a child of the table view, and go to the Attributes Inspector. Under Identifier, type “tvcItems”.

Select the cell, still in the Attributes Inspector. The first item is Style. Choose Basic. Now the cell has a label that’s been added automatically. Farther down in the view section is Tag, type “100.” The number does not matter, a much as the fact that each object on the cell should have a unique tag. If you don’t use the tag, the data will not appear later.

Populating Cells

Using the combination of the cell identifier and the tag, we will have full access to deliver the data to the cell. Back to RootViewController.m, add:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];
UILabel *lblName = (UILabel *)[cell viewWithTag:100];
[lblName setText:[maTheData objectAtIndex:[indexPath row]]];
return cell;
}

 

Run the project in the simulator, and you should see a simple table view with our array data.

Custom Cells

Whether you use one of the custom table view cell style types or go custom, the process is the same. However, with custom, you must drag all the objects you want on the cell manually. Go to the storyboard and select the cell. Change the style to Custom. The first thing you’ll notice is our label is gone. Grab one and drag it onto the cell, and set its Tag to 100. Now grab a Round Rect Button and drag it onto the cell, and set it’s Tag to 200. The Tag is in the View section, so you will have to scroll down a bit to find it, but it’s there. You may want to manually make them wider, so the text will fit easily.

Now go back to RootViewController.m, and add to the cellForRowAtIndexPath method to:

– (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”tvcItems”];
UILabel *lblName = (UILabel *)[cell viewWithTag:100];
[lblName setText:[maTheData objectAtIndex:[indexPath row]]];
UIButton *btnName = (UIButton *)[cell viewWithTag:200];
[btnName setTitle:[maTheData objectAtIndex:[indexPath row]] forState:UIControlStateNormal];
return cell;
}

 

Run it again in the simulator, and the buttons should have the same text from the array. While this may not seem terribly useful, it shows the basics of customization. A real project would typically have complex sets of data, including images and multiple labels. For each object type, drag it, tag it, make a local method variable of the object type, and set the data to it.

Conclusion

The addition of storyboards and prototype cells has made the old way of populating tables much easier than before. The process is to become a delegate, have some data available, set the delegate and datasource from the table to the controller, set the identifier for the cell, set the tags of the cell objects, and implement the delegate methods.

Posted in iOS

iOS Tutorial: Combining Delegation, Storyboards, Popovers and Data

In this tutorial, we’ll show how to pass data from a view controller to a popover, and have data passed passed back from a button click, as well as dismissing the popover. The benefit is that it allows you to programmatically save or alter data, and pass it back. This is in contrast to a popover being dismissed by merely tapping outside the popover area of the screen. These are typical elements that would be used together for an iPad or Universal project. Since popovers are not available to iPhone (as of iOS 6 anyway), this would be used with an iPad storyboard.

I’ve posted the project files for starting, and the completed final.

Starting Point

The project starts with an iPad storyboard. The initial view controller is a UIViewController called RootViewController. It already has connected IBOutlets for a UITextField and a UIButton. There is a another UIViewController called PopViewController, which is the popover. A segue has been created from the button in the RootViewController to PopViewController. There is a UITextField and a UIButton on the popover to send back to the root, which are connected outlets. The view controller class files have been created and connected in the storyboard.

Segue Identifiers

It’s important to always give a name to your segues, as it is common for one view controller to have multiple segues. When doing segue delegation, you want to manage which segue, and differentiate which code goes with what segue. In the storyboard, select your segue, and go to the Attributes Inspector. Name the segue “segPop.”

Setting IBActions

The first thing we want to do is create IBActions for the buttons. In PopViewController.h, add a new function at the bottom.

@property (strong, nonatomic) IBOutlet UITextField *tfNewData;

– (IBAction)goBack: (id)sender;

@end

In PopViewController.m, we want to add the implementation of the function.

– (IBAction)goBack: (id)sender {

}

@end

 

 

Now connect the button click to the IBAction. One way to do this is to go to the storyboard, select the button in the Document outline, and ctrl-drag to Pop View Controller. Select the inaction goBack.

You can always go to the Connections Inspector to see (or set) your connections.

Delegation

Delegation is a programming pattern that allows an object to work in coordination with another object. A delegate will receive event messages, or callbacks, from the delegating object. Using delegation is so common in iOS development, that understanding it is a requirement.

Creating a Protocol

In order to do a delegate callback function, you need to establish a protocol, which will outline what callbacks are available. In PopViewController.h, add some protocol lines.

#import <UIKit/UIKit.h>@protocol PopViewControllerDelegate;    // Declare a protocol name

@interface PopViewController : UIViewController

@end

@protocol PopViewControllerDelegate <NSObject>

@required

– (void)dismissPop: (NSString *)value;

@end

 

It is good practice to name your delegate as “<classname>Delegate”, making it easy to understand to code. In protocols, methods can be required or optional. If your class implements a delegate protocol, and does not include a method to handle the callback, Xcode will give a warning that the implementation is incomplete.

Creating a Local Delegate

The calling object needs to set itself as the delegate in the delegation relationship. We’ll establish a property to hold this. Back to PopViewController.h:

@property (weak) id <PopViewControllerDelegate> delegate;

 

The property is set to a weak reference, for ARC compliance, and good memory management. Because this property stores a reference from a different class instance, if t gets destroyed somewhere else, this instance can free the memory. Make sure to synthesize any properties you add, so in PopViewController.m:

@synthesize delegate;

 

Sending a Delegate Method

Now that we have a property to store the delegate, we can add the code to send a delegate event. We’ll do that in our IBAction of the button in the popover. Add a line to our goBack function in PopViewController.m:

– (IBAction)goBack: (id)sender {

[delegate dismissPop:[tfNewData text]];  // make delegate callback here

}

 

This code is going to take the text of our UITextField and send it back to the delegate, which is our RootViewController. Remember that delegate is an id, or pointer, back to the RootViewController instance. This tells us where to send the delegate message.

Preparing for Incoming Data

In order to prepare to receive data from RootViewController, we want to add a string property to receive the data, as the segue will not have direct access to the UITextField. In PopViewController.h, add the following:

@property (strong, nonatomic) NSString *strPassedValue;

 

Make sure to synthesize in PopViewController.m:

@synthesize strPassedValue;

 

Since PopViewController is a UIViewController, it is automatically able to do its own delegate methods. We want to add one to PopViewController.m:

– (void)viewWillAppear: (BOOL)animated {
[tfNewData setText:strPassedValue];
}

 

Becoming a Delegate

Go to RootViewController.h, and add the following:

#import “PopViewController.h”   // add header to gain access to its protocol
@interface RootViewController : UIViewController <PopViewControllerDelegate, UIPopoverControllerDelegate>

 

First, you must import the header file, which is how to reach the delegate protocol. This will help code completion make this easy. We want to be sign up for two delegate protocols. The second one is so we can receive callback messages from the popover. Second, we have an implementation in RootViewController.m to receive the callback:

– (void)dismissPop: (NSString *)value {

[tfUserText setText:value]; // populates data from popover

}

 

This function allows us to capture and display the data string sent back from the popover via delegation.

Managing the Popover

We want to be able to send data to our popover, as well as be able to programmatically close our popover, so in RootViewController.h, add some properties:

@property (strong, nonatomic) UIStoryboardPopoverSegue *currentPopoverSegue;
@property (strong, nonatomic) PopViewController *pvc;

 

Synthesize them in our implementation RootViewController.m:

@synthesize currentPopoverSegue;
@synthesize pvc;

 

Passing Data in a Segue

Since we signed up for the popover delegate protocol, we want to implement the prepareForSegue function. Add the lines:

-(void)prepareForSegue: (UIStoryboardSegue *)segue sender: (id)sender {
if ([[segue identifier] isEqualToString:@”segPop”]) {
currentPopoverSegue = (UIStoryboardPopoverSegue *)segue;
pvc = [segue destinationViewController];
[pvc setDelegate:self];
[pvc setStrPassedValue:[tfUserText text]];}

}

 

In this code, we are looking to make sure that we have the proper segue, which is why we set its identifier property in the storyboard. Next, we want to keep a pointer to the popover segue, so we can dismiss it after we have processed the delegate callback data. We also want a pointer to the view controller that is the popover, because we set ourselves as the delegate. Without setting the delegate, the delegate callbacks would go nowhere. Lastly, we want to pass data into the PopViewController,which allows us a round trip of data back and forth from both objects.

Dismissing the Popover

As the final step, we want to add a line of code to our delegate callback function in RootViewController.m:

– (void)dismissPop: (NSString *)value {
[tfUserText setText:value]; // populates data from popover
[[currentPopoverSegue popoverController] dismissPopoverAnimated: YES]; // dismiss the popover
}

 

The final line uses our pointer to the segue, so we can have the popoverController dismiss or popover instance. Notice we do not send anything to the PopViewController instance. When we created a segue that was of type popover, a popoverController was automatically created for us, and that is what want to access to do the actual dismissing.

Using Data Passed via Segue

Now that we have data coming across the segue, we want to use it in our popover. In PopViewController.h, we want to add  In PopViewController.m, add the following UIViewController delegate function:

– (void)viewWillAppear: (BOOL)animated {
[tfNewData setText:strPassedValue];
}

 

Conclusion

Run the project in the iPad Simulator, and you should be able to pass data back and forth between the text fields. The button on the popover should also dismiss the popover. Okay that was a lot of steps, but you can pass data from segues, delegate callbacks, and control your popovers, all at the same time.

Posted in Apple, iOS