I have 1 main Master screen (MVC) and 4 other screens that share ~80% of graphic objects. They differ in some label texts, a button with action and some other 20% graphics. Thinking in terms of clean object oriented code architecture, I have started to implement those screens as separate UIViewControllers. But I didn't like having pointers to those 4 MVCs and a duplication of some methods, so I rewrited the code into one UIViewController. Most of graphic objects are UIImageViews that I put on with Interface Builder. So, now the xib file of that "unified" UIViewController is a little bit bloated with overlapping objects from those 4 screens. I also need to have those methods like showScreen1, hideScreen2, showScreen2, hideScreen2, and other methods, so I'm not very happy with this architecture too. I understand that I should not mix those 4 MVCs (screens) and both the code, and xib files would be cleaner but I'm also thing about performance, saving memory loads and etc. What would be your opinions on that? How much memory resources takes the loading of separate UIViewController? Maybe the amount of saved memory is not worth when compared to code cleanness? Again, having 4 separate MVC's would force me to have 4 pointers both to my Master MVCs and 4 pointers to those separate MVCs from my Master MVC, because I need to communicate and navigate between those screens. Another option would to use notifications instead of pointers but it doesn't change the amount of required relations. So please share your thoughts and insights :)
For user interface controls that share the same design perhaps you could use categories, this is what I'm doing in a project. I've added a category to UINavigationBar to show a texture on the bar, added a category to UIBarButtonItem / UIButton for a back & cancel button and since my ViewControllers all share the same background image I've created a UIViewController subclass that contains the default background image - every view controller used in my app inherits from this default view controller.
I would stick with 1 view controller per screen.
Apple doesn't recommend creating giant nibs, this is especially visible in the WWDC 2011 video on storyboarding (check this video out if you're a registered Apple developer). Giant nibs are bad in terms of performance, it takes a lot of time to load all objects and all the objects from the nib stay in memory all the time, even if the objects are on a screen that's currently not being displayed. It's a better approach to have a separate nib per screen.
Related
I am using xib-s for my UITableViewCells on iPhone. Now I need to convert my app to universal app. Do I have to create new xib-s (looking exactly the same way) for the iPad version? My current problem is that I am using grouped UITableViews. As the left and right margins on both devices differ, some of the controls on iPad are partly "out of the cells".
In case I need new xib-s (looking exactly the same way), do I need separate properties for the controls in the ViewController? For example, for a label named myLabel, do I need a second property myLabelIpad or is there a better way to handle that?
Cheers
My suggestion is to create new xib. But if there are small changes , then you can maintain one xib. However it depends on how different your iPhone / iPad versions are. For example, if the iPad version is just a bigger version of the iPhone one with a few extra buttons, etc, it's easier to use one UIView and just set the frames of the subviews appropriately.
First understand what you are up to. How do you want your iPad app to look like? How does it navigate. Ceratinly you want to leverage from the lager screen of the ipad. When ever you do that and the auto-resizing mechanism is not sufficient (which it rarely is) then go for a separated xib file.
Second - for each XIB which hosts the same number and types of UIView and UIConrol subclasses, you should be able to use the same view controller for two separate XIBs. Just link all conrols within both XIB to the related IBOutlet properties and IBAction methods alike.
However, when you take leveraging from iPad capabilites seriously then you are like to end up with a different set of view controllers. That is when you can combine the controls of several iPad views wihin one single iPad view and similar cases.
Nevertheless, think of using popups. The content of a popup could nicely correlate to what is a full screen on the iPhone. In that case you can use the same view controller again within that popup container.
Does this sort of answer your question? If not, then please be more specific.
Actually you can retain the same Table cell xib files. You just have to get the Auto resizing masks of the cell and its subviews right.
With the introduction of storyboard, I wouldn't select to create a .xib/.nib when I create a subclass of UIViewController, because I can just drag out a viewcontroller in interface builder and assign it to the new class.
So, with storyboard, when would i need to use the .xib/.nib file?
Thank you.
Storyboards don't completely remove the need for NIB files. One common example is when creating subviews to go inside a UIScrollView. You can't create the subviews separately in a storyboard; instead you have to create separate NIB(s) for the subviews and attach them to the scroll view programatically.
In fact, on almost any occasion where you have a need for subviews which change at runtime you'll want to use separate NIBs.
Storyboards are great for certain kinds of apps, but for anything even remotely complicated the old way works very well still. An additional benefit is that they co-exist nicely. You can put placeholder views in your storyboard and fill them programatically with NIB-defined views later on.
I guess, storyboard contains the .xib/.nib files for all your views. It present relationships between them and helps you to avoid confusion if you have a LOT of views. Also it saves your time and nerves when writing code.
I have tried out storyboarding lately and I do have mixed feelings about its use:
Pro's
Convenience: You might have to write much less code. So you can for example show a static view without having to write any code.
Overview: You can quickly see how the ViewControllers relate to each other
Efficiency: For the simple use cases I find the Storyboarding much more efficient than "the old way".
Example 1: Editor > Embed In > Navigation Controller and voilà, no more instantiating and configuring is required.
Example 2: You can make "Prototype Cells" for TableView which speeds up the creation of static table views dramatically. AFAIK this is not possible with nib files
It's cool :-)
Con's
I find that the re-usability somehow suffers with storyboards. Although I can segue to a given ViewController from multiple points, it is still limited since in one case I might use the VC as a Popover and in another as a Master-ViewController.
Assuming that you are working in a big team and different people are changing different parts of your application, having one monolithic storyboard which you then have to merge might pose a big problem team-work-wise.
I really would like to have some mechanism to include or reference existing nib files into the storyboard which is currently not possible.
So considering these points I still find storyboarding very appealing but it makes sense to combine both approaches which is not really a big deal. Additionally, this technology it is still quite new so it might improve in the (near) future.
If you use storyboards, you generally won't need to create separate .xib files. You can still use a .xib file if you want to -- it might be useful e.g. if you have a particularly complex view that you'd like to configure by itself. Most of the time, though, there won't be a need to do that.
I have written a little PDF viewer which is supposed to show PDFs page by page to reduce memory usage.
It consists of a PdfViewController which shows a specific page of the PDF (using UIScrollView, CATiledLayer).
Now the (maybe stupid) question is: if I want to show the next page (using a swipe gesture ot whatever), how would I do that? Should my controller handle it and update its views (which is a horror becaue CATiledLayer seems to crash as soon as you look at it :-)), or should there be an "outer" controller which generates a new PdfViewController for every page flip (the more flexible aproach)?
What is the best practice in these situations? Looking at UINavigationController, you're supposed to push a new UIViewController for every level. But there, all controllers being pushed may be different. In my case, all pages are using the same controller.
You likely shouldn't use the UINavigationController for that. In general, the UINavController should be used for drill-down operations, where you have a limited set of items to be pushed.
In your case, I think the best option is to use a large UIScrollView which will take care of the pagination and then just create a new UIView with the CATiledlayer inside.
I created for my app Quicklytics a PagedViewController class that does most of that for you. You basically create a PageDataSource that creates the UIViews for each page, and handle it over to the control. You may not use this exactly as is on your code, but it'll give you a good idea on where to go:
https://github.com/escoz/monotouch-controls/blob/master/UICatalog/PagedViewController.cs
Hope this helps you.
Here are two useful resources
Fast and Lean PDF Viewer for iPhone / iPad / iOs - tips and hints? collects a whole lot of information on displaying pdfs.
https://github.com/vfr/Reader a basic pdf reader for ios that does what you are trying to do.
In terms of whether to use nested UIViewControllers I would recommend against it, however if you do you should be aware that they will not handle rotation very well (I don't think they receive orientation change events) as well as viewDidAppear and other view lifecycle events, also make sure only to display modal view controllers from the root view controller otherwise they won't show properly (I had issues with them appearing in the wrong orientation in landscape, or in the wrong position).
In the app I built I used one UIViewController to manage the display of the pdf and I subclassed NSObject for any other "sub" controllers to make it more manageable. For example I had vertical scrolling as well as horizontal scrolling of pdf pages. My first attempt used nested UIViewControllers however I had issues with orientation till I rebuilt using controllers subclassed from NSObject for managing vertical slides.
I want to have one iPad screen with multiple independent sections that can be dragged by the users finger.
Each section will have different objects like UIButton, UILabel, UIImage, etc. When the section is dragged, all of the associated objects in that section will moved with it as a group.
Therefore I was thinking each section could be a UIView or a UIViewController.
The whole thing should be under one UIViewController type (navigation etc).
I been trying different things but nothing works fully, only pieces of it works. I tried using different UIViews, and loading nibs into that, but then the buttons don't respond to touches.
Anybody got any ideas?
As per Apple's Review Policy:
https://developer.apple.com/appstore/resources/approval/guidelines.html
Apps that create alternate
desktop/home screen environments or
simulate multi-app widget experiences
will be rejected.
I would recommend rethinking your design (not trying to be rude !!)
I have an idea about an application that I want to build and Im new to iPhone/iPad development (but not new to development in other languages/frameworks such as .NET and Java). I want to layout some views on the screen so that they animate (slide in) from different directions into their places.
The question is about the strucuture of the application, if I have say 4 rectanglular areas on the screen that contain business data, such as contacts (name, photo, etc...) and they all take up different widths of the screen (say the first contact takes up one row of the screen, but the next 2 take up half the width of the next row each, and so on).
Should I create a custom view for the different sized contact views, (i.e. LargeCustomView and SmallCustomView, and any other special type that I make) or should it all be one type, say, CustomerDetailsView which could be stretched to fit at design time?
Also, if there were, say, 3 different instances of the same custom view on the one screen, are there 3 instances of the view controller also? Im a little confused about powering the data behind a view, can someone shed some light on this for me? Do I just set the properties (say an instance variable ContactForView) on the view controller for each instance?
Thanks for any help you can give
Cheers,
Mark
Should I create a custom view for the different sized contact views, (i.e. LargeCustomView and SmallCustomView, and any other special type that I make) or should it all be one type, say, CustomerDetailsView which could be stretched to fit at design time?
I think only you can answer that question. If UIView autoresizing masks are enough to accomondate both layouts, you should probably go for just one class. If that's not enough, you can either override layoutSubviews to account for different sizes or perhaps go with a common superclass to contain the logic and two subclasses to do the different layouts.
Also, if there were, say, 3 different instances of the same custom view on the one screen, are there 3 instances of the view controller also?
Because of the way UIViewControllers work, Apple generally recommends not having more than one view controller per screen. From the docs:
You should not use view controllers to manage views that fill only a part of their window—that is, only part of the area defined by the application content rectangle. If you want to have an interface composed of several smaller views, embed them all in a single root view and manage that view with your view controller.
Otherwise, things like device rotation can get tricky as a view controller that is not full screen should probably react differently to such events and Apple's UIViewController is not written to do that. However, nobody stops you from writing your own view controllers (derived from NSObject, not from UIViewController) so that's what I would recommend: if the view is quite complex, write a custom controller class for it but stick to one UIViewController per screen.