Saving a UIView for next launch (not as an image) - iphone

I am building an app with several UIViews which are generated dynamically, based on user inputs. These UIViews may contain labels, images and text. They take some time to generate so I would like the user to be able to load them up quickly on future launches of the app without having to redraw them again. One requirement is that they need to keep their interactive state so the user can continue to edit them.
I looked into NSKeyedArchiver but this doesn't seem to support UIImage. Also, I can't save it as PNG since I would like to retain their interactive state.
Is there any way to do this?

You should consider keeping the model of your data separate from the interface. You can then use this stored model to generate the interface. I know you specifically said that you don't want to do this. However, any built in method is going to have to rebuild the UIViews in exactly the same way.
If the processing of the model data is the issue, try to come up with a way to efficiently represent the state of the interface so that you don't have to start from scratch. However, that will be a lot more work.

Related

How to deal with the layouts of presentable images?

A presentable image starts out in VK_IMAGE_LAYOUT_UNDEFINED but will be VK_IMAGE_LAYOUT_PRESENT_SRC_KHR after they have been presented once.
A lot of examples do a transition of all vkImages to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR immediately after creating the vkSwapchain. Which allows them to use an VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for oldLayout. But doing the transition right after creation of the swapchain is not allowed.
Use of a presentable image must occur only after the image is returned by vkAcquireNextImageKHR, and before it is presented by vkQueuePresentKHR. This includes transitioning the image layout and rendering commands.
What are my options to deal with the swapchain image layouts correctly?
There are 3 options. Ordered from best to worst (IMO):
Simply set the initialLayout of the attachment in the renderPass to VK_IMAGE_LAYOUT_UNDEFINED or transition from VK_IMAGE_LAYOUT_UNDEFINED every time. This is allowed and will imply that you don't care about the data still in the image. Most often you will be clearing or fully overwriting the image anyway.
valid Usage [of VkImageMemoryBarrier]
[...]
oldLayout must be VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PREINITIALIZED or the current layout of the image region affected by the barrier
Keep track of which images have been through the pipeline already and select the oldLayout accordingly when recording the commandBuffer.
Do the transitions after creating the swapchain but using vkAcquireNextImageKHR and vkQueuePresentKHR to ensure the application owns the image while transitioning. There is no guarantee in which order you get the images So it may be possible one image never gets returned.
I've been trying a fourth option but some input on its validity would be useful. When creating the swapchain the images are in VK_IMAGE_LAYOUT_UNDEFINED, which to me seems to indicate that they're all available to the application because they need VK_IMAGE_LAYOUT_PRESENT_SRC_KHR for presentation and so shouldn't be displayed or in queue. I didn't find anything in the spec that would guarantee this however.
The spec says that we can acquire multiple images from the swapchain if we want:
If a swapchain has enough presentable images, applications can acquire multiple images without an intervening vkQueuePresentKHR. Applications can present images in a different order than the order in which they were acquired.
Using the conclusion above I just called vkAcquireNextImageKHR to get every image of the swapchain and changed layout on all of them at once. After that I presented all of them to get them into the system so to speak.
It seems to work in the sense that all images are handed to me by the swapchain, but then again, I found no guarantee that all of them can actually be acquired immediately after creating the swapchain.

Choosing between the two - Interface Builder OR creating via code

When I started with IPhone development I preferred using Interface builder for creating views in my application. With time I considered the option of creating the application via code which I really feel comfortable working with.
Now, when I know both ways to create my user interface, I have doubts which way to follow. I keep thinking where to use IB and where to use code. How can I figure out before starting with my application, which way should I create my UI?
There are a number of factors that can influence your choice. It can come down to personal taste, but there are some advantages to using Interface Builder.
The first thing to recognize is that UI design is inherently a visual task. Interface Builder can allow you to create and modify a UI much faster than you can in code. Rather than endlessly tweaking CGRect values in code, then recompiling, testing, and repeating this process, you can instead get direct visual feedback about your changes. This means you can refine and polish the UI much more efficiently, and even test out radically different layouts without too much time or effort.
Another important point is that if you can create and layout a control in Interface Builder, that means there is less code in your view controller. Less code is always a good thing (less bugs, easier to maintain, ...).
So I believe you should try to define as much of the layout and properties in Interface Builder as you can. This can be hard for people who prefer "full control" over things. Many years ago, visual GUI editors were renowned for doing the wrong thing, and developers often shunned their use over doing everything by hand. But Interface Builder is pretty good at what it does, and you can easily dive into code when you need to.
The situations where you would create controls purely in code are when you need to dynamically create a number of objects, for example thumbnail buttons for a photo gallery, or if you have custom layout requirements.
For example, if you have a label whose height is dynamic at runtime, and you want to layout a bunch of controls underneath it (taking its height into consideration), that can only be done in code (UPDATE: iOS 6's Auto-layout can do this now). You can either create and layout everything in code, or you can still create the controls using Interface Builder and just give them arbitrary positions in the XIB which are modified when you lay them out in code. It's not uncommon to see this in some of my XIBs:
The buttons along the top can be created and layed out fully in IB, but the image views below need their images and positions to be calculated at runtime. So we just give them arbitrary positions in the XIB. Some might find this ugly, but it saves time and effort on writing code to create the image views and set up their properties. Again, less code is a good thing.
Other times you may want to use code is setting certain explicit properties. Let's say you have an image view which needs to receive touch events because it has some gesture recognizers added to it. You need to set the "User Interaction Enabled" property to TRUE. It can be better to do this in code because the requirement is more visible and you can leave appropriate comments as to why you are setting the property. It's also harder to 'lose' the setting like you can in interface builder if you need to delete and recreate a bunch of views.
I think for many applications that use the stock UI, Interface Builder is a great tool to rapidly get things up and linked with the underlying code. Also, it really stresses the paradigm of the View being separated from the Controller as you really can't push code into places where it shouldn't be.
That being said, I use it less and less the more I learn about how to rapidly code interfaces due to the fact that they may need to be more flexible or need a variable number of UI elements based on the Model behind it.
Use interface builder as per your requirement. It's depend on you that how you manage things. See creating a custom cell using interface builder is much easier to update at a later stage while using code you have to do a lot of changes if layout changes. Also you can visualize the view before running the actual app but in code you cannot you just have to assume.There are both prons and cons of both things.

What's the best way of building an app to display two lists in a single UITableView (switching between datasets)

I'm relatively new to iOS development and am just wanting a few pointers as to what will be the best way to go about doing this. I am building an app with a tab bar and one of those tabs will be a table view at the top of which is a segmented control with two buttons allowing you to swap between datasets.
The first question I have is:
The data is relatively simple but there are about 6000 records would it be best to use a simple NSDictionary as the data source or should I look into using Core Data. Users of the app will simply be able to select a record to add it to a favourites list, or deselect it.
Secondly:
Should I use two different view controllers and swap them in and out depending on which option is selected or should I use a single view controller and swap the data in that class to populate the table.
I'm a registered Apple Dev so I have access to their examples but often can find them difficult to follow, any pointers to resources/tutorials would be VERY appreciated.
First off, for anything nontrivial always consider Core Data - in your case especially so. A 6000-object dictionary can easily get unwieldy to manage.
As for the view controllers, I believe the canonical thing to do is to use a single table view controller (since you remain on a single UITabBarController tab), but change out its data source, or just change the data returned from that source.
If you need it to look reasonably smooth, you can play with the built-in UITableView animation methods - I believe the AP application changed out its news stories by animating out all the old ones and animating in all the new ones within a single table view, so the effect was of a complete dataset change but without the extra view controller.
Generally I've found the Apple examples and tutorials to be the best available, but there's no substitute for just building apps and playing around with the technologies yourself - if you don't understand an example, try to reimplement it yourself and see what's giving you trouble. If you're truly stuck on something, come back and ask another question!
First question:
If your dataset is fairly simple, I would recommend sticking with an array of dictionaries; or, if order is well-defined, and each row has a meaningful unique key, simply use a dictionary.
There's a complexity tradeoff involved in using a large framework like Core Data, and until you have—for instance—relationships expressed in your object model, I don't think the tradeoff is worth taking.
That said, there are performance issues to take into account when making these kinds of decisions. You have 6,000 records, but is each just a key and a value? That wouldn't be such a big deal. But if you have a number of columns, and sorting is an issue, Core Data's SQLite backend would help you out a great deal.
If the array or dictionary is filled with standard Foundation data types, you'd get serialization for free, since all of them implement NSCoding.
Second question:
Read through Apple's article on the model-view-controller design paradigm. The thing to note about what you're trying to do here is that since you're only looking to vary your data, only your model should be changing.
UITableView is designed to make that easy. It's a view, so it doesn't store its data, but it has a dataSource property which it queries to display information. So when your user switches datasets, simply switch your table view's data source.

Easy way to build an in-app demo like they do in Convertbot?

I want to make a little in-app demo like Tapbots does in Convertbot. Maybe there is a better solution than mine?
make everything programmatically controlable
write a huge class with hundreds of performSelector:withObject:afterDelay: calls to control the whole app for the demo
The demo actually only does two things:
Simulate touches on controls (i.e. programmatically pressing buttons)
Show text message bubbles when appropriate to explain what is going on
How would you do it?
I don't think there is an easy way to accomplish this.
My suggestion would be to create a class that runs a script of actions for you. The script itself could be as simple as an NSArray of objects representing steps in the demo, each with values such as text for a callout bubble, an action/target pairing (for calling selectors), delay, and so forth. Use NSButton setHighlighted: to simulate button presses. Your class then runs through the array of steps to conduct the demo. You could code this directly, or construct the script at runtime from a YAML file (or other file format that you find easy to edit).
I would expect that investing some time in a mechanism like this will make your life a lot easier when it comes time to a) write and b) fine tune your demo, particularly down the road when you want to add features. You don't want to be managing a huge list of hardcoded calls. And you might even be able to re-use the demo-running code on other projects.

Very basic question about the structure of my iPhone game

I'm making an iPhone game in which I have two main views, the planning stage and the action stage. Both of these will have different graphics etc, but I'll obviously need to pass information between them. I've pretty much finished programming the planning stage, and I know how to switch between views, but I'm a little fuzzy on how exactly I should be setting the whole thing up. Should my SwitchViewController, which handles the switching between the two views, also control the passing of the game state and the game moves between the two views? Or is there a better way to do this? Thanks for reading!
It would probably make sense to package all your game information up into a single 'gameState' object, and attach that to your app delegate (or some other 'non transient' object).
If you pass it all back and forth, you can run into problems if you ever change your flow, or add a variable and forget to pass it. This approach avoids both those issues.
I would suggest setting up a sharedInstance which will allow you to use data between the two screens.