Dynamic number of pages in Watchkit Page Navigation - swift

Is there any way dynamically create pages in a page-based navigation? In every example I read, the pages were created as Interface Controllers and linked in the Storyboard.

Here is the way to do it
WKInterfaceController.reloadRootControllersWithNames(["pageController", "pageController"], contexts: ["pageController", "pageController"])

To avoid infinite loop use:
static BOOL first = YES;
- (void)willActivate {
// This method is called when watch view controller is about to be visible to user
[super willActivate];
if (first) {
[WKInterfaceController reloadRootControllersWithNames:[NSArray arrayWithObjects:#"SinglePageICIdentifier",#"SinglePageICIdentifier", nil] contexts:[NSArray arrayWithObjects:#"First",#"Second", nil]];
first = NO;
}
}

I presumed you want to display several page of the same kind of data.
Apple Watch Programming Guide states the following:
This style is suited for apps with simple data models where the data on each page is not closely related to the data on any other page.
Therefore, I think you should stick to table views to display several items that are closely related (by kind) to each other. From my point of view, page-based controller navigation (swipe) is too slow / boring to be used for lots of pages. Also, I think it could take a lot of time to load the page-based controller.

Related

How to get/set the rootViewController?

Now,I gonna Develop an App ,which wants to switch from many different Views irregularly,also the views need to load large resources,AKA,it's hard to manage memory.Are there any good solustion?
PS:I created a ViewController as RootViewController,and When a button was Touch,run the code as
"ViewController=newController"
.The problem came,The new View loaded wrong way,it rotate so that couldn't show in a correct way.
I google for the solution,some one said ,I should replace the rootViewController,just like that,
[UIApplication sharedApplication].delegate.window.rootViewController=newController;
But I can't get/set the rootViewController in other class though it's a singleton.
Why not having a class that handles all the view switches ?
This article describes an architecture that might be helpfull: http://www.mikeziray.com/2010/01/27/handling-your-initial-view-controllers-for-iphone/comment-page-1/#comment-607

iPhone App Dev - Loading View From View Controller

I have a questionnaire viewcontroller class. This instantiates several questionviewcontrollers (each questionviewcontroller has an associated view).
How do I get the questionnaire to load these question views associated with their questionviewcontrollers....
EDIT:
-(void) setQuestions{
for (NSDictionary *q in self.questions) {
/* Create our Question object and populate it */
QuestionViewController *question = [[QuestionViewController alloc]init];
[question setQuestionId:[q objectForKey:#"questionId"] withTitle:[q objectForKey:#"question"] number:[q objectForKey:#"questionNumber"] section:[q objectForKey:#"sectionId"]];
/* Add it to our question (mutable) array */
[questionArray addObject:question];
[question release];
}
}
The above method is called in the viewDidLoad method of the QuestionnaireViewController and is where the QuestionViewControllers are created. Each one has an associated view with a next button.
It's not clear from your question what you mean when you say, "How do I get the questionnaire to load these question views".
Are you just asking how to display a QuestionViewController when a question is selected? If so, this sounds like a navigation based application. You would typically use a UINavigationController as your top level view controller in your app delegate, setting your QuestionaireViewController as the rootViewController of your UINavigationController. Then, when the user selects a question in your QuestionaireViewController, you can display its controller using:
[self.navigationController pushViewController:questionViewController animated:YES];
If instead you're asking how you can display the views for these QuestionViewControllers as subviews of your QuestionaireViewController, the short answer is don't do it (at least not under iOS 4.x). Apple's view controller framework is not designed to support using nested view controllers to manage multiple subviews simultaneously. The documentation states that each view controller should correspond to one full-screen view on iPhone. iPad changes these rules slightly for things like split views and popovers, but it's still not designed to let you nest view controllers within your own custom view controllers.
(In truth it is technically possible to use multiple view controllers to manage different subviews on a single screen, but doing so properly requires expert knowledge of how the view controller framework is designed so that you can properly delegate all the various UIViewController methods and properties like viewWillAppear:, navigationController, tabBarController, etc. You're generally better off following Apple's advice and using one view controller per screen.)

An easy, clean way to switch/swap views?

I have looked at several sources but I am still very confused! I want to make an application with several views (just standard views, no table views or anything), from which I can click buttons on each view to access the others.
I've seen several ways to do this, but the only one that made any sense to me is to have the application delegate be responsible for swapping views. And I'm not even sure my code correctly cleans up the memory of the view it's swapping!
Is there a cleaner, or easier way to switch between views (I don't care about animations) than using a delegate?
I've also seen presentModalViewController, but that seems sort of unorganized. (E.g. If you have more than one view presenting a modal, how can you easily tell the newest view to close all views up to the root).
There's also creating a window-based application and using the window to addSubView, and removeFromSuperview, but how would you swap one very for another without creating extra, cumbersome coding in the delegate method to detect what view what removed, and which new view should be added? I can't find an addViewToSuperview method, at least.
So please share how you guys swap views, and perhaps the benefit to your system.
Talk really slow, because I feel very slow when it comes to swapping views!
Thank you for your time!
Dealing with multiple views is pretty easy if you understand the concept behind the views. For example your Delegate could be linked to an empty parent View. Then you just create your children views and add them to the parent view with addSubview. The last added view is the one that will be displayed in the foreground.
Now you can bring the views into the front using bringSubviewToFront method. Keep in mind that all your views are kept in memory until you remove them from the parent view using the children view's removeFromSuperview method.
Swapping views is just removing the child view before you add the next one but then you have to decide if you want to retain them or if you want to release them but then you need to *re-create (alloc / init) the views later.
BTW If you views are not at the right place then you either need to adjust the positions relative to the parent view or set them right in the interface builder because iOS will not reposition them because you add them as sub view.
For example I used that code to switch between a view that displays an Ad or a ticker:
- (void) showAds:(BOOL)flag {
if( showAds != flag ) {
while([[self.bottomView subviews] count] > 0 ) {
[[[self.bottomView subviews] objectAtIndex:0] removeFromSuperview];
}
showAds = flag;
if( showAds ) {
[self.tickerViewController stop];
[self.bottomView addSubview:self.adViewController.view];
} else {
[self.bottomView addSubview:self.tickerViewController.view];
[self.tickerViewController start];
}
}}
The 2nd line makes sure I don't remove and add if nothing has changed. The next 3 lines remove any residual sub views. After that either add the Add or the Ticker view as my current sub view (including making sure the ticker is started / stopped properly).
Hope that helps.

iPhone/UIViewController: when navigating away from a view, what is the best way to handle data entries

I should know this by now, but I am still a bit confused. When my app navigates from one view controller to the next (via the navigation controller) I want to "finalize" the data for the current VC before going to the next VC. The only way I see to intercept the "page swap" is in the [old view viewWillDisappear] -> [newView viewWillAppear] transition. It seems weird, though I guess it works okay.
Is that really the right way to handle navigation transitions? My app is a bunch of VCs which collectively build a database file. Each VC deals with a different aspect of the data.
I don't know your exact setup, so this may not be useful to you, but I have good experiences with saving data in -(void)textFieldDidEndEditing:(UITextField*)tf, using tf.tag to index the fields. From there I commit the data to a storage class, and have no worries about what happens in the UI.
What exactly is involved in the "finalizing" part? I assume you are storing some state in the view controller for various fields and then you want to write that to the database file before going on to the next view?
When it comes to "edit view controllers" I find a nice way to do it is to have the view controller directly write to a simple model object which is injected through a property before pushing it to the nav controller.
So something like:
/* Somewhere in the app delegate, like application:didFinishLaunching */
DatabaseFileModel *model = ...;
viewController1.model = model;
viewController2.model = model;
/* ... */
[self.window makeKeyAndVisible];
Then each view controller writes to this model by setting properties etc. when a text field ends editing or whatever. Having the view controller write straight to the object means you don't need to handle viewWillDisappear etc.
If you do still need to do this however you can add a delegate to the navigation controller and handle these two methods:
– navigationController:willShowViewController:animated:
– navigationController:didShowViewController:animated:
See the UINavigationControllerDelegate documentation for more information.
This will let you keep the logic in one place rather than spread out in each view controller.

iPhone App - If I want to load different views based on actions on first view, what design pattern I should use?

My app has a main login/password screen where user enters credentials and submits the info to a web service. Once authenticated, web-service will also tell me what kind of user is loggin in. So user can be type "A", "B" or "C".
Now depending on kind of user I need to load different views (having functionalities) only that particular type of user can use. So I have home screens for "A-HOME" "B-HOME" and "C-HOME" which will then be a Nav Controller or a Tab Controller.
So basically if A logged in - next view loaded should be "A-HOME"
My layman's guess is to load view programmatically. However, I prefer to not do it as you can forget few steps and leak or screw the app. Is there any common design pattern that is used in such cases. The scenario seems pretty regular case to me. Are there any apps with sample code on apple's developer website that does the same thing?
Please give your suggestions.
Thanks.
If the views are "sufficient distinct" use different view controllers for each one, and load the approriate one. You can load the whole thing from a nib if you want, just wire this up in code, after your login procedure, i.e.
-(void) doLogin:(LoginType)loginType
{
if (loginType == LoginTypeA)
{
TypeAViewController *viewController = .... // Load from i.e. "TypeAViewController.nib"
// Add its view
}
}